## Automatically generated incremental diff
## From:   linux-2.2.17-pre15
## To:     linux-2.2.17-pre16
## Robot:  $Id: make-incremental-diff,v 1.8 2001/12/04 06:05:04 hpa Exp $

diff -urN linux-2.2.17-pre15/CREDITS linux/CREDITS
--- linux-2.2.17-pre15/CREDITS	Mon Dec  3 22:10:44 2001
+++ linux/CREDITS	Mon Dec  3 22:10:50 2001
@@ -983,9 +983,10 @@
 S: USA
 
 N: Dave Jones
+E: davej@suse.de
 E: dave@powertweak.com
 E: djones2@glam.ac.uk
-W: http://linux.powertweak.com
+W: http://powertweak.sourceforge.net
 D: Userspace PCI bridge tuning (Powertweak).
 D: Centaur/IDT Winchip/Winchip 2 tweaks.
 D: Misc clean ups and other random hacking.
diff -urN linux-2.2.17-pre15/DAC960.patch linux/DAC960.patch
--- linux-2.2.17-pre15/DAC960.patch	Wed Dec 31 16:00:00 1969
+++ linux/DAC960.patch	Mon Dec  3 22:10:50 2001
@@ -0,0 +1,52 @@
+--- linux/include/linux/pci.h-	Wed May  3 17:16:52 2000
++++ linux/include/linux/pci.h	Thu May  4 08:19:51 2000
+@@ -558,10 +558,12 @@
+ #define PCI_DEVICE_ID_PICOP_PT80C524	0x8002
+ 
+ #define PCI_VENDOR_ID_MYLEX		0x1069
+-#define PCI_DEVICE_ID_MYLEX_DAC960P_V2	0x0001
+-#define PCI_DEVICE_ID_MYLEX_DAC960P_V3	0x0002
+-#define PCI_DEVICE_ID_MYLEX_DAC960P_V4	0x0010
+-#define PCI_DEVICE_ID_MYLEX_DAC960P_V5	0x0020
++#define PCI_DEVICE_ID_MYLEX_DAC960_P	0x0001
++#define PCI_DEVICE_ID_MYLEX_DAC960_PD	0x0002
++#define PCI_DEVICE_ID_MYLEX_DAC960_PG	0x0010
++#define PCI_DEVICE_ID_MYLEX_DAC960_LA	0x0020
++#define PCI_DEVICE_ID_MYLEX_DAC960_LP	0x0050
++#define PCI_DEVICE_ID_MYLEX_DAC960_BA	0xBA56
+ 
+ #define PCI_VENDOR_ID_APPLE		0x106b
+ #define PCI_DEVICE_ID_APPLE_BANDIT	0x0001
+@@ -1094,6 +1096,7 @@
+ #define PCI_DEVICE_ID_INTEL_82430	0x0486
+ #define PCI_DEVICE_ID_INTEL_82434	0x04a3
+ #define PCI_DEVICE_ID_INTEL_I960	0x0960
++#define PCI_DEVICE_ID_INTEL_I960RN	0x0964
+ #define PCI_DEVICE_ID_INTEL_82559ER	0x1209
+ #define PCI_DEVICE_ID_INTEL_82092AA_0	0x1221
+ #define PCI_DEVICE_ID_INTEL_82092AA_1	0x1222
+--- linux/drivers/pci/oldproc.c-	Wed May  3 17:16:43 2000
++++ linux/drivers/pci/oldproc.c	Thu May  4 08:20:15 2000
+@@ -224,9 +224,11 @@
+ 	DEVICE( X,		X_AGX016,	"ITT AGX016"),
+ 	DEVICE( PICOP,		PICOP_PT86C52X,	"PT86C52x Vesuvius"),
+ 	DEVICE( PICOP,		PICOP_PT80C524,	"PT80C524 Nile"),
+-	DEVICE( MYLEX,		MYLEX_DAC960P_V2,"DAC960P V2"),
+-	DEVICE( MYLEX,		MYLEX_DAC960P_V3,"DAC960P V3"),
+-	DEVICE( MYLEX,		MYLEX_DAC960P_V4,"DAC960P V4"),
++	DEVICE( MYLEX,		MYLEX_DAC960_P, "DAC960 P Series"),
++	DEVICE( MYLEX,		MYLEX_DAC960_PD,"DAC960 PD Series"),
++	DEVICE( MYLEX,		MYLEX_DAC960_PG,"DAC960 PG Series"),
++	DEVICE( MYLEX,		MYLEX_DAC960_LP,"DAC960 LP Series"),
++	DEVICE( MYLEX,		MYLEX_DAC960_BA,"DAC960 BA Series"),
+ 	DEVICE( APPLE,		APPLE_BANDIT,	"Bandit"),
+ 	DEVICE( APPLE,		APPLE_GC,	"Grand Central"),
+ 	DEVICE( APPLE,		APPLE_HYDRA,	"Hydra"),
+@@ -519,6 +521,7 @@
+ 	DEVICE( INTEL,		INTEL_82430,	"82430ZX Aries"),
+ 	DEVICE( INTEL,		INTEL_82434,	"82434LX Mercury/Neptune"),
+ 	DEVICE( INTEL,		INTEL_I960,	"i960"),
++	DEVICE( INTEL,		INTEL_I960RN,	"i960 RN"),
+ 	DEVICE( INTEL,		INTEL_82559ER,	"82559ER"),
+ 	DEVICE( INTEL,		INTEL_82092AA_0,"82092AA PCMCIA bridge"),
+ 	DEVICE( INTEL,		INTEL_82092AA_1,"82092AA EIDE"),
diff -urN linux-2.2.17-pre15/Documentation/Configure.help linux/Documentation/Configure.help
--- linux-2.2.17-pre15/Documentation/Configure.help	Mon Dec  3 22:10:44 2001
+++ linux/Documentation/Configure.help	Mon Dec  3 22:10:50 2001
@@ -11465,6 +11465,17 @@
   whenever you want). If you want to compile it as a module, say M
   here and read Documentation/modules.txt.
 
+GMAC (Core99 ethernet) support
+CONFIG_GMAC
+  Say Y for support of the GMAC Ethernet interfaces. This interface
+  is used on some Apple G4 PowerMacs (recent ones), new iMacs, iBooks
+  and PowerBook 2000 (aka "Pismo").
+
+  This driver is also available as a module called gmac.o ( = code
+  which can be inserted in and removed from the running kernel
+  whenever you want). If you want to compile it as a module, say M
+  here and read Documentation/modules.txt.
+
 Video For Linux
 CONFIG_VIDEO_DEV
   Support for audio/video capture and overlay devices and FM radio
diff -urN linux-2.2.17-pre15/Documentation/README.DAC960 linux/Documentation/README.DAC960
--- linux-2.2.17-pre15/Documentation/README.DAC960	Wed May  3 17:16:30 2000
+++ linux/Documentation/README.DAC960	Mon Dec  3 22:10:50 2001
@@ -1,11 +1,11 @@
-	   Mylex DAC960/DAC1100 PCI RAID Controller Driver for Linux
+   Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
 
-			Version 2.2.5 for Linux 2.2.14
-			Version 2.0.5 for Linux 2.0.38
+			Version 2.2.7 for Linux 2.2.16
+			Version 2.4.7 for Linux 2.4.0
 
 			      PRODUCTION RELEASE
 
-				23 January 2000
+				 1 August 2000
 
 			       Leonard N. Zubkoff
 			       Dandelion Digital
@@ -18,30 +18,35 @@
 
 Mylex, Inc. designs and manufactures a variety of high performance PCI RAID
 controllers.  Mylex Corporation is located at 34551 Ardenwood Blvd., Fremont,
-California 94555, USA and can be reached at 510/796-6100 or on the World Wide
-Web at http://www.mylex.com.  Mylex RAID Technical Support can be reached by
-electronic mail at support@mylex.com (for eXtremeRAID 1100 and older DAC960
-models) or techsup@mylex.com (for AcceleRAID models), by voice at 510/608-2400,
-or by FAX at 510/745-7715.  Contact information for offices in Europe and Japan
-is available on the Web site.
+California 94555, USA and can be reached at 510.796.6100 or on the World Wide
+Web at http://www.mylex.com.  Mylex Technical Support can be reached by
+electronic mail at support@mylex.com, by voice at 510.608.2400, or by FAX at
+510.745.7715.  Contact information for offices in Europe and Japan is available
+on their Web site.
 
 The latest information on Linux support for DAC960 PCI RAID Controllers, as
 well as the most recent release of this driver, will always be available from
 my Linux Home Page at URL "http://www.dandelion.com/Linux/".  The Linux DAC960
-driver supports all current DAC960 PCI family controllers including the
-AcceleRAID models, as well as the eXtremeRAID 1100; see below for a complete
-list.  For simplicity, in most places this documentation refers to DAC960
-generically rather than explicitly listing all the models.
-
-Bug reports should be sent via electronic mail to "lnz@dandelion.com".  Please
-include with the bug report the complete configuration messages reported by the
-driver at startup, along with any subsequent system messages relevant to the
-controller's operation, and a detailed description of your system's hardware
-configuration.
-
-Please consult the DAC960 RAID controller documentation for detailed
-information regarding installation and configuration of the controllers.  This
-document primarily provides information specific to the Linux DAC960 support.
+driver supports all current Mylex PCI RAID controllers including the new
+eXtremeRAID 2000/3000 and AcceleRAID 352/170 models which have an entirely new
+firmware interface from the older eXtremeRAID 1100, AcceleRAID 150/200/250, and
+DAC960PJ/PG/PU/PD/PL.  See below for a complete controller list as well as
+minimum firmware version requirements.  For simplicity, in most places this
+documentation refers to DAC960 generically rather than explicitly listing all
+the supported models.
+
+Driver bug reports should be sent via electronic mail to "lnz@dandelion.com".
+Please include with the bug report the complete configuration messages reported
+by the driver at startup, along with any subsequent system messages relevant to
+the controller's operation, and a detailed description of your system's
+hardware configuration.  Driver bugs are actually quite rare; if you encounter
+problems with disks being marked offline, for example, please contact Mylex
+Technical Support as the problem is related to the hardware configuration
+rather than the Linux driver.
+
+Please consult the RAID controller documentation for detailed information
+regarding installation and configuration of the controllers.  This document
+primarily provides information specific to the Linux support.
 
 
 				DRIVER FEATURES
@@ -60,16 +65,18 @@
 from Linux while the system is operational.
 
 The DAC960 driver is architected to support up to 8 controllers per system.
-Each DAC960 controller can support up to 15 disk drives per channel, for a
-maximum of 45 drives on a three channel controller.  The drives installed on a
-controller are divided into one or more "Drive Groups", and then each Drive
-Group is subdivided further into 1 to 32 "Logical Drives".  Each Logical Drive
-has a specific RAID Level and caching policy associated with it, and it appears
-to Linux as a single block device.  Logical Drives are further subdivided into
-up to 7 partitions through the normal Linux and PC disk partitioning schemes.
-Logical Drives are also known as "System Drives", and Drive Groups are also
-called "Packs".  Both terms are in use in the Mylex documentation; I have
-chosen to standardize on the more generic "Logical Drive" and "Drive Group".
+Each DAC960 parallel SCSI controller can support up to 15 disk drives per
+channel, for a maximum of 60 drives on a four channel controller; the fibre
+channel eXtremeRAID 3000 controller supports up to 125 disk drives per loop for
+a total of 250 drives.  The drives installed on a controller are divided into
+one or more "Drive Groups", and then each Drive Group is subdivided further
+into 1 to 32 "Logical Drives".  Each Logical Drive has a specific RAID Level
+and caching policy associated with it, and it appears to Linux as a single
+block device.  Logical Drives are further subdivided into up to 7 partitions
+through the normal Linux and PC disk partitioning schemes.  Logical Drives are
+also known as "System Drives", and Drive Groups are also called "Packs".  Both
+terms are in use in the Mylex documentation; I have chosen to standardize on
+the more generic "Logical Drive" and "Drive Group".
 
 DAC960 RAID disk devices are named in the style of the Device File System
 (DEVFS).  The device corresponding to Logical Drive D on Controller C is
@@ -82,19 +89,41 @@
 Drive and 3 bits for the partition.
 
 
-		 SUPPORTED DAC960/DAC1100 PCI RAID CONTROLLERS
+	  SUPPORTED DAC960/AcceleRAID/eXtremeRAID PCI RAID CONTROLLERS
 
-The following list comprises the supported DAC960 and DAC1100 PCI RAID
-Controllers as of the date of this document.  It is recommended that anyone
-purchasing a Mylex PCI RAID Controller not in the following table contact the
-author beforehand to verify that it is or will be supported.  The eXtremeRAID
-2000, eXtremeRAID 3000, and AcceleRAID 352 have an entirely new firmware
-interface and are not yet supported by this driver.
+The following list comprises the supported DAC960, AcceleRAID, and eXtremeRAID
+PCI RAID Controllers as of the date of this document.  It is recommended that
+anyone purchasing a Mylex PCI RAID Controller not in the following table
+contact the author beforehand to verify that it is or will be supported.
+
+eXtremeRAID 3000
+	    1 Wide Ultra-2/LVD SCSI channel
+	    2 External Fibre FC-AL channels
+	    233MHz StrongARM SA 110 Processor
+	    64 Bit 33MHz PCI (backward compatible with 32 Bit PCI slots)
+	    32MB/64MB ECC SDRAM Memory
+
+eXtremeRAID 2000
+	    4 Wide Ultra-160 LVD SCSI channels
+	    233MHz StrongARM SA 110 Processor
+	    64 Bit 33MHz PCI (backward compatible with 32 Bit PCI slots)
+	    32MB/64MB ECC SDRAM Memory
+
+AcceleRAID 352
+	    2 Wide Ultra-160 LVD SCSI channels
+	    100MHz Intel i960RN RISC Processor
+	    64 Bit 33MHz PCI (backward compatible with 32 Bit PCI slots)
+	    32MB/64MB ECC SDRAM Memory
+
+AcceleRAID 170
+	    1 Wide Ultra-160 LVD SCSI channel
+	    100MHz Intel i960RM RISC Processor
+	    16MB/32MB/64MB ECC SDRAM Memory
 
 eXtremeRAID 1100 (DAC1164P)
 	    3 Wide Ultra-2/LVD SCSI channels
 	    233MHz StrongARM SA 110 Processor
-	    64 Bit PCI (backward compatible with 32 Bit PCI slots)
+	    64 Bit 33MHz PCI (backward compatible with 32 Bit PCI slots)
 	    16MB/32MB/64MB Parity SDRAM Memory with Battery Backup
 
 AcceleRAID 250 (DAC960PTL1)
@@ -135,6 +164,9 @@
 	    Intel i960 RISC Processor
 	    2MB/4MB/8MB/16MB/32MB DRAM Memory
 
+For the eXtremeRAID 2000/3000 and AcceleRAID 352/170, firmware version 6.00-01
+or above is required.
+
 For the eXtremeRAID 1100, firmware version 5.06-0-52 or above is required.
 
 For the AcceleRAID 250, 200, and 150, firmware version 4.06-0-57 or above is
@@ -165,16 +197,16 @@
 
 			      DRIVER INSTALLATION
 
-This distribution was prepared for Linux kernel version 2.2.14 or 2.0.38.
+This distribution was prepared for Linux kernel version 2.2.16 or 2.4.0.
 
 To install the DAC960 RAID driver, you may use the following commands,
 replacing "/usr/src" with wherever you keep your Linux kernel source tree:
 
   cd /usr/src
-  tar -xvzf DAC960-2.2.5.tar.gz (or DAC960-2.0.5.tar.gz)
+  tar -xvzf DAC960-2.2.7.tar.gz (or DAC960-2.4.7.tar.gz)
   mv README.DAC960 linux/Documentation
   mv DAC960.[ch] linux/drivers/block
-  patch -p0 < DAC960.patch (driver 2.0.5 only)
+  patch -p0 < DAC960.patch
   cd linux
   make config
   make depend
@@ -203,13 +235,13 @@
 drives using the BIOS Configuration Utility or DACCF.  Please note that since
 there are only at most 6 usable partitions on each logical drive, systems
 requiring more partitions should subdivide a drive group into multiple logical
-drives, each of which can have up to 6 partitions.  Also, note that with large
-disk arrays it is advisable to enable the 8GB BIOS Geometry (255/63) rather
-than accepting the default 2GB BIOS Geometry (128/32); failing to so do will
-cause the logical drive geometry to have more than 65535 cylinders which will
-make it impossible for FDISK to be used properly.  The 8GB BIOS Geometry can be
-enabled by configuring the DAC960 BIOS, which is accessible via Alt-M during
-the BIOS initialization sequence.
+drives, each of which can have up to 6 usable partitions.  Also, note that with
+large disk arrays it is advisable to enable the 8GB BIOS Geometry (255/63)
+rather than accepting the default 2GB BIOS Geometry (128/32); failing to so do
+will cause the logical drive geometry to have more than 65535 cylinders which
+will make it impossible for FDISK to be used properly.  The 8GB BIOS Geometry
+can be enabled by configuring the DAC960 BIOS, which is accessible via Alt-M
+during the BIOS initialization sequence.
 
 For maximum performance and the most efficient E2FSCK performance, it is
 recommended that EXT2 file systems be built with a 4KB block size and 16 block
diff -urN linux-2.2.17-pre15/Documentation/proc.txt linux/Documentation/proc.txt
--- linux-2.2.17-pre15/Documentation/proc.txt	Tue Jan  4 10:12:10 2000
+++ linux/Documentation/proc.txt	Mon Dec  3 22:10:50 2001
@@ -459,12 +459,6 @@
    encountered a peak in your usage of file handles and you don't need
    to increase the maximum.
 
-   However, there is still a per process limit of open files, which
-   unfortunatly can't be changed that easily. It is set to 1024 by
-   default. To change this you have to edit the files limits.h and
-   fs.h in the directory /usr/src/linux/include/linux. Change the
-   definition of NR_OPEN and recompile the kernel.
-
 inode-state, inode-nr and inode-max
    As with file handles, the kernel allocates the inode structures
    dynamically, but can't free them yet.
diff -urN linux-2.2.17-pre15/Documentation/sysctl/vm.txt linux/Documentation/sysctl/vm.txt
--- linux-2.2.17-pre15/Documentation/sysctl/vm.txt	Mon Aug  9 12:04:38 1999
+++ linux/Documentation/sysctl/vm.txt	Mon Dec  3 22:10:50 2001
@@ -168,7 +168,7 @@
 
 This feature can be very useful because there are a lot of
 programs that malloc() huge amounts of memory "just-in-case"
-and don't much of it.
+and don't use much of it.
 
 Look at: mm/mmap.c::vm_enough_memory() for more information.
 
diff -urN linux-2.2.17-pre15/Makefile linux/Makefile
--- linux-2.2.17-pre15/Makefile	Mon Dec  3 22:10:44 2001
+++ linux/Makefile	Mon Dec  3 22:10:50 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 17
-EXTRAVERSION = pre15
+EXTRAVERSION = pre16
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
diff -urN linux-2.2.17-pre15/arch/ppc/kernel/pmac_time.c linux/arch/ppc/kernel/pmac_time.c
--- linux-2.2.17-pre15/arch/ppc/kernel/pmac_time.c	Mon Dec  3 22:10:44 2001
+++ linux/arch/ppc/kernel/pmac_time.c	Mon Dec  3 22:10:50 2001
@@ -57,9 +57,6 @@
 {
 	s32 delta = 0;
 	int dst;
-	int i;
-	char tmp[1024];
-	char *p = tmp;
 	
 	delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
 	delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
@@ -116,6 +113,7 @@
 int pmac_set_rtc_time(unsigned long nowtime)
 {
 	struct adb_request req;
+	int dst, delta;
 
 	nowtime += RTC_OFFSET - sys_tz.tz_minuteswest * 60;
 
@@ -134,7 +132,7 @@
 //		if (req.reply_len != 7)
 			printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
 			       req.reply_len);
-		return 1;
+		break;
 	case ADB_VIAPMU:
 		if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
 				nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
@@ -144,10 +142,21 @@
 		if (req.reply_len != 5)
 			printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
 			       req.reply_len);
-		return 1;
+		break;
 	default:
 		return 0;
 	}
+
+	/* write the timezone offset back into the xpram */
+	delta = sys_tz.tz_minuteswest * -60;
+	pmac_xpram_write(PMAC_XPRAM_MACHINE_LOC + 0x9, delta >> 16);
+	pmac_xpram_write(PMAC_XPRAM_MACHINE_LOC + 0xa, delta >> 8);
+	pmac_xpram_write(PMAC_XPRAM_MACHINE_LOC + 0xb, delta);
+	dst = pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 8);
+	dst = sys_tz.tz_dsttime? (dst | 0x80): (dst & ~0x80);
+	pmac_xpram_write(PMAC_XPRAM_MACHINE_LOC + 8, dst);
+
+	return 1;
 }
 
 /*
diff -urN linux-2.2.17-pre15/drivers/block/DAC960.c linux/drivers/block/DAC960.c
--- linux-2.2.17-pre15/drivers/block/DAC960.c	Wed May  3 17:16:32 2000
+++ linux/drivers/block/DAC960.c	Mon Dec  3 22:10:50 2001
@@ -1,8 +1,8 @@
 /*
 
-  Linux Driver for Mylex DAC960 and DAC1100 PCI RAID Controllers
+  Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
 
-  Copyright 1998-1999 by Leonard N. Zubkoff <lnz@dandelion.com>
+  Copyright 1998-2000 by Leonard N. Zubkoff <lnz@dandelion.com>
 
   This program is free software; you may redistribute and/or modify it under
   the terms of the GNU General Public License Version 2 as published by the
@@ -19,8 +19,8 @@
 */
 
 
-#define DAC960_DriverVersion			"2.2.5"
-#define DAC960_DriverDate			"23 January 2000"
+#define DAC960_DriverVersion			"2.2.7"
+#define DAC960_DriverDate			"1 August 2000"
 
 
 #include <linux/version.h>
@@ -55,7 +55,7 @@
 
 
 /*
-  DAC960_ActiveControllerCount is the number of Active DAC960 Controllers
+  DAC960_ActiveControllerCount is the number of active DAC960 Controllers
   detected.
 */
 
@@ -130,7 +130,7 @@
 */
 
 static boolean DAC960_Failure(DAC960_Controller_T *Controller,
-			      char *ErrorMessage)
+			      unsigned char *ErrorMessage)
 {
   DAC960_Error("While configuring DAC960 PCI RAID Controller at\n",
 	       Controller);
@@ -150,17 +150,128 @@
 
 
 /*
-  DAC960_ClearCommand clears critical fields of Command.
+  DAC960_CreateAuxiliaryStructures allocates and initializes the auxiliary
+  data structures for Controller.  It returns true on success and false on
+  failure.
 */
 
-static inline void DAC960_ClearCommand(DAC960_Command_T *Command)
+static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
 {
-  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-  CommandMailbox->Words[0] = 0;
-  CommandMailbox->Words[1] = 0;
-  CommandMailbox->Words[2] = 0;
-  CommandMailbox->Words[3] = 0;
-  Command->CommandStatus = 0;
+  int CommandAllocationLength, CommandAllocationGroupSize;
+  int CommandsRemaining = 0, CommandIdentifier, CommandGroupByteCount;
+  void *AllocationPointer = NULL;
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+    {
+      CommandAllocationLength = offsetof(DAC960_Command_T, V1.EndMarker);
+      CommandAllocationGroupSize = DAC960_V1_CommandAllocationGroupSize;
+    }
+  else
+    {
+      CommandAllocationLength = offsetof(DAC960_Command_T, V2.EndMarker);
+      CommandAllocationGroupSize = DAC960_V2_CommandAllocationGroupSize;
+    }
+  Controller->CommandAllocationGroupSize = CommandAllocationGroupSize;
+  Controller->FreeCommands = NULL;
+  for (CommandIdentifier = 1;
+       CommandIdentifier <= Controller->DriverQueueDepth;
+       CommandIdentifier++)
+    {
+      DAC960_Command_T *Command;
+      if (--CommandsRemaining <= 0)
+	{
+	  CommandsRemaining =
+	    Controller->DriverQueueDepth - CommandIdentifier + 1;
+	  if (CommandsRemaining > CommandAllocationGroupSize)
+	    CommandsRemaining = CommandAllocationGroupSize;
+	  CommandGroupByteCount =
+	    CommandsRemaining * CommandAllocationLength;
+	  AllocationPointer = kmalloc(CommandGroupByteCount, GFP_ATOMIC);
+	  if (AllocationPointer == NULL)
+	    return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION");
+	  memset(AllocationPointer, 0, CommandGroupByteCount);
+	}
+      Command = (DAC960_Command_T *) AllocationPointer;
+      AllocationPointer += CommandAllocationLength;
+      Command->CommandIdentifier = CommandIdentifier;
+      Command->Controller = Controller;
+      Command->Next = Controller->FreeCommands;
+      Controller->FreeCommands = Command;
+      Controller->Commands[CommandIdentifier-1] = Command;
+    }
+  return true;
+}
+
+
+/*
+  DAC960_DestroyAuxiliaryStructures deallocates the auxiliary data
+  structures for Controller.
+*/
+
+static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
+{
+  int i;
+  Controller->FreeCommands = NULL;
+  for (i = 0; i < Controller->DriverQueueDepth; i++)
+    {
+      DAC960_Command_T *Command = Controller->Commands[i];
+      if (Command != NULL &&
+	  (Command->CommandIdentifier
+	   % Controller->CommandAllocationGroupSize) == 1)
+	kfree(Command);
+      Controller->Commands[i] = NULL;
+    }
+  if (Controller->CombinedStatusBuffer != NULL)
+    {
+      kfree(Controller->CombinedStatusBuffer);
+      Controller->CombinedStatusBuffer = NULL;
+      Controller->CurrentStatusBuffer = NULL;
+    }
+  if (Controller->FirmwareType == DAC960_V1_Controller) return;
+  for (i = 0; i < DAC960_MaxLogicalDrives; i++)
+    if (Controller->V2.LogicalDeviceInformation[i] != NULL)
+      {
+	kfree(Controller->V2.LogicalDeviceInformation[i]);
+	Controller->V2.LogicalDeviceInformation[i] = NULL;
+      }
+  for (i = 0; i < DAC960_V2_MaxPhysicalDevices; i++)
+    {
+      if (Controller->V2.PhysicalDeviceInformation[i] != NULL)
+	{
+	  kfree(Controller->V2.PhysicalDeviceInformation[i]);
+	  Controller->V2.PhysicalDeviceInformation[i] = NULL;
+	}
+      if (Controller->V2.InquiryUnitSerialNumber[i] != NULL)
+	{
+	  kfree(Controller->V2.InquiryUnitSerialNumber[i]);
+	  Controller->V2.InquiryUnitSerialNumber[i] = NULL;
+	}
+    }
+}
+
+
+/*
+  DAC960_V1_ClearCommand clears critical fields of Command for DAC960 V1
+  Firmware Controllers.
+*/
+
+static inline void DAC960_V1_ClearCommand(DAC960_Command_T *Command)
+{
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  memset(CommandMailbox, 0, sizeof(DAC960_V1_CommandMailbox_T));
+  Command->V1.CommandStatus = 0;
+}
+
+
+/*
+  DAC960_V2_ClearCommand clears critical fields of Command for DAC960 V2
+  Firmware Controllers.
+*/
+
+static inline void DAC960_V2_ClearCommand(DAC960_Command_T *Command)
+{
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  memset(CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));
+  Command->V2.CommandStatus = 0;
 }
 
 
@@ -211,66 +322,181 @@
 
 
 /*
-  DAC960_QueueCommand queues Command.
+  DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers.
 */
 
-static void DAC960_QueueCommand(DAC960_Command_T *Command)
+static void DAC960_BA_QueueCommand(DAC960_Command_T *Command)
 {
   DAC960_Controller_T *Controller = Command->Controller;
   void *ControllerBaseAddress = Controller->BaseAddress;
-  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-  DAC960_CommandMailbox_T *NextCommandMailbox;
-  CommandMailbox->Common.CommandIdentifier = Command - Controller->Commands;
-  switch (Controller->ControllerType)
-    {
-    case DAC960_V5_Controller:
-      NextCommandMailbox = Controller->NextCommandMailbox;
-      DAC960_V5_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
-      if (Controller->PreviousCommandMailbox1->Words[0] == 0 ||
-	  Controller->PreviousCommandMailbox2->Words[0] == 0)
-	{
-	  if (Controller->DualModeMemoryMailboxInterface)
-	    DAC960_V5_MemoryMailboxNewCommand(ControllerBaseAddress);
-	  else DAC960_V5_HardwareMailboxNewCommand(ControllerBaseAddress);
-	}
-      Controller->PreviousCommandMailbox2 = Controller->PreviousCommandMailbox1;
-      Controller->PreviousCommandMailbox1 = NextCommandMailbox;
-      if (++NextCommandMailbox > Controller->LastCommandMailbox)
-	NextCommandMailbox = Controller->FirstCommandMailbox;
-      Controller->NextCommandMailbox = NextCommandMailbox;
-      break;
-    case DAC960_V4_Controller:
-      NextCommandMailbox = Controller->NextCommandMailbox;
-      DAC960_V4_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
-      if (Controller->PreviousCommandMailbox1->Words[0] == 0 ||
-	  Controller->PreviousCommandMailbox2->Words[0] == 0)
-	{
-	  if (Controller->DualModeMemoryMailboxInterface)
-	    DAC960_V4_MemoryMailboxNewCommand(ControllerBaseAddress);
-	  else DAC960_V4_HardwareMailboxNewCommand(ControllerBaseAddress);
-	}
-      Controller->PreviousCommandMailbox2 = Controller->PreviousCommandMailbox1;
-      Controller->PreviousCommandMailbox1 = NextCommandMailbox;
-      if (++NextCommandMailbox > Controller->LastCommandMailbox)
-	NextCommandMailbox = Controller->FirstCommandMailbox;
-      Controller->NextCommandMailbox = NextCommandMailbox;
-      break;
-    case DAC960_V3_Controller:
-      while (DAC960_V3_MailboxFullP(ControllerBaseAddress))
-	udelay(1);
-      DAC960_V3_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
-      DAC960_V3_NewCommand(ControllerBaseAddress);
-      break;
-    }
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandMailbox_T *NextCommandMailbox =
+    Controller->V2.NextCommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  DAC960_BA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+  if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
+      Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
+    DAC960_BA_MemoryMailboxNewCommand(ControllerBaseAddress);
+  Controller->V2.PreviousCommandMailbox2 =
+    Controller->V2.PreviousCommandMailbox1;
+  Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
+  if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
+    NextCommandMailbox = Controller->V2.FirstCommandMailbox;
+  Controller->V2.NextCommandMailbox = NextCommandMailbox;
 }
 
 
 /*
-  DAC960_ExecuteCommand executes Command and waits for completion.  It
-  returns true on success and false on failure.
+  DAC960_LP_QueueCommand queues Command for DAC960 LP Series Controllers.
+*/
+
+static void DAC960_LP_QueueCommand(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandMailbox_T *NextCommandMailbox =
+    Controller->V2.NextCommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  DAC960_LP_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+  if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
+      Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
+    DAC960_LP_MemoryMailboxNewCommand(ControllerBaseAddress);
+  Controller->V2.PreviousCommandMailbox2 =
+    Controller->V2.PreviousCommandMailbox1;
+  Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
+  if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
+    NextCommandMailbox = Controller->V2.FirstCommandMailbox;
+  Controller->V2.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+  DAC960_LA_QueueCommandDualMode queues Command for DAC960 LA Series
+  Controllers with Dual Mode Firmware.
+*/
+
+static void DAC960_LA_QueueCommandDualMode(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandMailbox_T *NextCommandMailbox =
+    Controller->V1.NextCommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+  if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
+      Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
+    DAC960_LA_MemoryMailboxNewCommand(ControllerBaseAddress);
+  Controller->V1.PreviousCommandMailbox2 =
+    Controller->V1.PreviousCommandMailbox1;
+  Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
+  if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
+    NextCommandMailbox = Controller->V1.FirstCommandMailbox;
+  Controller->V1.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+  DAC960_LA_QueueCommandSingleMode queues Command for DAC960 LA Series
+  Controllers with Single Mode Firmware.
+*/
+
+static void DAC960_LA_QueueCommandSingleMode(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandMailbox_T *NextCommandMailbox =
+    Controller->V1.NextCommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+  if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
+      Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
+    DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
+  Controller->V1.PreviousCommandMailbox2 =
+    Controller->V1.PreviousCommandMailbox1;
+  Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
+  if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
+    NextCommandMailbox = Controller->V1.FirstCommandMailbox;
+  Controller->V1.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+  DAC960_PG_QueueCommandDualMode queues Command for DAC960 PG Series
+  Controllers with Dual Mode Firmware.
+*/
+
+static void DAC960_PG_QueueCommandDualMode(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandMailbox_T *NextCommandMailbox =
+    Controller->V1.NextCommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+  if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
+      Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
+    DAC960_PG_MemoryMailboxNewCommand(ControllerBaseAddress);
+  Controller->V1.PreviousCommandMailbox2 =
+    Controller->V1.PreviousCommandMailbox1;
+  Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
+  if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
+    NextCommandMailbox = Controller->V1.FirstCommandMailbox;
+  Controller->V1.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+  DAC960_PG_QueueCommandSingleMode queues Command for DAC960 PG Series
+  Controllers with Single Mode Firmware.
+*/
+
+static void DAC960_PG_QueueCommandSingleMode(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandMailbox_T *NextCommandMailbox =
+    Controller->V1.NextCommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+  if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
+      Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
+    DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
+  Controller->V1.PreviousCommandMailbox2 =
+    Controller->V1.PreviousCommandMailbox1;
+  Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
+  if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
+    NextCommandMailbox = Controller->V1.FirstCommandMailbox;
+  Controller->V1.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+  DAC960_PD_QueueCommand queues Command for DAC960 PD Series Controllers.
+*/
+
+static void DAC960_PD_QueueCommand(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  while (DAC960_PD_MailboxFullP(ControllerBaseAddress))
+    udelay(1);
+  DAC960_PD_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
+  DAC960_PD_NewCommand(ControllerBaseAddress);
+}
+
+
+/*
+  DAC960_ExecuteCommand executes Command and waits for completion.
 */
 
-static boolean DAC960_ExecuteCommand(DAC960_Command_T *Command)
+static void DAC960_ExecuteCommand(DAC960_Command_T *Command)
 {
   DAC960_Controller_T *Controller = Command->Controller;
   Semaphore_T Semaphore = MUTEX_LOCKED;
@@ -279,227 +505,386 @@
   DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
   DAC960_QueueCommand(Command);
   DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
-  if (!in_interrupt())
-    down(&Semaphore);
-  return Command->CommandStatus == DAC960_NormalCompletion;
+  if (in_interrupt()) return;
+  down(&Semaphore);
 }
 
 
 /*
-  DAC960_ExecuteType3 executes a DAC960 Type 3 Command and waits for
-  completion.  It returns true on success and false on failure.
+  DAC960_V1_ExecuteType3 executes a DAC960 V1 Firmware Controller Type 3
+  Command and waits for completion.  It returns true on success and false
+  on failure.
 */
 
-static boolean DAC960_ExecuteType3(DAC960_Controller_T *Controller,
-				   DAC960_CommandOpcode_T CommandOpcode,
-				   void *DataPointer)
+static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
+				      DAC960_V1_CommandOpcode_T CommandOpcode,
+				      void *DataPointer)
 {
   DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
-  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-  boolean Result;
-  DAC960_ClearCommand(Command);
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandStatus_T CommandStatus;
+  DAC960_V1_ClearCommand(Command);
   Command->CommandType = DAC960_ImmediateCommand;
   CommandMailbox->Type3.CommandOpcode = CommandOpcode;
   CommandMailbox->Type3.BusAddress = Virtual_to_Bus(DataPointer);
-  Result = DAC960_ExecuteCommand(Command);
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V1.CommandStatus;
   DAC960_DeallocateCommand(Command);
-  return Result;
+  return (CommandStatus == DAC960_V1_NormalCompletion);
 }
 
 
 /*
-  DAC960_ExecuteType3D executes a DAC960 Type 3D Command and waits for
-  completion.  It returns true on success and false on failure.
+  DAC960_V1_ExecuteType3D executes a DAC960 V1 Firmware Controller Type 3D
+  Command and waits for completion.  It returns true on success and false
+  on failure.
 */
 
-static boolean DAC960_ExecuteType3D(DAC960_Controller_T *Controller,
-				    DAC960_CommandOpcode_T CommandOpcode,
-				    unsigned char Channel,
-				    unsigned char TargetID,
-				    void *DataPointer)
+static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
+				       DAC960_V1_CommandOpcode_T CommandOpcode,
+				       unsigned char Channel,
+				       unsigned char TargetID,
+				       void *DataPointer)
 {
   DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
-  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-  boolean Result;
-  DAC960_ClearCommand(Command);
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandStatus_T CommandStatus;
+  DAC960_V1_ClearCommand(Command);
   Command->CommandType = DAC960_ImmediateCommand;
   CommandMailbox->Type3D.CommandOpcode = CommandOpcode;
   CommandMailbox->Type3D.Channel = Channel;
   CommandMailbox->Type3D.TargetID = TargetID;
   CommandMailbox->Type3D.BusAddress = Virtual_to_Bus(DataPointer);
-  Result = DAC960_ExecuteCommand(Command);
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V1.CommandStatus;
   DAC960_DeallocateCommand(Command);
-  return Result;
+  return (CommandStatus == DAC960_V1_NormalCompletion);
 }
 
 
 /*
-  DAC960_ReportErrorStatus reports Controller BIOS Messages passed through
-  the Error Status Register when the driver performs the BIOS handshaking.
-  It returns true for fatal errors and false otherwise.
+  DAC960_V2_GeneralInfo executes a DAC960 V2 Firmware General Information
+  Reading IOCTL Command and waits for completion.  It returns true on success
+  and false on failure.
 */
 
-static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
-					unsigned char ErrorStatus,
-					unsigned char Parameter0,
-					unsigned char Parameter1)
+static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller,
+				     DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
+				     void *DataPointer,
+				     unsigned int DataByteCount)
 {
-  switch (ErrorStatus)
-    {
-    case 0x00:
-      DAC960_Notice("Physical Drive %d:%d Not Responding\n",
-		    Controller, Parameter1, Parameter0);
-      break;
-    case 0x08:
-      if (Controller->DriveSpinUpMessageDisplayed) break;
-      DAC960_Notice("Spinning Up Drives\n", Controller);
-      Controller->DriveSpinUpMessageDisplayed = true;
-      break;
-    case 0x30:
-      DAC960_Notice("Configuration Checksum Error\n", Controller);
-      break;
-    case 0x60:
-      DAC960_Notice("Mirror Race Recovery Failed\n", Controller);
-      break;
-    case 0x70:
-      DAC960_Notice("Mirror Race Recovery In Progress\n", Controller);
-      break;
-    case 0x90:
-      DAC960_Notice("Physical Drive %d:%d COD Mismatch\n",
-		    Controller, Parameter1, Parameter0);
-      break;
-    case 0xA0:
-      DAC960_Notice("Logical Drive Installation Aborted\n", Controller);
-      break;
-    case 0xB0:
-      DAC960_Notice("Mirror Race On A Critical Logical Drive\n", Controller);
-      break;
-    case 0xD0:
-      DAC960_Notice("New Controller Configuration Found\n", Controller);
-      break;
-    case 0xF0:
-      DAC960_Error("Fatal Memory Parity Error for Controller at\n", Controller);
-      return true;
-    default:
-      DAC960_Error("Unknown Initialization Error %02X for Controller at\n",
-		   Controller, ErrorStatus);
-      return true;
-    }
-  return false;
+  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandStatus_T CommandStatus;
+  DAC960_V2_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->Common.CommandControlBits
+			.DataTransferControllerToHost = true;
+  CommandMailbox->Common.CommandControlBits
+			.NoAutoRequestSense = true;
+  CommandMailbox->Common.DataTransferSize = DataByteCount;
+  CommandMailbox->Common.IOCTL_Opcode = IOCTL_Opcode;
+  CommandMailbox->Common.DataTransferMemoryAddress
+			.ScatterGatherSegments[0]
+			.SegmentDataPointer =
+    Virtual_to_Bus(DataPointer);
+  CommandMailbox->Common.DataTransferMemoryAddress
+			.ScatterGatherSegments[0]
+			.SegmentByteCount =
+    CommandMailbox->Common.DataTransferSize;
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V2.CommandStatus;
+  DAC960_DeallocateCommand(Command);
+  return (CommandStatus == DAC960_V2_NormalCompletion);
 }
 
 
 /*
-  DAC960_EnableMemoryMailboxInterface enables the Memory Mailbox Interface.
+  DAC960_V2_ControllerInfo executes a DAC960 V2 Firmware Controller
+  Information Reading IOCTL Command and waits for completion.  It returns
+  true on success and false on failure.
 */
 
-static boolean DAC960_EnableMemoryMailboxInterface(DAC960_Controller_T
-						   *Controller)
+static boolean DAC960_V2_ControllerInfo(DAC960_Controller_T *Controller,
+					DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
+					void *DataPointer,
+					unsigned int DataByteCount)
+{
+  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandStatus_T CommandStatus;
+  DAC960_V2_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->ControllerInfo.CommandControlBits
+				.DataTransferControllerToHost = true;
+  CommandMailbox->ControllerInfo.CommandControlBits
+				.NoAutoRequestSense = true;
+  CommandMailbox->ControllerInfo.DataTransferSize = DataByteCount;
+  CommandMailbox->ControllerInfo.ControllerNumber = 0;
+  CommandMailbox->ControllerInfo.IOCTL_Opcode = IOCTL_Opcode;
+  CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+				.ScatterGatherSegments[0]
+				.SegmentDataPointer =
+    Virtual_to_Bus(DataPointer);
+  CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+				.ScatterGatherSegments[0]
+				.SegmentByteCount =
+    CommandMailbox->ControllerInfo.DataTransferSize;
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V2.CommandStatus;
+  DAC960_DeallocateCommand(Command);
+  return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+  DAC960_V2_LogicalDeviceInfo executes a DAC960 V2 Firmware Controller Logical
+  Device Information Reading IOCTL Command and waits for completion.  It
+  returns true on success and false on failure.
+*/
+
+static boolean DAC960_V2_LogicalDeviceInfo(DAC960_Controller_T *Controller,
+					   DAC960_V2_IOCTL_Opcode_T
+					     IOCTL_Opcode,
+					   unsigned short
+					     LogicalDeviceNumber,
+					   void *DataPointer,
+					   unsigned int DataByteCount)
+{
+  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandStatus_T CommandStatus;
+  DAC960_V2_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->LogicalDeviceInfo.CommandControlBits
+				   .DataTransferControllerToHost = true;
+  CommandMailbox->LogicalDeviceInfo.CommandControlBits
+				   .NoAutoRequestSense = true;
+  CommandMailbox->LogicalDeviceInfo.DataTransferSize = DataByteCount;
+  CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
+    LogicalDeviceNumber;
+  CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
+  CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
+				   .ScatterGatherSegments[0]
+				   .SegmentDataPointer =
+    Virtual_to_Bus(DataPointer);
+  CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
+				   .ScatterGatherSegments[0]
+				   .SegmentByteCount =
+    CommandMailbox->LogicalDeviceInfo.DataTransferSize;
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V2.CommandStatus;
+  DAC960_DeallocateCommand(Command);
+  return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+  DAC960_V2_PhysicalDeviceInfo executes a DAC960 V2 Firmware Controller Physical
+  Device Information Reading IOCTL Command and waits for completion.  It
+  returns true on success and false on failure.
+*/
+
+static boolean DAC960_V2_PhysicalDeviceInfo(DAC960_Controller_T *Controller,
+					    DAC960_V2_IOCTL_Opcode_T
+					      IOCTL_Opcode,
+					    unsigned char Channel,
+					    unsigned char TargetID,
+					    unsigned char LogicalUnit,
+					    void *DataPointer,
+					    unsigned int DataByteCount)
+{
+  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandStatus_T CommandStatus;
+  DAC960_V2_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->PhysicalDeviceInfo.CommandControlBits
+				    .DataTransferControllerToHost = true;
+  CommandMailbox->PhysicalDeviceInfo.CommandControlBits
+				    .NoAutoRequestSense = true;
+  CommandMailbox->PhysicalDeviceInfo.DataTransferSize = DataByteCount;
+  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit = LogicalUnit;
+  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
+  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
+  CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
+  CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
+				    .ScatterGatherSegments[0]
+				    .SegmentDataPointer =
+    Virtual_to_Bus(DataPointer);
+  CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
+				    .ScatterGatherSegments[0]
+				    .SegmentByteCount =
+    CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V2.CommandStatus;
+  DAC960_DeallocateCommand(Command);
+  return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+  DAC960_V2_DeviceOperation executes a DAC960 V2 Firmware Controller Device
+  Operation IOCTL Command and waits for completion.  It returns true on
+  success and false on failure.
+*/
+
+static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller,
+					 DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
+					 DAC960_V2_OperationDevice_T
+					   OperationDevice)
+{
+  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandStatus_T CommandStatus;
+  DAC960_V2_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox->DeviceOperation.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->DeviceOperation.CommandControlBits
+				 .DataTransferControllerToHost = true;
+  CommandMailbox->DeviceOperation.CommandControlBits
+    				 .NoAutoRequestSense = true;
+  CommandMailbox->DeviceOperation.IOCTL_Opcode = IOCTL_Opcode;
+  CommandMailbox->DeviceOperation.OperationDevice = OperationDevice;
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V2.CommandStatus;
+  DAC960_DeallocateCommand(Command);
+  return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+  DAC960_V1_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
+  for DAC960 V1 Firmware Controllers.
+*/
+
+static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
+						      *Controller)
 {
   void *ControllerBaseAddress = Controller->BaseAddress;
-  DAC960_CommandMailbox_T *CommandMailboxesMemory;
-  DAC960_StatusMailbox_T *StatusMailboxesMemory;
-  DAC960_CommandMailbox_T CommandMailbox;
-  DAC960_CommandStatus_T CommandStatus;
+  DAC960_V1_CommandMailbox_T *CommandMailboxesMemory;
+  DAC960_V1_StatusMailbox_T *StatusMailboxesMemory;
+  DAC960_V1_CommandMailbox_T CommandMailbox;
+  DAC960_V1_CommandStatus_T CommandStatus;
+  unsigned long MemoryMailboxPagesAddress;
+  unsigned long MemoryMailboxPagesOrder;
+  unsigned long MemoryMailboxPagesSize;
   void *SavedMemoryMailboxesAddress = NULL;
   short NextCommandMailboxIndex = 0;
   short NextStatusMailboxIndex = 0;
   int TimeoutCounter = 1000000, i;
-  if (Controller->ControllerType == DAC960_V5_Controller)
-    DAC960_V5_RestoreMemoryMailboxInfo(Controller,
+  MemoryMailboxPagesOrder = 0;
+  MemoryMailboxPagesSize =
+    DAC960_V1_CommandMailboxCount * sizeof(DAC960_V1_CommandMailbox_T) +
+    DAC960_V1_StatusMailboxCount * sizeof(DAC960_V1_StatusMailbox_T);
+  while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
+    MemoryMailboxPagesOrder++;
+  if (Controller->HardwareType == DAC960_LA_Controller)
+    DAC960_LA_RestoreMemoryMailboxInfo(Controller,
 				       &SavedMemoryMailboxesAddress,
 				       &NextCommandMailboxIndex,
 				       &NextStatusMailboxIndex);
-  else DAC960_V4_RestoreMemoryMailboxInfo(Controller,
+  else DAC960_PG_RestoreMemoryMailboxInfo(Controller,
 					  &SavedMemoryMailboxesAddress,
 					  &NextCommandMailboxIndex,
 					  &NextStatusMailboxIndex);
   if (SavedMemoryMailboxesAddress == NULL)
-    CommandMailboxesMemory =
-      (DAC960_CommandMailbox_T *) __get_free_pages(GFP_KERNEL, 1);
+    {
+      MemoryMailboxPagesAddress =
+	__get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
+      Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
+      CommandMailboxesMemory =
+	(DAC960_V1_CommandMailbox_T *) MemoryMailboxPagesAddress;
+    }
   else CommandMailboxesMemory = SavedMemoryMailboxesAddress;
-  memset(CommandMailboxesMemory, 0, PAGE_SIZE << 1);
-  Controller->FirstCommandMailbox = CommandMailboxesMemory;
-  CommandMailboxesMemory += DAC960_CommandMailboxCount - 1;
-  Controller->LastCommandMailbox = CommandMailboxesMemory;
-  Controller->NextCommandMailbox =
-    &Controller->FirstCommandMailbox[NextCommandMailboxIndex];
+  if (CommandMailboxesMemory == NULL) return false;
+  Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
+  memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
+  Controller->V1.FirstCommandMailbox = CommandMailboxesMemory;
+  CommandMailboxesMemory += DAC960_V1_CommandMailboxCount - 1;
+  Controller->V1.LastCommandMailbox = CommandMailboxesMemory;
+  Controller->V1.NextCommandMailbox =
+    &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
   if (--NextCommandMailboxIndex < 0)
-    NextCommandMailboxIndex = DAC960_CommandMailboxCount - 1;
-  Controller->PreviousCommandMailbox1 =
-    &Controller->FirstCommandMailbox[NextCommandMailboxIndex];
+    NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
+  Controller->V1.PreviousCommandMailbox1 =
+    &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
   if (--NextCommandMailboxIndex < 0)
-    NextCommandMailboxIndex = DAC960_CommandMailboxCount - 1;
-  Controller->PreviousCommandMailbox2 =
-    &Controller->FirstCommandMailbox[NextCommandMailboxIndex];
+    NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
+  Controller->V1.PreviousCommandMailbox2 =
+    &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
   StatusMailboxesMemory =
-    (DAC960_StatusMailbox_T *) (CommandMailboxesMemory + 1);
-  Controller->FirstStatusMailbox = StatusMailboxesMemory;
-  StatusMailboxesMemory += DAC960_StatusMailboxCount - 1;
-  Controller->LastStatusMailbox = StatusMailboxesMemory;
-  Controller->NextStatusMailbox =
-    &Controller->FirstStatusMailbox[NextStatusMailboxIndex];
+    (DAC960_V1_StatusMailbox_T *) (CommandMailboxesMemory + 1);
+  Controller->V1.FirstStatusMailbox = StatusMailboxesMemory;
+  StatusMailboxesMemory += DAC960_V1_StatusMailboxCount - 1;
+  Controller->V1.LastStatusMailbox = StatusMailboxesMemory;
+  Controller->V1.NextStatusMailbox =
+    &Controller->V1.FirstStatusMailbox[NextStatusMailboxIndex];
   if (SavedMemoryMailboxesAddress != NULL) return true;
   /* Enable the Memory Mailbox Interface. */
-  Controller->DualModeMemoryMailboxInterface = true;
+  Controller->V1.DualModeMemoryMailboxInterface = true;
   CommandMailbox.TypeX.CommandOpcode = 0x2B;
   CommandMailbox.TypeX.CommandIdentifier = 0;
   CommandMailbox.TypeX.CommandOpcode2 = 0x14;
   CommandMailbox.TypeX.CommandMailboxesBusAddress =
-    Virtual_to_Bus(Controller->FirstCommandMailbox);
+    Virtual_to_Bus(Controller->V1.FirstCommandMailbox);
   CommandMailbox.TypeX.StatusMailboxesBusAddress =
-    Virtual_to_Bus(Controller->FirstStatusMailbox);
+    Virtual_to_Bus(Controller->V1.FirstStatusMailbox);
   for (i = 0; i < 2; i++)
-    switch (Controller->ControllerType)
+    switch (Controller->HardwareType)
       {
-      case DAC960_V5_Controller:
+      case DAC960_LA_Controller:
 	while (--TimeoutCounter >= 0)
 	  {
-	    if (!DAC960_V5_HardwareMailboxFullP(ControllerBaseAddress))
+	    if (!DAC960_LA_HardwareMailboxFullP(ControllerBaseAddress))
 	      break;
 	    udelay(10);
 	  }
 	if (TimeoutCounter < 0) return false;
-	DAC960_V5_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
-	DAC960_V5_HardwareMailboxNewCommand(ControllerBaseAddress);
+	DAC960_LA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+	DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
 	while (--TimeoutCounter >= 0)
 	  {
-	    if (DAC960_V5_HardwareMailboxStatusAvailableP(
+	    if (DAC960_LA_HardwareMailboxStatusAvailableP(
 		  ControllerBaseAddress))
 	      break;
 	    udelay(10);
 	  }
 	if (TimeoutCounter < 0) return false;
-	CommandStatus = DAC960_V5_ReadStatusRegister(ControllerBaseAddress);
-	DAC960_V5_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
-	DAC960_V5_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
-	if (CommandStatus == DAC960_NormalCompletion) return true;
-	Controller->DualModeMemoryMailboxInterface = false;
+	CommandStatus = DAC960_LA_ReadStatusRegister(ControllerBaseAddress);
+	DAC960_LA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+	DAC960_LA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
+	if (CommandStatus == DAC960_V1_NormalCompletion) return true;
+	Controller->V1.DualModeMemoryMailboxInterface = false;
 	CommandMailbox.TypeX.CommandOpcode2 = 0x10;
 	break;
-      case DAC960_V4_Controller:
+      case DAC960_PG_Controller:
 	while (--TimeoutCounter >= 0)
 	  {
-	    if (!DAC960_V4_HardwareMailboxFullP(ControllerBaseAddress))
+	    if (!DAC960_PG_HardwareMailboxFullP(ControllerBaseAddress))
 	      break;
 	    udelay(10);
 	  }
 	if (TimeoutCounter < 0) return false;
-	DAC960_V4_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
-	DAC960_V4_HardwareMailboxNewCommand(ControllerBaseAddress);
+	DAC960_PG_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+	DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
 	while (--TimeoutCounter >= 0)
 	  {
-	    if (DAC960_V4_HardwareMailboxStatusAvailableP(
+	    if (DAC960_PG_HardwareMailboxStatusAvailableP(
 		  ControllerBaseAddress))
 	      break;
 	    udelay(10);
 	  }
 	if (TimeoutCounter < 0) return false;
-	CommandStatus = DAC960_V4_ReadStatusRegister(ControllerBaseAddress);
-	DAC960_V4_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
-	DAC960_V4_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
-	if (CommandStatus == DAC960_NormalCompletion) return true;
-	Controller->DualModeMemoryMailboxInterface = false;
+	CommandStatus = DAC960_PG_ReadStatusRegister(ControllerBaseAddress);
+	DAC960_PG_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+	DAC960_PG_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
+	if (CommandStatus == DAC960_V1_NormalCompletion) return true;
+	Controller->V1.DualModeMemoryMailboxInterface = false;
 	CommandMailbox.TypeX.CommandOpcode2 = 0x10;
 	break;
       default:
@@ -510,283 +895,165 @@
 
 
 /*
-  DAC960_DetectControllers detects DAC960 PCI RAID Controllers by interrogating
-  the PCI Configuration Space for Controller Type.
+  DAC960_V2_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
+  for DAC960 V2 Firmware Controllers.
 */
 
-static void DAC960_DetectControllers(DAC960_ControllerType_T ControllerType)
+static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
+						      *Controller)
 {
-  unsigned short VendorID = 0, DeviceID = 0;
-  unsigned int MemoryWindowSize = 0;
-  PCI_Device_T *PCI_Device = NULL;
-  switch (ControllerType)
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V2_CommandMailbox_T *CommandMailboxesMemory;
+  DAC960_V2_StatusMailbox_T *StatusMailboxesMemory;
+  DAC960_V2_CommandMailbox_T CommandMailbox;
+  DAC960_V2_CommandStatus_T CommandStatus = 0;
+  unsigned long MemoryMailboxPagesAddress;
+  unsigned long MemoryMailboxPagesOrder;
+  unsigned long MemoryMailboxPagesSize;
+  MemoryMailboxPagesOrder = 0;
+  MemoryMailboxPagesSize =
+    DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T) +
+    DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T) +
+    sizeof(DAC960_V2_HealthStatusBuffer_T);
+  while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
+    MemoryMailboxPagesOrder++;
+  MemoryMailboxPagesAddress =
+    __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
+  Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
+  CommandMailboxesMemory =
+    (DAC960_V2_CommandMailbox_T *) MemoryMailboxPagesAddress;
+  if (CommandMailboxesMemory == NULL) return false;
+  Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
+  memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
+  Controller->V2.FirstCommandMailbox = CommandMailboxesMemory;
+  CommandMailboxesMemory += DAC960_V2_CommandMailboxCount - 1;
+  Controller->V2.LastCommandMailbox = CommandMailboxesMemory;
+  Controller->V2.NextCommandMailbox = Controller->V2.FirstCommandMailbox;
+  Controller->V2.PreviousCommandMailbox1 = Controller->V2.LastCommandMailbox;
+  Controller->V2.PreviousCommandMailbox2 =
+    Controller->V2.LastCommandMailbox - 1;
+  StatusMailboxesMemory =
+    (DAC960_V2_StatusMailbox_T *) (CommandMailboxesMemory + 1);
+  Controller->V2.FirstStatusMailbox = StatusMailboxesMemory;
+  StatusMailboxesMemory += DAC960_V2_StatusMailboxCount - 1;
+  Controller->V2.LastStatusMailbox = StatusMailboxesMemory;
+  Controller->V2.NextStatusMailbox = Controller->V2.FirstStatusMailbox;
+  Controller->V2.HealthStatusBuffer =
+    (DAC960_V2_HealthStatusBuffer_T *) (StatusMailboxesMemory + 1);
+  /* Enable the Memory Mailbox Interface. */
+  memset(&CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));
+  CommandMailbox.SetMemoryMailbox.CommandIdentifier = 1;
+  CommandMailbox.SetMemoryMailbox.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox.SetMemoryMailbox.CommandControlBits.NoAutoRequestSense = true;
+  CommandMailbox.SetMemoryMailbox.FirstCommandMailboxSizeKB =
+    (DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T)) >> 10;
+  CommandMailbox.SetMemoryMailbox.FirstStatusMailboxSizeKB =
+    (DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T)) >> 10;
+  CommandMailbox.SetMemoryMailbox.SecondCommandMailboxSizeKB = 0;
+  CommandMailbox.SetMemoryMailbox.SecondStatusMailboxSizeKB = 0;
+  CommandMailbox.SetMemoryMailbox.RequestSenseSize = 0;
+  CommandMailbox.SetMemoryMailbox.IOCTL_Opcode = DAC960_V2_SetMemoryMailbox;
+  CommandMailbox.SetMemoryMailbox.HealthStatusBufferSizeKB = 1;
+  CommandMailbox.SetMemoryMailbox.HealthStatusBufferBusAddress =
+    Virtual_to_Bus(Controller->V2.HealthStatusBuffer);
+  CommandMailbox.SetMemoryMailbox.FirstCommandMailboxBusAddress =
+    Virtual_to_Bus(Controller->V2.FirstCommandMailbox);
+  CommandMailbox.SetMemoryMailbox.FirstStatusMailboxBusAddress =
+    Virtual_to_Bus(Controller->V2.FirstStatusMailbox);
+  switch (Controller->HardwareType)
     {
-    case DAC960_V5_Controller:
-      VendorID = PCI_VENDOR_ID_DEC;
-      DeviceID = PCI_DEVICE_ID_DEC_21285;
-      MemoryWindowSize = DAC960_V5_RegisterWindowSize;
+    case DAC960_BA_Controller:
+      while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress))
+	udelay(1);
+      DAC960_BA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+      DAC960_BA_HardwareMailboxNewCommand(ControllerBaseAddress);
+      while (!DAC960_BA_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
+	udelay(1);
+      CommandStatus = DAC960_BA_ReadCommandStatus(ControllerBaseAddress);
+      DAC960_BA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+      DAC960_BA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
       break;
-    case DAC960_V4_Controller:
-      VendorID = PCI_VENDOR_ID_MYLEX;
-      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960P_V4;
-      MemoryWindowSize = DAC960_V4_RegisterWindowSize;
+    case DAC960_LP_Controller:
+      while (DAC960_LP_HardwareMailboxFullP(ControllerBaseAddress))
+	udelay(1);
+      DAC960_LP_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+      DAC960_LP_HardwareMailboxNewCommand(ControllerBaseAddress);
+      while (!DAC960_LP_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
+	udelay(1);
+      CommandStatus = DAC960_LP_ReadCommandStatus(ControllerBaseAddress);
+      DAC960_LP_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+      DAC960_LP_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
       break;
-    case DAC960_V3_Controller:
-      VendorID = PCI_VENDOR_ID_MYLEX;
-      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960P_V3;
-      MemoryWindowSize = DAC960_V3_RegisterWindowSize;
+    default:
       break;
     }
-  while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
+  return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+  DAC960_V1_ReadControllerConfiguration reads the Configuration Information
+  from DAC960 V1 Firmware Controllers and initializes the Controller structure.
+*/
+
+static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
+						     *Controller)
+{
+  DAC960_V1_Enquiry2_T Enquiry2;
+  DAC960_V1_Config2_T Config2;
+  int LogicalDriveNumber, Channel, TargetID;
+  if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry,
+			      &Controller->V1.Enquiry))
+    return DAC960_Failure(Controller, "ENQUIRY");
+  if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry2, &Enquiry2))
+    return DAC960_Failure(Controller, "ENQUIRY2");
+  if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_ReadConfig2, &Config2))
+    return DAC960_Failure(Controller, "READ CONFIG2");
+  if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_GetLogicalDriveInformation,
+			      &Controller->V1.LogicalDriveInformation))
+    return DAC960_Failure(Controller, "GET LOGICAL DRIVE INFORMATION");
+  for (Channel = 0; Channel < Enquiry2.ActualChannels; Channel++)
+    for (TargetID = 0; TargetID < Enquiry2.MaxTargets; TargetID++)
+      if (!DAC960_V1_ExecuteType3D(Controller, DAC960_V1_GetDeviceState,
+				   Channel, TargetID,
+				   &Controller->V1.DeviceState
+						   [Channel][TargetID]))
+	return DAC960_Failure(Controller, "GET DEVICE STATE");
+  /*
+    Initialize the Controller Model Name and Full Model Name fields.
+  */
+  switch (Enquiry2.HardwareID.SubModel)
     {
-      DAC960_Controller_T *Controller = (DAC960_Controller_T *)
-	kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
-      DAC960_IO_Address_T IO_Address = 0;
-      DAC960_PCI_Address_T PCI_Address = 0;
-      unsigned char Bus = PCI_Device->bus->number;
-      unsigned char DeviceFunction = PCI_Device->devfn;
-      unsigned char Device = DeviceFunction >> 3;
-      unsigned char Function = DeviceFunction & 0x7;
-      unsigned char ErrorStatus, Parameter0, Parameter1;
-      unsigned int IRQ_Channel = PCI_Device->irq;
-      unsigned long BaseAddress0 = PCI_Device->base_address[0];
-      unsigned long BaseAddress1 = PCI_Device->base_address[1];
-      unsigned short SubsystemVendorID, SubsystemDeviceID;
-      int CommandIdentifier;
-      void *BaseAddress;
-      pci_read_config_word(PCI_Device, PCI_SUBSYSTEM_VENDOR_ID,
-			   &SubsystemVendorID);
-      pci_read_config_word(PCI_Device, PCI_SUBSYSTEM_ID,
-			   &SubsystemDeviceID);
-      switch (ControllerType)
-	{
-	case DAC960_V5_Controller:
-	  if (!(SubsystemVendorID == PCI_VENDOR_ID_MYLEX &&
-		SubsystemDeviceID == PCI_DEVICE_ID_MYLEX_DAC960P_V5))
-	    goto Ignore;
-	  PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
-	  break;
-	case DAC960_V4_Controller:
-	  PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
-	  break;
-	case DAC960_V3_Controller:
-	  IO_Address = BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
-	  PCI_Address = BaseAddress1 & PCI_BASE_ADDRESS_MEM_MASK;
-	  break;
-	}
-      if (DAC960_ControllerCount == DAC960_MaxControllers)
-	{
-	  DAC960_Error("More than %d DAC960 Controllers detected - "
-		       "ignoring from Controller at\n",
-		       NULL, DAC960_MaxControllers);
-	  goto Ignore;
-	}
-      if (Controller == NULL)
-	{
-	  DAC960_Error("Unable to allocate Controller structure for "
-		       "Controller at\n", NULL);
-	  goto Ignore;
-	}
-      memset(Controller, 0, sizeof(DAC960_Controller_T));
-      Controller->ControllerNumber = DAC960_ControllerCount;
-      DAC960_Controllers[DAC960_ControllerCount++] = Controller;
-      DAC960_AnnounceDriver(Controller);
-      Controller->ControllerType = ControllerType;
-      Controller->IO_Address = IO_Address;
-      Controller->PCI_Address = PCI_Address;
-      Controller->Bus = Bus;
-      Controller->Device = Device;
-      Controller->Function = Function;
-      sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
-      /*
-	Map the Controller Register Window.
-      */
-      if (MemoryWindowSize < PAGE_SIZE)
-	MemoryWindowSize = PAGE_SIZE;
-      Controller->MemoryMappedAddress =
-	ioremap_nocache(PCI_Address & PAGE_MASK, MemoryWindowSize);
-      Controller->BaseAddress =
-	Controller->MemoryMappedAddress + (PCI_Address & ~PAGE_MASK);
-      if (Controller->MemoryMappedAddress == NULL)
-	{
-	  DAC960_Error("Unable to map Controller Register Window for "
-		       "Controller at\n", Controller);
-	  goto Failure;
-	}
-      BaseAddress = Controller->BaseAddress;
-      switch (ControllerType)
-	{
-	case DAC960_V5_Controller:
-	  DAC960_V5_DisableInterrupts(BaseAddress);
-	  DAC960_V5_AcknowledgeHardwareMailboxStatus(BaseAddress);
-	  udelay(1000);
-	  while (DAC960_V5_InitializationInProgressP(BaseAddress))
-	    {
-	      if (DAC960_V5_ReadErrorStatus(BaseAddress, &ErrorStatus,
-					    &Parameter0, &Parameter1) &&
-		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
-					   Parameter0, Parameter1))
-		goto Failure;
-	      udelay(10);
-	    }
-	  if (!DAC960_EnableMemoryMailboxInterface(Controller))
-	    {
-	      DAC960_Error("Unable to Enable Memory Mailbox Interface "
-			   "for Controller at\n", Controller);
-	      goto Failure;
-	    }
-	  DAC960_V5_EnableInterrupts(BaseAddress);
-	  break;
-	case DAC960_V4_Controller:
-	  DAC960_V4_DisableInterrupts(BaseAddress);
-	  DAC960_V4_AcknowledgeHardwareMailboxStatus(BaseAddress);
-	  udelay(1000);
-	  while (DAC960_V4_InitializationInProgressP(BaseAddress))
-	    {
-	      if (DAC960_V4_ReadErrorStatus(BaseAddress, &ErrorStatus,
-					    &Parameter0, &Parameter1) &&
-		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
-					   Parameter0, Parameter1))
-		goto Failure;
-	      udelay(10);
-	    }
-	  if (!DAC960_EnableMemoryMailboxInterface(Controller))
-	    {
-	      DAC960_Error("Unable to Enable Memory Mailbox Interface "
-			   "for Controller at\n", Controller);
-	      goto Failure;
-	    }
-	  DAC960_V4_EnableInterrupts(BaseAddress);
-	  break;
-	case DAC960_V3_Controller:
-	  request_region(Controller->IO_Address, 0x80,
-			 Controller->FullModelName);
-	  DAC960_V3_DisableInterrupts(BaseAddress);
-	  DAC960_V3_AcknowledgeStatus(BaseAddress);
-	  udelay(1000);
-	  while (DAC960_V3_InitializationInProgressP(BaseAddress))
-	    {
-	      if (DAC960_V3_ReadErrorStatus(BaseAddress, &ErrorStatus,
-					    &Parameter0, &Parameter1) &&
-		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
-					   Parameter0, Parameter1))
-		goto Failure;
-	      udelay(10);
-	    }
-	  DAC960_V3_EnableInterrupts(BaseAddress);
-	  break;
-	}
-      /*
-	Acquire shared access to the IRQ Channel.
-      */
-      if (IRQ_Channel == 0)
-	{
-	  DAC960_Error("IRQ Channel %d illegal for Controller at\n",
-		       Controller, IRQ_Channel);
-	  goto Failure;
-	}
-      strcpy(Controller->FullModelName, "DAC960");
-      if (request_irq(IRQ_Channel, DAC960_InterruptHandler,
-		      SA_SHIRQ, Controller->FullModelName, Controller) < 0)
-	{
-	  DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
-		       Controller, IRQ_Channel);
-	  goto Failure;
-	}
-      Controller->IRQ_Channel = IRQ_Channel;
-      DAC960_ActiveControllerCount++;
-      for (CommandIdentifier = 0;
-	   CommandIdentifier < DAC960_MaxChannels;
-	   CommandIdentifier++)
-	{
-	  Controller->Commands[CommandIdentifier].Controller = Controller;
-	  Controller->Commands[CommandIdentifier].Next =
-	    Controller->FreeCommands;
-	  Controller->FreeCommands = &Controller->Commands[CommandIdentifier];
-	}
-      continue;
-    Failure:
-      if (IO_Address == 0)
-	DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
-		     "PCI Address 0x%X\n", Controller,
-		     Bus, Device, Function, PCI_Address);
-      else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
-			"0x%X PCI Address 0x%X\n", Controller,
-			Bus, Device, Function, IO_Address, PCI_Address);
-      if (Controller == NULL) break;
-      if (Controller->MemoryMappedAddress != NULL)
-	iounmap(Controller->MemoryMappedAddress);
-      DAC960_Controllers[Controller->ControllerNumber] = NULL;
-      if (Controller->IRQ_Channel > 0)
-	free_irq(IRQ_Channel, Controller);
-    Ignore:
-      kfree(Controller);
-    }
-}
-
-
-/*
-  DAC960_ReadControllerConfiguration reads the Configuration Information
-  from Controller and initializes the Controller structure.
-*/
-
-static boolean DAC960_ReadControllerConfiguration(DAC960_Controller_T
-						  *Controller)
-{
-  DAC960_Enquiry2_T Enquiry2;
-  DAC960_Config2_T Config2;
-  int LogicalDriveNumber, Channel, TargetID;
-  if (!DAC960_ExecuteType3(Controller, DAC960_Enquiry,
-			   &Controller->Enquiry[0]))
-    return DAC960_Failure(Controller, "ENQUIRY");
-  if (!DAC960_ExecuteType3(Controller, DAC960_Enquiry2, &Enquiry2))
-    return DAC960_Failure(Controller, "ENQUIRY2");
-  if (!DAC960_ExecuteType3(Controller, DAC960_ReadConfig2, &Config2))
-    return DAC960_Failure(Controller, "READ CONFIG2");
-  if (!DAC960_ExecuteType3(Controller, DAC960_GetLogicalDriveInformation,
-			   &Controller->LogicalDriveInformation[0]))
-    return DAC960_Failure(Controller, "GET LOGICAL DRIVE INFORMATION");
-  for (Channel = 0; Channel < Enquiry2.ActualChannels; Channel++)
-    for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
-      if (!DAC960_ExecuteType3D(Controller, DAC960_GetDeviceState,
-				Channel, TargetID,
-				&Controller->DeviceState[0][Channel][TargetID]))
-	return DAC960_Failure(Controller, "GET DEVICE STATE");
-  /*
-    Initialize the Controller Model Name and Full Model Name fields.
-  */
-  switch (Enquiry2.HardwareID.SubModel)
-    {
-    case DAC960_P_PD_PU:
-      if (Enquiry2.SCSICapability.BusSpeed == DAC960_Ultra)
+    case DAC960_V1_P_PD_PU:
+      if (Enquiry2.SCSICapability.BusSpeed == DAC960_V1_Ultra)
 	strcpy(Controller->ModelName, "DAC960PU");
       else strcpy(Controller->ModelName, "DAC960PD");
       break;
-    case DAC960_PL:
+    case DAC960_V1_PL:
       strcpy(Controller->ModelName, "DAC960PL");
       break;
-    case DAC960_PG:
+    case DAC960_V1_PG:
       strcpy(Controller->ModelName, "DAC960PG");
       break;
-    case DAC960_PJ:
+    case DAC960_V1_PJ:
       strcpy(Controller->ModelName, "DAC960PJ");
       break;
-    case DAC960_PR:
+    case DAC960_V1_PR:
       strcpy(Controller->ModelName, "DAC960PR");
       break;
-    case DAC960_PT:
+    case DAC960_V1_PT:
       strcpy(Controller->ModelName, "DAC960PT");
       break;
-    case DAC960_PTL0:
+    case DAC960_V1_PTL0:
       strcpy(Controller->ModelName, "DAC960PTL0");
       break;
-    case DAC960_PRL:
+    case DAC960_V1_PRL:
       strcpy(Controller->ModelName, "DAC960PRL");
       break;
-    case DAC960_PTL1:
+    case DAC960_V1_PTL1:
       strcpy(Controller->ModelName, "DAC960PTL1");
       break;
-    case DAC1164_P:
+    case DAC960_V1_1164P:
       strcpy(Controller->ModelName, "DAC1164P");
       break;
     default:
@@ -818,61 +1085,197 @@
       return false;
     }
   /*
-    Initialize the Controller Channels, Memory Size, and SAF-TE Enclosure
-    Management Enabled fields.
+    Initialize the Controller Channels, Targets, Memory Size, and SAF-TE
+    Enclosure Management Enabled fields.
   */
   Controller->Channels = Enquiry2.ActualChannels;
+  Controller->Targets = Enquiry2.MaxTargets;
   Controller->MemorySize = Enquiry2.MemorySize >> 20;
-  Controller->SAFTE_EnclosureManagementEnabled =
-    Enquiry2.FaultManagementType == DAC960_SAFTE;
+  Controller->V1.SAFTE_EnclosureManagementEnabled =
+    (Enquiry2.FaultManagementType == DAC960_V1_SAFTE);
   /*
     Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
-    Count, Maximum Blocks per Command, and Maximum Scatter/Gather Segments.
-    The Driver Queue Depth must be at most one less than the Controller Queue
-    Depth to allow for an automatic drive rebuild operation.
+    Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and
+    Driver Scatter/Gather Limit.  The Driver Queue Depth must be at most one
+    less than the Controller Queue Depth to allow for an automatic drive
+    rebuild operation.
   */
-  Controller->ControllerQueueDepth = Controller->Enquiry[0].MaxCommands;
+  Controller->ControllerQueueDepth = Controller->V1.Enquiry.MaxCommands;
   Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
-  Controller->LogicalDriveCount = Controller->Enquiry[0].NumberOfLogicalDrives;
+  if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth)
+    Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
+  Controller->LogicalDriveCount =
+    Controller->V1.Enquiry.NumberOfLogicalDrives;
   Controller->MaxBlocksPerCommand = Enquiry2.MaxBlocksPerCommand;
-  Controller->MaxScatterGatherSegments = Enquiry2.MaxScatterGatherEntries;
+  Controller->ControllerScatterGatherLimit = Enquiry2.MaxScatterGatherEntries;
+  Controller->DriverScatterGatherLimit =
+    Controller->ControllerScatterGatherLimit;
+  if (Controller->DriverScatterGatherLimit > DAC960_V1_ScatterGatherLimit)
+    Controller->DriverScatterGatherLimit = DAC960_V1_ScatterGatherLimit;
   /*
     Initialize the Stripe Size, Segment Size, and Geometry Translation.
   */
-  Controller->StripeSize = Config2.BlocksPerStripe * Config2.BlockFactor
-			   >> (10 - DAC960_BlockSizeBits);
-  Controller->SegmentSize = Config2.BlocksPerCacheLine * Config2.BlockFactor
-			    >> (10 - DAC960_BlockSizeBits);
+  Controller->V1.StripeSize = Config2.BlocksPerStripe * Config2.BlockFactor
+			      >> (10 - DAC960_BlockSizeBits);
+  Controller->V1.SegmentSize = Config2.BlocksPerCacheLine * Config2.BlockFactor
+			       >> (10 - DAC960_BlockSizeBits);
   switch (Config2.DriveGeometry)
     {
-    case DAC960_Geometry_128_32:
-      Controller->GeometryTranslationHeads = 128;
-      Controller->GeometryTranslationSectors = 32;
-      break;
-    case DAC960_Geometry_255_63:
-      Controller->GeometryTranslationHeads = 255;
-      Controller->GeometryTranslationSectors = 63;
+    case DAC960_V1_Geometry_128_32:
+      Controller->V1.GeometryTranslationHeads = 128;
+      Controller->V1.GeometryTranslationSectors = 32;
+      break;
+    case DAC960_V1_Geometry_255_63:
+      Controller->V1.GeometryTranslationHeads = 255;
+      Controller->V1.GeometryTranslationSectors = 63;
       break;
     default:
       return DAC960_Failure(Controller, "CONFIG2 DRIVE GEOMETRY");
     }
   /*
-    Initialize the Logical Drive Initial State.
+    Initialize the Logical Drive Initially Accessible flag.
   */
   for (LogicalDriveNumber = 0;
        LogicalDriveNumber < Controller->LogicalDriveCount;
        LogicalDriveNumber++)
-    Controller->LogicalDriveInitialState[LogicalDriveNumber] =
-      Controller->LogicalDriveInformation[0]
-		  [LogicalDriveNumber].LogicalDriveState;
-  Controller->LastRebuildStatus = DAC960_NoRebuildOrCheckInProgress;
+    if (Controller->V1.LogicalDriveInformation
+		       [LogicalDriveNumber].LogicalDriveState !=
+	DAC960_V1_LogicalDrive_Offline)
+      Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
+  Controller->V1.LastRebuildStatus = DAC960_V1_NoRebuildOrCheckInProgress;
   return true;
 }
 
 
 /*
-  DAC960_ReportControllerConfiguration reports the Configuration Information of
-  Controller.
+  DAC960_V2_ReadControllerConfiguration reads the Configuration Information
+  from DAC960 V2 Firmware Controllers and initializes the Controller structure.
+*/
+
+static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
+						     *Controller)
+{
+  DAC960_V2_ControllerInfo_T *ControllerInfo =
+    &Controller->V2.ControllerInformation;
+  unsigned short LogicalDeviceNumber = 0;
+  int ModelNameLength;
+  if (!DAC960_V2_ControllerInfo(Controller, DAC960_V2_GetControllerInfo,
+				ControllerInfo,
+				sizeof(DAC960_V2_ControllerInfo_T)))
+    return DAC960_Failure(Controller, "GET CONTROLLER INFO");
+  if (!DAC960_V2_GeneralInfo(Controller, DAC960_V2_GetHealthStatus,
+			     Controller->V2.HealthStatusBuffer,
+			     sizeof(DAC960_V2_HealthStatusBuffer_T)))
+    return DAC960_Failure(Controller, "GET HEALTH STATUS");
+  /*
+    Initialize the Controller Model Name and Full Model Name fields.
+  */
+  ModelNameLength = sizeof(ControllerInfo->ControllerName);
+  if (ModelNameLength > sizeof(Controller->ModelName)-1)
+    ModelNameLength = sizeof(Controller->ModelName)-1;
+  memcpy(Controller->ModelName, ControllerInfo->ControllerName,
+	 ModelNameLength);
+  ModelNameLength--;
+  while (Controller->ModelName[ModelNameLength] == ' ' ||
+	 Controller->ModelName[ModelNameLength] == '\0')
+    ModelNameLength--;
+  Controller->ModelName[++ModelNameLength] = '\0';
+  strcpy(Controller->FullModelName, "Mylex ");
+  strcat(Controller->FullModelName, Controller->ModelName);
+  /*
+    Initialize the Controller Firmware Version field.
+  */
+  sprintf(Controller->FirmwareVersion, "%d.%02d-%02d",
+	  ControllerInfo->FirmwareMajorVersion,
+	  ControllerInfo->FirmwareMinorVersion,
+	  ControllerInfo->FirmwareTurnNumber);
+  if (ControllerInfo->FirmwareMajorVersion == 6 &&
+      ControllerInfo->FirmwareMinorVersion == 0 &&
+      ControllerInfo->FirmwareTurnNumber < 1)
+    {
+      DAC960_Info("FIRMWARE VERSION %s DOES NOT PROVIDE THE CONTROLLER\n",
+		  Controller, Controller->FirmwareVersion);
+      DAC960_Info("STATUS MONITORING FUNCTIONALITY NEEDED BY THIS DRIVER.\n",
+		  Controller);
+      DAC960_Info("PLEASE UPGRADE TO VERSION 6.00-01 OR ABOVE.\n",
+		  Controller);
+    }
+  /*
+    Initialize the Controller Channels, Targets, and Memory Size.
+  */
+  Controller->Channels = ControllerInfo->NumberOfPhysicalChannelsPresent;
+  Controller->Targets =
+    ControllerInfo->MaximumTargetsPerChannel
+		    [ControllerInfo->NumberOfPhysicalChannelsPresent-1];
+  Controller->MemorySize = ControllerInfo->MemorySizeMB;
+  /*
+    Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
+    Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and
+    Driver Scatter/Gather Limit.  The Driver Queue Depth must be at most one
+    less than the Controller Queue Depth to allow for an automatic drive
+    rebuild operation.
+  */
+  Controller->ControllerQueueDepth = ControllerInfo->MaximumParallelCommands;
+  Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
+  if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth)
+    Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
+  Controller->LogicalDriveCount = ControllerInfo->LogicalDevicesPresent;
+  Controller->MaxBlocksPerCommand =
+    ControllerInfo->MaximumDataTransferSizeInBlocks;
+  Controller->ControllerScatterGatherLimit =
+    ControllerInfo->MaximumScatterGatherEntries;
+  Controller->DriverScatterGatherLimit =
+    Controller->ControllerScatterGatherLimit;
+  if (Controller->DriverScatterGatherLimit > DAC960_V2_ScatterGatherLimit)
+    Controller->DriverScatterGatherLimit = DAC960_V2_ScatterGatherLimit;
+  /*
+    Initialize the Logical Device Information.
+  */
+  while (true)
+    {
+      DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
+	&Controller->V2.NewLogicalDeviceInformation;
+      DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo;
+      DAC960_V2_PhysicalDevice_T PhysicalDevice;
+      if (!DAC960_V2_LogicalDeviceInfo(Controller,
+				       DAC960_V2_GetLogicalDeviceInfoValid,
+				       LogicalDeviceNumber,
+				       NewLogicalDeviceInfo,
+				       sizeof(DAC960_V2_LogicalDeviceInfo_T)))
+	break;
+      LogicalDeviceNumber = NewLogicalDeviceInfo->LogicalDeviceNumber;
+      if (LogicalDeviceNumber > DAC960_MaxLogicalDrives)
+	panic("DAC960: Logical Drive Number %d not supported\n",
+		       LogicalDeviceNumber);
+      if (NewLogicalDeviceInfo->DeviceBlockSizeInBytes != DAC960_BlockSize)
+	panic("DAC960: Logical Drive Block Size %d not supported\n",
+	      NewLogicalDeviceInfo->DeviceBlockSizeInBytes);
+      PhysicalDevice.Controller = 0;
+      PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
+      PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
+      PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
+      Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
+	PhysicalDevice;
+      if (NewLogicalDeviceInfo->LogicalDeviceState !=
+	  DAC960_V2_LogicalDevice_Offline)
+	Controller->LogicalDriveInitiallyAccessible[LogicalDeviceNumber] = true;
+      LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
+	kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
+      if (LogicalDeviceInfo == NULL)
+	return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION");
+      Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
+	LogicalDeviceInfo;
+      memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
+	     sizeof(DAC960_V2_LogicalDeviceInfo_T));
+      LogicalDeviceNumber++;
+    }
+  return true;
+}
+
+
+/*
+  DAC960_ReportControllerConfiguration reports the Configuration Information
+  for Controller.
 */
 
 static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T
@@ -898,54 +1301,60 @@
 	      Controller, Controller->ControllerQueueDepth,
 	      Controller->MaxBlocksPerCommand);
   DAC960_Info("  Driver Queue Depth: %d, "
-	      "Maximum Scatter/Gather Segments: %d\n",
+	      "Scatter/Gather Limit: %d of %d Segments\n",
 	      Controller, Controller->DriverQueueDepth,
-	      Controller->MaxScatterGatherSegments);
-  DAC960_Info("  Stripe Size: %dKB, Segment Size: %dKB, "
-	      "BIOS Geometry: %d/%d\n", Controller,
-	      Controller->StripeSize,
-	      Controller->SegmentSize,
-	      Controller->GeometryTranslationHeads,
-	      Controller->GeometryTranslationSectors);
-  if (Controller->SAFTE_EnclosureManagementEnabled)
-    DAC960_Info("  SAF-TE Enclosure Management Enabled\n", Controller);
+	      Controller->DriverScatterGatherLimit,
+	      Controller->ControllerScatterGatherLimit);
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+    {
+      DAC960_Info("  Stripe Size: %dKB, Segment Size: %dKB, "
+		  "BIOS Geometry: %d/%d\n", Controller,
+		  Controller->V1.StripeSize,
+		  Controller->V1.SegmentSize,
+		  Controller->V1.GeometryTranslationHeads,
+		  Controller->V1.GeometryTranslationSectors);
+      if (Controller->V1.SAFTE_EnclosureManagementEnabled)
+	DAC960_Info("  SAF-TE Enclosure Management Enabled\n", Controller);
+    }
   return true;
 }
 
 
 /*
-  DAC960_ReadDeviceConfiguration reads the Device Configuration Information by
-  requesting the SCSI Inquiry and SCSI Inquiry Unit Serial Number information
-  for each device connected to Controller.
+  DAC960_V1_ReadDeviceConfiguration reads the Device Configuration Information
+  for DAC960 V1 Firmware Controllers by requesting the SCSI Inquiry and SCSI
+  Inquiry Unit Serial Number information for each device connected to
+  Controller.
 */
 
-static boolean DAC960_ReadDeviceConfiguration(DAC960_Controller_T *Controller)
+static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
+						 *Controller)
 {
-  DAC960_DCDB_T DCDBs[DAC960_MaxChannels], *DCDB;
-  Semaphore_T Semaphores[DAC960_MaxChannels], *Semaphore;
+  DAC960_V1_DCDB_T DCDBs[DAC960_V1_MaxChannels], *DCDB;
+  Semaphore_T Semaphores[DAC960_V1_MaxChannels], *Semaphore;
   unsigned long ProcessorFlags;
   int Channel, TargetID;
-  for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
+  for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
     {
       for (Channel = 0; Channel < Controller->Channels; Channel++)
 	{
-	  DAC960_Command_T *Command = &Controller->Commands[Channel];
+	  DAC960_Command_T *Command = Controller->Commands[Channel];
 	  DAC960_SCSI_Inquiry_T *InquiryStandardData =
-	    &Controller->InquiryStandardData[Channel][TargetID];
+	    &Controller->V1.InquiryStandardData[Channel][TargetID];
 	  InquiryStandardData->PeripheralDeviceType = 0x1F;
 	  Semaphore = &Semaphores[Channel];
 	  *Semaphore = MUTEX_LOCKED;
 	  DCDB = &DCDBs[Channel];
-	  DAC960_ClearCommand(Command);
+	  DAC960_V1_ClearCommand(Command);
 	  Command->CommandType = DAC960_ImmediateCommand;
 	  Command->Semaphore = Semaphore;
-	  Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
-	  Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
+	  Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
+	  Command->V1.CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
 	  DCDB->Channel = Channel;
 	  DCDB->TargetID = TargetID;
-	  DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
+	  DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
 	  DCDB->EarlyStatus = false;
-	  DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
+	  DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
 	  DCDB->NoAutomaticRequestSense = false;
 	  DCDB->DisconnectPermitted = true;
 	  DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
@@ -965,13 +1374,14 @@
 	}
       for (Channel = 0; Channel < Controller->Channels; Channel++)
 	{
-	  DAC960_Command_T *Command = &Controller->Commands[Channel];
+	  DAC960_Command_T *Command = Controller->Commands[Channel];
 	  DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
-	    &Controller->InquiryUnitSerialNumber[Channel][TargetID];
+	    &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
 	  InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
 	  Semaphore = &Semaphores[Channel];
 	  down(Semaphore);
-	  if (Command->CommandStatus != DAC960_NormalCompletion) continue;
+	  if (Command->V1.CommandStatus != DAC960_V1_NormalCompletion)
+	    continue;
 	  Command->Semaphore = Semaphore;
 	  DCDB = &DCDBs[Channel];
 	  DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
@@ -989,107 +1399,215 @@
 	  down(Semaphore);
 	}
     }
-  return true; 
+  return true;
+}
+
+
+/*
+  DAC960_V2_ReadDeviceConfiguration reads the Device Configuration Information
+  for DAC960 V2 Firmware Controllers by requesting the Physical Device
+  Information and SCSI Inquiry Unit Serial Number information for each
+  device connected to Controller.
+*/
+
+static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
+						 *Controller)
+{
+  unsigned char Channel = 0, TargetID = 0, LogicalUnit = 0;
+  unsigned short PhysicalDeviceIndex = 0;
+  while (true)
+    {
+      DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
+	&Controller->V2.NewPhysicalDeviceInformation;
+      DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo;
+      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber;
+      DAC960_Command_T *Command;
+      DAC960_V2_CommandMailbox_T *CommandMailbox;
+      if (!DAC960_V2_PhysicalDeviceInfo(Controller,
+					DAC960_V2_GetPhysicalDeviceInfoValid,
+					Channel,
+					TargetID,
+					LogicalUnit,
+					NewPhysicalDeviceInfo,
+					sizeof(DAC960_V2_PhysicalDeviceInfo_T)))
+	  break;
+      Channel = NewPhysicalDeviceInfo->Channel;
+      TargetID = NewPhysicalDeviceInfo->TargetID;
+      LogicalUnit = NewPhysicalDeviceInfo->LogicalUnit;
+      PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
+	kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
+      if (PhysicalDeviceInfo == NULL)
+	return DAC960_Failure(Controller, "PHYSICAL DEVICE ALLOCATION");
+      Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex] =
+	PhysicalDeviceInfo;
+      memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
+	     sizeof(DAC960_V2_PhysicalDeviceInfo_T));
+      InquiryUnitSerialNumber = (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
+	kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC);
+      if (InquiryUnitSerialNumber == NULL)
+	return DAC960_Failure(Controller, "SERIAL NUMBER ALLOCATION");
+      Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex] =
+	InquiryUnitSerialNumber;
+      memset(InquiryUnitSerialNumber, 0,
+	     sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
+      InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+      Command = DAC960_AllocateCommand(Controller);
+      CommandMailbox = &Command->V2.CommandMailbox;
+      DAC960_V2_ClearCommand(Command);
+      Command->CommandType = DAC960_ImmediateCommand;
+      CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10_Passthru;
+      CommandMailbox->SCSI_10.CommandControlBits
+			     .DataTransferControllerToHost = true;
+      CommandMailbox->SCSI_10.CommandControlBits
+			     .NoAutoRequestSense = true;
+      CommandMailbox->SCSI_10.DataTransferSize =
+	sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+      CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit = LogicalUnit;
+      CommandMailbox->SCSI_10.PhysicalDevice.TargetID = TargetID;
+      CommandMailbox->SCSI_10.PhysicalDevice.Channel = Channel;
+      CommandMailbox->SCSI_10.CDBLength = 6;
+      CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
+      CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
+      CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
+      CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
+      CommandMailbox->SCSI_10.SCSI_CDB[4] =
+	sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+      CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
+      CommandMailbox->SCSI_10.DataTransferMemoryAddress
+			     .ScatterGatherSegments[0]
+			     .SegmentDataPointer =
+	Virtual_to_Bus(InquiryUnitSerialNumber);
+      CommandMailbox->SCSI_10.DataTransferMemoryAddress
+			     .ScatterGatherSegments[0]
+			     .SegmentByteCount =
+	CommandMailbox->SCSI_10.DataTransferSize;
+      DAC960_ExecuteCommand(Command);
+      DAC960_DeallocateCommand(Command);
+      PhysicalDeviceIndex++;
+      LogicalUnit++;
+    }
+  return true;
+}
+
+
+/*
+  DAC960_SanitizeInquiryData sanitizes the Vendor, Model, Revision, and
+  Product Serial Number fields of the Inquiry Standard Data and Inquiry
+  Unit Serial Number structures.
+*/
+
+static void DAC960_SanitizeInquiryData(DAC960_SCSI_Inquiry_T
+					 *InquiryStandardData,
+				       DAC960_SCSI_Inquiry_UnitSerialNumber_T
+					 *InquiryUnitSerialNumber,
+				       unsigned char *Vendor,
+				       unsigned char *Model,
+				       unsigned char *Revision,
+				       unsigned char *SerialNumber)
+{
+  int SerialNumberLength, i;
+  if (InquiryStandardData->PeripheralDeviceType == 0x1F) return;
+  for (i = 0; i < sizeof(InquiryStandardData->VendorIdentification); i++)
+    {
+      unsigned char VendorCharacter =
+	InquiryStandardData->VendorIdentification[i];
+      Vendor[i] = (VendorCharacter >= ' ' && VendorCharacter <= '~'
+		   ? VendorCharacter : ' ');
+    }
+  Vendor[sizeof(InquiryStandardData->VendorIdentification)] = '\0';
+  for (i = 0; i < sizeof(InquiryStandardData->ProductIdentification); i++)
+    {
+      unsigned char ModelCharacter =
+	InquiryStandardData->ProductIdentification[i];
+      Model[i] = (ModelCharacter >= ' ' && ModelCharacter <= '~'
+		  ? ModelCharacter : ' ');
+    }
+  Model[sizeof(InquiryStandardData->ProductIdentification)] = '\0';
+  for (i = 0; i < sizeof(InquiryStandardData->ProductRevisionLevel); i++)
+    {
+      unsigned char RevisionCharacter =
+	InquiryStandardData->ProductRevisionLevel[i];
+      Revision[i] = (RevisionCharacter >= ' ' && RevisionCharacter <= '~'
+		     ? RevisionCharacter : ' ');
+    }
+  Revision[sizeof(InquiryStandardData->ProductRevisionLevel)] = '\0';
+  if (InquiryUnitSerialNumber->PeripheralDeviceType == 0x1F) return;
+  SerialNumberLength = InquiryUnitSerialNumber->PageLength;
+  if (SerialNumberLength >
+      sizeof(InquiryUnitSerialNumber->ProductSerialNumber))
+    SerialNumberLength = sizeof(InquiryUnitSerialNumber->ProductSerialNumber);
+  for (i = 0; i < SerialNumberLength; i++)
+    {
+      unsigned char SerialNumberCharacter =
+	InquiryUnitSerialNumber->ProductSerialNumber[i];
+      SerialNumber[i] =
+	(SerialNumberCharacter >= ' ' && SerialNumberCharacter <= '~'
+	 ? SerialNumberCharacter : ' ');
+    }
+  SerialNumber[SerialNumberLength] = '\0';
 }
 
 
 /*
-  DAC960_ReportDeviceConfiguration reports the Device Configuration Information
-  of Controller.
+  DAC960_V1_ReportDeviceConfiguration reports the Device Configuration
+  Information for DAC960 V1 Firmware Controllers.
 */
 
-static boolean DAC960_ReportDeviceConfiguration(DAC960_Controller_T *Controller)
+static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
+						   *Controller)
 {
   int LogicalDriveNumber, Channel, TargetID;
   DAC960_Info("  Physical Devices:\n", Controller);
   for (Channel = 0; Channel < Controller->Channels; Channel++)
-    for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
+    for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
       {
 	DAC960_SCSI_Inquiry_T *InquiryStandardData =
-	  &Controller->InquiryStandardData[Channel][TargetID];
+	  &Controller->V1.InquiryStandardData[Channel][TargetID];
 	DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
-	  &Controller->InquiryUnitSerialNumber[Channel][TargetID];
-	DAC960_DeviceState_T *DeviceState =
-	  &Controller->DeviceState[Controller->DeviceStateIndex]
-				  [Channel][TargetID];
-	DAC960_ErrorTable_T *ErrorTable =
-	  &Controller->ErrorTable[Controller->ErrorTableIndex];
-	DAC960_ErrorTableEntry_T *ErrorEntry =
-	  &ErrorTable->ErrorTableEntries[Channel][TargetID];
+	  &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
+	DAC960_V1_DeviceState_T *DeviceState =
+	  &Controller->V1.DeviceState[Channel][TargetID];
+	DAC960_V1_ErrorTableEntry_T *ErrorEntry =
+	  &Controller->V1.ErrorTable.ErrorTableEntries[Channel][TargetID];
 	char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)];
 	char Model[1+sizeof(InquiryStandardData->ProductIdentification)];
 	char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)];
 	char SerialNumber[1+sizeof(InquiryUnitSerialNumber
 				   ->ProductSerialNumber)];
-	int i;
 	if (InquiryStandardData->PeripheralDeviceType == 0x1F) continue;
-	for (i = 0; i < sizeof(Vendor)-1; i++)
-	  {
-	    unsigned char VendorCharacter =
-	      InquiryStandardData->VendorIdentification[i];
-	    Vendor[i] = (VendorCharacter >= ' ' && VendorCharacter <= '~'
-			 ? VendorCharacter : ' ');
-	  }
-	Vendor[sizeof(Vendor)-1] = '\0';
-	for (i = 0; i < sizeof(Model)-1; i++)
-	  {
-	    unsigned char ModelCharacter =
-	      InquiryStandardData->ProductIdentification[i];
-	    Model[i] = (ModelCharacter >= ' ' && ModelCharacter <= '~'
-			? ModelCharacter : ' ');
-	  }
-	Model[sizeof(Model)-1] = '\0';
-	for (i = 0; i < sizeof(Revision)-1; i++)
-	  {
-	    unsigned char RevisionCharacter =
-	      InquiryStandardData->ProductRevisionLevel[i];
-	    Revision[i] = (RevisionCharacter >= ' ' && RevisionCharacter <= '~'
-			   ? RevisionCharacter : ' ');
-	  }
-	Revision[sizeof(Revision)-1] = '\0';
+	DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber,
+				   Vendor, Model, Revision, SerialNumber);
 	DAC960_Info("    %d:%d%s Vendor: %s  Model: %s  Revision: %s\n",
 		    Controller, Channel, TargetID, (TargetID < 10 ? " " : ""),
 		    Vendor, Model, Revision);
 	if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
+	  DAC960_Info("         Serial Number: %s\n", Controller, SerialNumber);
+	if (DeviceState->Present &&
+	    DeviceState->DeviceType == DAC960_V1_DiskType)
 	  {
-	    int SerialNumberLength = InquiryUnitSerialNumber->PageLength;
-	    if (SerialNumberLength >
-		sizeof(InquiryUnitSerialNumber->ProductSerialNumber))
-	      SerialNumberLength =
-		sizeof(InquiryUnitSerialNumber->ProductSerialNumber);
-	    for (i = 0; i < SerialNumberLength; i++)
-	      {
-		unsigned char SerialNumberCharacter =
-		  InquiryUnitSerialNumber->ProductSerialNumber[i];
-		SerialNumber[i] =
-		  (SerialNumberCharacter >= ' ' && SerialNumberCharacter <= '~'
-		   ? SerialNumberCharacter : ' ');
-	      }
-	    SerialNumber[SerialNumberLength] = '\0';
-	    DAC960_Info("         Serial Number: %s\n",
-			Controller, SerialNumber);
-	  }
-	if (DeviceState->Present && DeviceState->DeviceType == DAC960_DiskType)
-	  {
-	    if (Controller->DeviceResetCount[Channel][TargetID] > 0)
+	    if (Controller->V1.DeviceResetCount[Channel][TargetID] > 0)
 	      DAC960_Info("         Disk Status: %s, %d blocks, %d resets\n",
 			  Controller,
-			  (DeviceState->DeviceState == DAC960_Device_Dead
+			  (DeviceState->DeviceState == DAC960_V1_Device_Dead
 			   ? "Dead"
-			   : DeviceState->DeviceState == DAC960_Device_WriteOnly
-			   ? "Write-Only"
-			   : DeviceState->DeviceState == DAC960_Device_Online
-			   ? "Online" : "Standby"),
+			   : DeviceState->DeviceState
+			     == DAC960_V1_Device_WriteOnly
+			     ? "Write-Only"
+			     : DeviceState->DeviceState
+			       == DAC960_V1_Device_Online
+			       ? "Online" : "Standby"),
 			  DeviceState->DiskSize,
-			  Controller->DeviceResetCount[Channel][TargetID]);
+			  Controller->V1.DeviceResetCount[Channel][TargetID]);
 	    else
 	      DAC960_Info("         Disk Status: %s, %d blocks\n", Controller,
-			  (DeviceState->DeviceState == DAC960_Device_Dead
+			  (DeviceState->DeviceState == DAC960_V1_Device_Dead
 			   ? "Dead"
-			   : DeviceState->DeviceState == DAC960_Device_WriteOnly
-			   ? "Write-Only"
-			   : DeviceState->DeviceState == DAC960_Device_Online
-			   ? "Online" : "Standby"),
+			   : DeviceState->DeviceState
+			     == DAC960_V1_Device_WriteOnly
+			     ? "Write-Only"
+			     : DeviceState->DeviceState
+			       == DAC960_V1_Device_Online
+			       ? "Online" : "Standby"),
 			  DeviceState->DiskSize);
 	  }
 	if (ErrorEntry->ParityErrorCount > 0 ||
@@ -1108,17 +1626,16 @@
        LogicalDriveNumber < Controller->LogicalDriveCount;
        LogicalDriveNumber++)
     {
-      DAC960_LogicalDriveInformation_T *LogicalDriveInformation =
-	&Controller->LogicalDriveInformation
-	   [Controller->LogicalDriveInformationIndex][LogicalDriveNumber];
+      DAC960_V1_LogicalDriveInformation_T *LogicalDriveInformation =
+	&Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
       DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %d blocks, %s\n",
 		  Controller, Controller->ControllerNumber, LogicalDriveNumber,
 		  LogicalDriveInformation->RAIDLevel,
-		  (LogicalDriveInformation->LogicalDriveState ==
-		     DAC960_LogicalDrive_Online
+		  (LogicalDriveInformation->LogicalDriveState
+		   == DAC960_V1_LogicalDrive_Online
 		   ? "Online"
-		   : LogicalDriveInformation->LogicalDriveState ==
-		     DAC960_LogicalDrive_Critical
+		   : LogicalDriveInformation->LogicalDriveState
+		     == DAC960_V1_LogicalDrive_Critical
 		     ? "Critical" : "Offline"),
 		  LogicalDriveInformation->LogicalDriveSize,
 		  (LogicalDriveInformation->WriteBack
@@ -1129,6 +1646,179 @@
 
 
 /*
+  DAC960_V2_ReportDeviceConfiguration reports the Device Configuration
+  Information for DAC960 V2 Firmware Controllers.
+*/
+
+static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
+						   *Controller)
+{
+  int PhysicalDeviceIndex, LogicalDriveNumber;
+  DAC960_Info("  Physical Devices:\n", Controller);
+  for (PhysicalDeviceIndex = 0;
+       PhysicalDeviceIndex < DAC960_V2_MaxPhysicalDevices;
+       PhysicalDeviceIndex++)
+    {
+      DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
+	Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
+      DAC960_SCSI_Inquiry_T *InquiryStandardData =
+	(DAC960_SCSI_Inquiry_T *) &PhysicalDeviceInfo->SCSI_InquiryData;
+      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
+	Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex];
+      char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)];
+      char Model[1+sizeof(InquiryStandardData->ProductIdentification)];
+      char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)];
+      char SerialNumber[1+sizeof(InquiryUnitSerialNumber->ProductSerialNumber)];
+      if (PhysicalDeviceInfo == NULL) break;
+      DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber,
+				 Vendor, Model, Revision, SerialNumber);
+      DAC960_Info("    %d:%d%s Vendor: %s  Model: %s  Revision: %s\n",
+		  Controller,
+		  PhysicalDeviceInfo->Channel,
+		  PhysicalDeviceInfo->TargetID,
+		  (PhysicalDeviceInfo->TargetID < 10 ? " " : ""),
+		  Vendor, Model, Revision);
+      if (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers == 0)
+	DAC960_Info("         %sAsynchronous\n", Controller,
+		    (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
+		     ? "Wide " :""));
+      else
+	DAC960_Info("         %sSynchronous at %d MB/sec\n", Controller,
+		    (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
+		     ? "Wide " :""),
+		    (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers
+		     * (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
+			? 2 : 1)));
+      if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
+	DAC960_Info("         Serial Number: %s\n", Controller, SerialNumber);
+      if (PhysicalDeviceInfo->PhysicalDeviceState ==
+	  DAC960_V2_Device_Unconfigured)
+	continue;
+      DAC960_Info("         Disk Status: %s, %d blocks\n", Controller,
+		  (PhysicalDeviceInfo->PhysicalDeviceState
+		   == DAC960_V2_Device_Online
+		   ? "Online"
+		   : PhysicalDeviceInfo->PhysicalDeviceState
+		     == DAC960_V2_Device_WriteOnly
+		     ? "Write-Only"
+		     : PhysicalDeviceInfo->PhysicalDeviceState
+		       == DAC960_V2_Device_Dead
+		       ? "Dead" : "Standby"),
+		  PhysicalDeviceInfo
+		  ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+      if (PhysicalDeviceInfo->ParityErrors == 0 &&
+	  PhysicalDeviceInfo->SoftErrors == 0 &&
+	  PhysicalDeviceInfo->HardErrors == 0 &&
+	  PhysicalDeviceInfo->MiscellaneousErrors == 0 &&
+	  PhysicalDeviceInfo->CommandTimeouts == 0 &&
+	  PhysicalDeviceInfo->Retries == 0 &&
+	  PhysicalDeviceInfo->Aborts == 0 &&
+	  PhysicalDeviceInfo->PredictedFailuresDetected == 0)
+	continue;
+      DAC960_Info("         Errors - Parity: %d, Soft: %d, "
+		  "Hard: %d, Misc: %d\n", Controller,
+		  PhysicalDeviceInfo->ParityErrors,
+		  PhysicalDeviceInfo->SoftErrors,
+		  PhysicalDeviceInfo->HardErrors,
+		  PhysicalDeviceInfo->MiscellaneousErrors);
+      DAC960_Info("                  Timeouts: %d, Retries: %d, "
+		  "Aborts: %d, Predicted: %d\n", Controller,
+		  PhysicalDeviceInfo->CommandTimeouts,
+		  PhysicalDeviceInfo->Retries,
+		  PhysicalDeviceInfo->Aborts,
+		  PhysicalDeviceInfo->PredictedFailuresDetected);
+    }
+  DAC960_Info("  Logical Drives:\n", Controller);
+  for (LogicalDriveNumber = 0;
+       LogicalDriveNumber < DAC960_MaxLogicalDrives;
+       LogicalDriveNumber++)
+    {
+      DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+	Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+      unsigned char *ReadCacheStatus[] = { "Read Cache Disabled",
+					   "Read Cache Enabled",
+					   "Read Ahead Enabled",
+					   "Intelligent Read Ahead Enabled",
+					   "-", "-", "-", "-" };
+      unsigned char *WriteCacheStatus[] = { "Write Cache Disabled",
+					    "Logical Device Read Only",
+					    "Write Cache Enabled",
+					    "Intelligent Write Cache Enabled",
+					    "-", "-", "-", "-" };
+      unsigned char *GeometryTranslation;
+      if (LogicalDeviceInfo == NULL) continue;
+      switch(LogicalDeviceInfo->DriveGeometry)
+	{
+	case DAC960_V2_Geometry_128_32:
+	  GeometryTranslation = "128/32";
+	  break;
+	case DAC960_V2_Geometry_255_63:
+	  GeometryTranslation = "255/63";
+	  break;
+	default:
+	  GeometryTranslation = "Invalid";
+	  DAC960_Error("Illegal Logical Device Geometry %d\n",
+		       Controller, LogicalDeviceInfo->DriveGeometry);
+	  break;
+	}
+      DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %d blocks\n",
+		  Controller, Controller->ControllerNumber, LogicalDriveNumber,
+		  LogicalDeviceInfo->RAIDLevel,
+		  (LogicalDeviceInfo->LogicalDeviceState
+		   == DAC960_V2_LogicalDevice_Online
+		   ? "Online"
+		   : LogicalDeviceInfo->LogicalDeviceState
+		     == DAC960_V2_LogicalDevice_Critical
+		     ? "Critical" : "Offline"),
+		  LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+      DAC960_Info("                  Logical Device %s, BIOS Geometry: %s\n",
+		  Controller,
+		  (LogicalDeviceInfo->LogicalDeviceControl
+				     .LogicalDeviceInitialized
+		   ? "Initialized" : "Uninitialized"),
+		  GeometryTranslation);
+      if (LogicalDeviceInfo->StripeSize == 0)
+	{
+	  if (LogicalDeviceInfo->CacheLineSize == 0)
+	    DAC960_Info("                  Stripe Size: N/A, "
+			"Segment Size: N/A\n", Controller);
+	  else
+	    DAC960_Info("                  Stripe Size: N/A, "
+			"Segment Size: %dKB\n", Controller,
+			1 << (LogicalDeviceInfo->CacheLineSize - 2));
+	}
+      else
+	{
+	  if (LogicalDeviceInfo->CacheLineSize == 0)
+	    DAC960_Info("                  Stripe Size: %dKB, "
+			"Segment Size: N/A\n", Controller,
+			1 << (LogicalDeviceInfo->StripeSize - 2));
+	  else
+	    DAC960_Info("                  Stripe Size: %dKB, "
+			"Segment Size: %dKB\n", Controller,
+			1 << (LogicalDeviceInfo->StripeSize - 2),
+			1 << (LogicalDeviceInfo->CacheLineSize - 2));
+	}
+      DAC960_Info("                  %s, %s\n", Controller,
+		  ReadCacheStatus[
+		    LogicalDeviceInfo->LogicalDeviceControl.ReadCache],
+		  WriteCacheStatus[
+		    LogicalDeviceInfo->LogicalDeviceControl.WriteCache]);
+      if (LogicalDeviceInfo->SoftErrors > 0 ||
+	  LogicalDeviceInfo->CommandsFailed > 0 ||
+	  LogicalDeviceInfo->DeferredWriteErrors)
+	DAC960_Info("                  Errors - Soft: %d, Failed: %d, "
+		    "Deferred Write: %d\n", Controller,
+		    LogicalDeviceInfo->SoftErrors,
+		    LogicalDeviceInfo->CommandsFailed,
+		    LogicalDeviceInfo->DeferredWriteErrors);
+
+    }
+  return true;
+}
+
+
+/*
   DAC960_RegisterBlockDevice registers the Block Device structures
   associated with Controller.
 */
@@ -1167,7 +1857,7 @@
       Controller->MaxSectorsPerRequest[MinorNumber] =
 	Controller->MaxBlocksPerCommand;
       Controller->MaxSegmentsPerRequest[MinorNumber] =
-	Controller->MaxScatterGatherSegments;
+	Controller->DriverScatterGatherLimit;
     }
   Controller->GenericDiskInfo.part = Controller->DiskPartitions;
   Controller->GenericDiskInfo.sizes = Controller->PartitionSizes;
@@ -1250,37 +1940,485 @@
 
 
 /*
-  DAC960_InitializeController initializes Controller.
+  DAC960_GenericDiskInit is the Generic Disk Information Initialization
+  Function for the DAC960 Driver.
 */
 
-static void DAC960_InitializeController(DAC960_Controller_T *Controller)
+static void DAC960_InitializeGenericDiskInfo(GenericDiskInfo_T *GenericDiskInfo)
 {
-  if (DAC960_ReadControllerConfiguration(Controller) &&
-      DAC960_ReportControllerConfiguration(Controller) &&
-      DAC960_ReadDeviceConfiguration(Controller) &&
-      DAC960_ReportDeviceConfiguration(Controller) &&
-      DAC960_RegisterBlockDevice(Controller))
-    {
-      /*
-	Initialize the Command structures.
-      */
-      DAC960_Command_T *Commands = Controller->Commands;
-      int CommandIdentifier;
-      Controller->FreeCommands = NULL;
-      for (CommandIdentifier = 0;
-	   CommandIdentifier < Controller->DriverQueueDepth;
-	   CommandIdentifier++)
-	{
-	  Commands[CommandIdentifier].Controller = Controller;
-	  Commands[CommandIdentifier].Next = Controller->FreeCommands;
-	  Controller->FreeCommands = &Commands[CommandIdentifier];
-	}
-      /*
-	Initialize the Monitoring Timer.
-      */
-      init_timer(&Controller->MonitoringTimer);
-      Controller->MonitoringTimer.expires =
-	jiffies + DAC960_MonitoringTimerInterval;
+  DAC960_Controller_T *Controller =
+    (DAC960_Controller_T *) GenericDiskInfo->real_devices;
+  int LogicalDriveNumber;
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+    for (LogicalDriveNumber = 0;
+	 LogicalDriveNumber < Controller->LogicalDriveCount;
+	 LogicalDriveNumber++)
+      GenericDiskInfo->part[DAC960_MinorNumber(LogicalDriveNumber, 0)]
+		      .nr_sects =
+	Controller->V1.LogicalDriveInformation
+		       [LogicalDriveNumber].LogicalDriveSize;
+  else
+    for (LogicalDriveNumber = 0;
+	 LogicalDriveNumber < DAC960_MaxLogicalDrives;
+	 LogicalDriveNumber++)
+      {
+	DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+	  Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+	if (LogicalDeviceInfo != NULL)
+	  GenericDiskInfo->part[DAC960_MinorNumber(LogicalDriveNumber, 0)]
+			  .nr_sects =
+	    LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB;
+      }
+}
+
+
+/*
+  DAC960_ReportErrorStatus reports Controller BIOS Messages passed through
+  the Error Status Register when the driver performs the BIOS handshaking.
+  It returns true for fatal errors and false otherwise.
+*/
+
+static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
+					unsigned char ErrorStatus,
+					unsigned char Parameter0,
+					unsigned char Parameter1)
+{
+  switch (ErrorStatus)
+    {
+    case 0x00:
+      DAC960_Notice("Physical Device %d:%d Not Responding\n",
+		    Controller, Parameter1, Parameter0);
+      break;
+    case 0x08:
+      if (Controller->DriveSpinUpMessageDisplayed) break;
+      DAC960_Notice("Spinning Up Drives\n", Controller);
+      Controller->DriveSpinUpMessageDisplayed = true;
+      break;
+    case 0x30:
+      DAC960_Notice("Configuration Checksum Error\n", Controller);
+      break;
+    case 0x60:
+      DAC960_Notice("Mirror Race Recovery Failed\n", Controller);
+      break;
+    case 0x70:
+      DAC960_Notice("Mirror Race Recovery In Progress\n", Controller);
+      break;
+    case 0x90:
+      DAC960_Notice("Physical Device %d:%d COD Mismatch\n",
+		    Controller, Parameter1, Parameter0);
+      break;
+    case 0xA0:
+      DAC960_Notice("Logical Drive Installation Aborted\n", Controller);
+      break;
+    case 0xB0:
+      DAC960_Notice("Mirror Race On A Critical Logical Drive\n", Controller);
+      break;
+    case 0xD0:
+      DAC960_Notice("New Controller Configuration Found\n", Controller);
+      break;
+    case 0xF0:
+      DAC960_Error("Fatal Memory Parity Error for Controller at\n", Controller);
+      return true;
+    default:
+      DAC960_Error("Unknown Initialization Error %02X for Controller at\n",
+		   Controller, ErrorStatus);
+      return true;
+    }
+  return false;
+}
+
+
+/*
+  DAC960_DetectControllers detects Mylex DAC960/AcceleRAID/eXtremeRAID
+  PCI RAID Controllers by interrogating the PCI Configuration Space for
+  Controller Type.
+*/
+
+static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
+{
+  void (*InterruptHandler)(int, void *, Registers_T *) = NULL;
+  DAC960_FirmwareType_T FirmwareType = 0;
+  unsigned short VendorID = 0, DeviceID = 0;
+  unsigned int MemoryWindowSize = 0;
+  PCI_Device_T *PCI_Device = NULL;
+  switch (HardwareType)
+    {
+    case DAC960_BA_Controller:
+      VendorID = PCI_VENDOR_ID_MYLEX;
+      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_BA;
+      FirmwareType = DAC960_V2_Controller;
+      InterruptHandler = DAC960_BA_InterruptHandler;
+      MemoryWindowSize = DAC960_BA_RegisterWindowSize;
+      break;
+    case DAC960_LP_Controller:
+      VendorID = PCI_VENDOR_ID_MYLEX;
+      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_LP;
+      FirmwareType = DAC960_LP_Controller;
+      InterruptHandler = DAC960_LP_InterruptHandler;
+      MemoryWindowSize = DAC960_LP_RegisterWindowSize;
+      break;
+    case DAC960_LA_Controller:
+      VendorID = PCI_VENDOR_ID_DEC;
+      DeviceID = PCI_DEVICE_ID_DEC_21285;
+      FirmwareType = DAC960_V1_Controller;
+      InterruptHandler = DAC960_LA_InterruptHandler;
+      MemoryWindowSize = DAC960_LA_RegisterWindowSize;
+      break;
+    case DAC960_PG_Controller:
+      VendorID = PCI_VENDOR_ID_MYLEX;
+      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PG;
+      FirmwareType = DAC960_V1_Controller;
+      InterruptHandler = DAC960_PG_InterruptHandler;
+      MemoryWindowSize = DAC960_PG_RegisterWindowSize;
+      break;
+    case DAC960_PD_Controller:
+      VendorID = PCI_VENDOR_ID_MYLEX;
+      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PD;
+      FirmwareType = DAC960_V1_Controller;
+      InterruptHandler = DAC960_PD_InterruptHandler;
+      MemoryWindowSize = DAC960_PD_RegisterWindowSize;
+      break;
+    }
+  while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
+    {
+      DAC960_Controller_T *Controller = NULL;
+      DAC960_IO_Address_T IO_Address = 0;
+      DAC960_PCI_Address_T PCI_Address = 0;
+      unsigned char Bus = PCI_Device->bus->number;
+      unsigned char DeviceFunction = PCI_Device->devfn;
+      unsigned char Device = DeviceFunction >> 3;
+      unsigned char Function = DeviceFunction & 0x7;
+      unsigned char ErrorStatus, Parameter0, Parameter1;
+      unsigned int IRQ_Channel = PCI_Device->irq;
+      unsigned long BaseAddress0 = PCI_Device->base_address[0];
+      unsigned long BaseAddress1 = PCI_Device->base_address[1];
+      unsigned short SubsystemVendorID, SubsystemDeviceID;
+      void *BaseAddress;
+      pci_read_config_word(PCI_Device, PCI_SUBSYSTEM_VENDOR_ID,
+			   &SubsystemVendorID);
+      pci_read_config_word(PCI_Device, PCI_SUBSYSTEM_ID,
+			   &SubsystemDeviceID);
+      switch (HardwareType)
+	{
+	case DAC960_BA_Controller:
+	  PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
+	  break;
+	case DAC960_LP_Controller:
+	  PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
+	  break;
+	case DAC960_LA_Controller:
+	  if (!(SubsystemVendorID == PCI_VENDOR_ID_MYLEX &&
+		SubsystemDeviceID == PCI_DEVICE_ID_MYLEX_DAC960_LA))
+	    continue;
+	  PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
+	  break;
+	case DAC960_PG_Controller:
+	  PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
+	  break;
+	case DAC960_PD_Controller:
+	  IO_Address = BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
+	  PCI_Address = BaseAddress1 & PCI_BASE_ADDRESS_MEM_MASK;
+	  break;
+	}
+      if (DAC960_ControllerCount == DAC960_MaxControllers)
+	{
+	  DAC960_Error("More than %d DAC960 Controllers detected - "
+		       "ignoring from Controller at\n",
+		       NULL, DAC960_MaxControllers);
+	  goto Failure;
+	}
+      Controller = (DAC960_Controller_T *)
+	kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
+      if (Controller == NULL)
+	{
+	  DAC960_Error("Unable to allocate Controller structure for "
+		       "Controller at\n", NULL);
+	  goto Failure;
+	}
+      memset(Controller, 0, sizeof(DAC960_Controller_T));
+      Controller->ControllerNumber = DAC960_ControllerCount;
+      DAC960_Controllers[DAC960_ControllerCount++] = Controller;
+      DAC960_AnnounceDriver(Controller);
+      Controller->FirmwareType = FirmwareType;
+      Controller->HardwareType = HardwareType;
+      Controller->IO_Address = IO_Address;
+      Controller->PCI_Address = PCI_Address;
+      Controller->Bus = Bus;
+      Controller->Device = Device;
+      Controller->Function = Function;
+      sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
+      /*
+	Map the Controller Register Window.
+      */
+      if (MemoryWindowSize < PAGE_SIZE)
+	MemoryWindowSize = PAGE_SIZE;
+      Controller->MemoryMappedAddress =
+	ioremap_nocache(PCI_Address & PAGE_MASK, MemoryWindowSize);
+      Controller->BaseAddress =
+	Controller->MemoryMappedAddress + (PCI_Address & ~PAGE_MASK);
+      if (Controller->MemoryMappedAddress == NULL)
+	{
+	  DAC960_Error("Unable to map Controller Register Window for "
+		       "Controller at\n", Controller);
+	  goto Failure;
+	}
+      BaseAddress = Controller->BaseAddress;
+      switch (HardwareType)
+	{
+	case DAC960_BA_Controller:
+	  DAC960_BA_DisableInterrupts(Controller->BaseAddress);
+	  DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress);
+	  udelay(1000);
+	  while (DAC960_BA_InitializationInProgressP(BaseAddress))
+	    {
+	      if (DAC960_BA_ReadErrorStatus(BaseAddress, &ErrorStatus,
+					    &Parameter0, &Parameter1) &&
+		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
+					   Parameter0, Parameter1))
+		goto Failure;
+	      udelay(10);
+	    }
+	  if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
+	    {
+	      DAC960_Error("Unable to Enable Memory Mailbox Interface "
+			   "for Controller at\n", Controller);
+	      goto Failure;
+	    }
+	  DAC960_BA_EnableInterrupts(Controller->BaseAddress);
+	  Controller->QueueCommand = DAC960_BA_QueueCommand;
+	  Controller->ReadControllerConfiguration =
+	    DAC960_V2_ReadControllerConfiguration;
+	  Controller->ReadDeviceConfiguration =
+	    DAC960_V2_ReadDeviceConfiguration;
+	  Controller->ReportDeviceConfiguration =
+	    DAC960_V2_ReportDeviceConfiguration;
+	  Controller->QueueReadWriteCommand =
+	    DAC960_V2_QueueReadWriteCommand;
+	  break;
+	case DAC960_LP_Controller:
+	  DAC960_LP_DisableInterrupts(Controller->BaseAddress);
+	  DAC960_LP_AcknowledgeHardwareMailboxStatus(BaseAddress);
+	  udelay(1000);
+	  while (DAC960_LP_InitializationInProgressP(BaseAddress))
+	    {
+	      if (DAC960_LP_ReadErrorStatus(BaseAddress, &ErrorStatus,
+					    &Parameter0, &Parameter1) &&
+		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
+					   Parameter0, Parameter1))
+		goto Failure;
+	      udelay(10);
+	    }
+	  if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
+	    {
+	      DAC960_Error("Unable to Enable Memory Mailbox Interface "
+			   "for Controller at\n", Controller);
+	      goto Failure;
+	    }
+	  DAC960_LP_EnableInterrupts(Controller->BaseAddress);
+	  Controller->QueueCommand = DAC960_LP_QueueCommand;
+	  Controller->ReadControllerConfiguration =
+	    DAC960_V2_ReadControllerConfiguration;
+	  Controller->ReadDeviceConfiguration =
+	    DAC960_V2_ReadDeviceConfiguration;
+	  Controller->ReportDeviceConfiguration =
+	    DAC960_V2_ReportDeviceConfiguration;
+	  Controller->QueueReadWriteCommand =
+	    DAC960_V2_QueueReadWriteCommand;
+	  break;
+	case DAC960_LA_Controller:
+	  DAC960_LA_DisableInterrupts(Controller->BaseAddress);
+	  DAC960_LA_AcknowledgeHardwareMailboxStatus(BaseAddress);
+	  udelay(1000);
+	  while (DAC960_LA_InitializationInProgressP(BaseAddress))
+	    {
+	      if (DAC960_LA_ReadErrorStatus(BaseAddress, &ErrorStatus,
+					    &Parameter0, &Parameter1) &&
+		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
+					   Parameter0, Parameter1))
+		goto Failure;
+	      udelay(10);
+	    }
+	  if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
+	    {
+	      DAC960_Error("Unable to Enable Memory Mailbox Interface "
+			   "for Controller at\n", Controller);
+	      goto Failure;
+	    }
+	  DAC960_LA_EnableInterrupts(Controller->BaseAddress);
+	  if (Controller->V1.DualModeMemoryMailboxInterface)
+	    Controller->QueueCommand = DAC960_LA_QueueCommandDualMode;
+	  else Controller->QueueCommand = DAC960_LA_QueueCommandSingleMode;
+	  Controller->ReadControllerConfiguration =
+	    DAC960_V1_ReadControllerConfiguration;
+	  Controller->ReadDeviceConfiguration =
+	    DAC960_V1_ReadDeviceConfiguration;
+	  Controller->ReportDeviceConfiguration =
+	    DAC960_V1_ReportDeviceConfiguration;
+	  Controller->QueueReadWriteCommand =
+	    DAC960_V1_QueueReadWriteCommand;
+	  break;
+	case DAC960_PG_Controller:
+	  DAC960_PG_DisableInterrupts(Controller->BaseAddress);
+	  DAC960_PG_AcknowledgeHardwareMailboxStatus(BaseAddress);
+	  udelay(1000);
+	  while (DAC960_PG_InitializationInProgressP(BaseAddress))
+	    {
+	      if (DAC960_PG_ReadErrorStatus(BaseAddress, &ErrorStatus,
+					    &Parameter0, &Parameter1) &&
+		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
+					   Parameter0, Parameter1))
+		goto Failure;
+	      udelay(10);
+	    }
+	  if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
+	    {
+	      DAC960_Error("Unable to Enable Memory Mailbox Interface "
+			   "for Controller at\n", Controller);
+	      goto Failure;
+	    }
+	  DAC960_PG_EnableInterrupts(Controller->BaseAddress);
+	  if (Controller->V1.DualModeMemoryMailboxInterface)
+	    Controller->QueueCommand = DAC960_PG_QueueCommandDualMode;
+	  else Controller->QueueCommand = DAC960_PG_QueueCommandSingleMode;
+	  Controller->ReadControllerConfiguration =
+	    DAC960_V1_ReadControllerConfiguration;
+	  Controller->ReadDeviceConfiguration =
+	    DAC960_V1_ReadDeviceConfiguration;
+	  Controller->ReportDeviceConfiguration =
+	    DAC960_V1_ReportDeviceConfiguration;
+	  Controller->QueueReadWriteCommand =
+	    DAC960_V1_QueueReadWriteCommand;
+	  break;
+	case DAC960_PD_Controller:
+	  request_region(Controller->IO_Address, 0x80,
+			 Controller->FullModelName);
+	  DAC960_PD_DisableInterrupts(BaseAddress);
+	  DAC960_PD_AcknowledgeStatus(BaseAddress);
+	  udelay(1000);
+	  while (DAC960_PD_InitializationInProgressP(BaseAddress))
+	    {
+	      if (DAC960_PD_ReadErrorStatus(BaseAddress, &ErrorStatus,
+					    &Parameter0, &Parameter1) &&
+		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
+					   Parameter0, Parameter1))
+		goto Failure;
+	      udelay(10);
+	    }
+	  DAC960_PD_EnableInterrupts(Controller->BaseAddress);
+	  Controller->QueueCommand = DAC960_PD_QueueCommand;
+	  Controller->ReadControllerConfiguration =
+	    DAC960_V1_ReadControllerConfiguration;
+	  Controller->ReadDeviceConfiguration =
+	    DAC960_V1_ReadDeviceConfiguration;
+	  Controller->ReportDeviceConfiguration =
+	    DAC960_V1_ReportDeviceConfiguration;
+	  Controller->QueueReadWriteCommand =
+	    DAC960_V1_QueueReadWriteCommand;
+	  break;
+	}
+      /*
+	Acquire shared access to the IRQ Channel.
+      */
+      if (IRQ_Channel == 0)
+	{
+	  DAC960_Error("IRQ Channel %d illegal for Controller at\n",
+		       Controller, IRQ_Channel);
+	  goto Failure;
+	}
+      strcpy(Controller->FullModelName, "DAC960");
+      if (request_irq(IRQ_Channel, InterruptHandler, SA_SHIRQ,
+		      Controller->FullModelName, Controller) < 0)
+	{
+	  DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
+		       Controller, IRQ_Channel);
+	  goto Failure;
+	}
+      Controller->IRQ_Channel = IRQ_Channel;
+      DAC960_ActiveControllerCount++;
+      Controller->InitialCommand.CommandIdentifier = 1;
+      Controller->InitialCommand.Controller = Controller;
+      Controller->Commands[0] = &Controller->InitialCommand;
+      Controller->FreeCommands = &Controller->InitialCommand;
+      Controller->ControllerDetectionSuccessful = true;
+      continue;
+    Failure:
+      if (IO_Address == 0)
+	DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
+		     "PCI Address 0x%X\n", Controller,
+		     Bus, Device, Function, PCI_Address);
+      else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
+			"0x%X PCI Address 0x%X\n", Controller,
+			Bus, Device, Function, IO_Address, PCI_Address);
+      if (Controller == NULL) break;
+      if (Controller->MemoryMappedAddress != NULL)
+	iounmap(Controller->MemoryMappedAddress);
+      if (Controller->IRQ_Channel > 0)
+	free_irq(IRQ_Channel, Controller);
+    }
+}
+
+
+/*
+  DAC960_SortControllers sorts the Controllers by PCI Bus and Device Number.
+*/
+
+static void DAC960_SortControllers(void)
+{
+  int ControllerNumber, LastInterchange, Bound, j;
+  LastInterchange = DAC960_ControllerCount-1;
+  while (LastInterchange > 0)
+    {
+      Bound = LastInterchange;
+      LastInterchange = 0;
+      for (j = 0; j < Bound; j++)
+	{
+	  DAC960_Controller_T *Controller1 = DAC960_Controllers[j];
+	  DAC960_Controller_T *Controller2 = DAC960_Controllers[j+1];
+	  if (Controller1->Bus > Controller2->Bus ||
+	      (Controller1->Bus == Controller2->Bus &&
+	       (Controller1->Device > Controller2->Device)))
+	    {
+	      Controller2->ControllerNumber = j;
+	      DAC960_Controllers[j] = Controller2;
+	      Controller1->ControllerNumber = j+1;
+	      DAC960_Controllers[j+1] = Controller1;
+	      LastInterchange = j;
+	    }
+	}
+    }
+  for (ControllerNumber = 0;
+       ControllerNumber < DAC960_ControllerCount;
+       ControllerNumber++)
+    {
+      DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
+      if (!Controller->ControllerDetectionSuccessful)
+	{
+	  DAC960_Controllers[ControllerNumber] = NULL;
+	  kfree(Controller);
+	}
+    }
+}
+
+
+/*
+  DAC960_InitializeController initializes Controller.
+*/
+
+static void DAC960_InitializeController(DAC960_Controller_T *Controller)
+{
+  if (DAC960_ReadControllerConfiguration(Controller) &&
+      DAC960_ReportControllerConfiguration(Controller) &&
+      DAC960_CreateAuxiliaryStructures(Controller) &&
+      DAC960_ReadDeviceConfiguration(Controller) &&
+      DAC960_ReportDeviceConfiguration(Controller) &&
+      DAC960_RegisterBlockDevice(Controller))
+    {
+      /*
+	Initialize the Monitoring Timer.
+      */
+      init_timer(&Controller->MonitoringTimer);
+      Controller->MonitoringTimer.expires =
+	jiffies + DAC960_MonitoringTimerInterval;
       Controller->MonitoringTimer.data = (unsigned long) Controller;
       Controller->MonitoringTimer.function = DAC960_MonitoringTimerFunction;
       add_timer(&Controller->MonitoringTimer);
@@ -1299,28 +2437,46 @@
   if (Controller->ControllerInitialized)
     {
       del_timer(&Controller->MonitoringTimer);
-      DAC960_Notice("Flushing Cache...", Controller);
-      DAC960_ExecuteType3(Controller, DAC960_Flush, NULL);
-      DAC960_Notice("done\n", Controller);
-      switch (Controller->ControllerType)
-	{
-	case DAC960_V5_Controller:
-	  if (!Controller->DualModeMemoryMailboxInterface)
-	    DAC960_V5_SaveMemoryMailboxInfo(Controller);
-	  break;
-	case DAC960_V4_Controller:
-	  if (!Controller->DualModeMemoryMailboxInterface)
-	    DAC960_V4_SaveMemoryMailboxInfo(Controller);
-	  break;
-	case DAC960_V3_Controller:
-	  break;
+      if (Controller->FirmwareType == DAC960_V1_Controller)
+	{
+	  DAC960_Notice("Flushing Cache...", Controller);
+	  DAC960_V1_ExecuteType3(Controller, DAC960_V1_Flush, NULL);
+	  DAC960_Notice("done\n", Controller);
+	  switch (Controller->HardwareType)
+	    {
+	    case DAC960_LA_Controller:
+	      if (Controller->V1.DualModeMemoryMailboxInterface)
+		free_pages(Controller->MemoryMailboxPagesAddress,
+			   Controller->MemoryMailboxPagesOrder);
+	      else DAC960_LA_SaveMemoryMailboxInfo(Controller);
+	      break;
+	    case DAC960_PG_Controller:
+	      if (Controller->V1.DualModeMemoryMailboxInterface)
+		free_pages(Controller->MemoryMailboxPagesAddress,
+			   Controller->MemoryMailboxPagesOrder);
+	      else DAC960_PG_SaveMemoryMailboxInfo(Controller);
+	      break;
+	    case DAC960_PD_Controller:
+	      release_region(Controller->IO_Address, 0x80);
+	      break;
+	    default:
+	      break;
+	    }
+	}
+      else
+	{
+	  DAC960_Notice("Flushing Cache...", Controller);
+	  DAC960_V2_DeviceOperation(Controller, DAC960_V2_PauseDevice,
+				    DAC960_V2_RAID_Controller);
+	  DAC960_Notice("done\n", Controller);
+	  free_pages(Controller->MemoryMailboxPagesAddress,
+		     Controller->MemoryMailboxPagesOrder);
 	}
     }
   free_irq(Controller->IRQ_Channel, Controller);
   iounmap(Controller->MemoryMappedAddress);
-  if (Controller->IO_Address > 0)
-    release_region(Controller->IO_Address, 0x80);
   DAC960_UnregisterBlockDevice(Controller);
+  DAC960_DestroyAuxiliaryStructures(Controller);
   DAC960_Controllers[Controller->ControllerNumber] = NULL;
   kfree(Controller);
 }
@@ -1333,9 +2489,12 @@
 void DAC960_Initialize(void)
 {
   int ControllerNumber;
-  DAC960_DetectControllers(DAC960_V5_Controller);
-  DAC960_DetectControllers(DAC960_V4_Controller);
-  DAC960_DetectControllers(DAC960_V3_Controller);
+  DAC960_DetectControllers(DAC960_BA_Controller);
+  DAC960_DetectControllers(DAC960_LP_Controller);
+  DAC960_DetectControllers(DAC960_LA_Controller);
+  DAC960_DetectControllers(DAC960_PG_Controller);
+  DAC960_DetectControllers(DAC960_PD_Controller);
+  DAC960_SortControllers();
   if (DAC960_ActiveControllerCount == 0) return;
   for (ControllerNumber = 0;
        ControllerNumber < DAC960_ControllerCount;
@@ -1371,68 +2530,38 @@
 
 
 /*
-  DAC960_ProcessRequest attempts to remove one I/O Request from Controller's
-  I/O Request Queue and queues it to the Controller.  WaitForCommand is true if
-  this function should wait for a Command to become available if necessary.
-  This function returns true if an I/O Request was queued and false otherwise.
+  DAC960_V1_QueueReadWriteCommand prepares and queues a Read/Write Command for
+  DAC960 V1 Firmware Controllers.
 */
 
-static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
-				     boolean WaitForCommand)
+static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command)
 {
-  IO_Request_T **RequestQueuePointer =
-    &blk_dev[DAC960_MAJOR + Controller->ControllerNumber].current_request;
-  IO_Request_T *Request;
-  DAC960_Command_T *Command;
-  char *RequestBuffer;
-  while (true)
-    {
-      Request = *RequestQueuePointer;
-      if (Request == NULL || Request->rq_status == RQ_INACTIVE) return false;
-      Command = DAC960_AllocateCommand(Controller);
-      if (Command != NULL) break;
-      if (!WaitForCommand) return false;
-      DAC960_WaitForCommand(Controller);
-    }
-  DAC960_ClearCommand(Command);
-  if (Request->cmd == READ)
-    Command->CommandType = DAC960_ReadCommand;
-  else Command->CommandType = DAC960_WriteCommand;
-  Command->Semaphore = Request->sem;
-  Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev);
-  Command->BlockNumber =
-    Request->sector
-    + Controller->GenericDiskInfo.part[MINOR(Request->rq_dev)].start_sect;
-  Command->BlockCount = Request->nr_sectors;
-  Command->SegmentCount = Request->nr_segments;
-  Command->BufferHeader = Request->bh;
-  RequestBuffer = Request->buffer;
-  Request->rq_status = RQ_INACTIVE;
-  *RequestQueuePointer = Request->next;
-  wake_up(&wait_for_request);
+  DAC960_Controller_T *Controller = Command->Controller;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_ClearCommand(Command);
   if (Command->SegmentCount == 1)
     {
-      DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
       if (Command->CommandType == DAC960_ReadCommand)
-	CommandMailbox->Type5.CommandOpcode = DAC960_Read;
-      else CommandMailbox->Type5.CommandOpcode = DAC960_Write;
+	CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
+      else CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
       CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
       CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
       CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
-      CommandMailbox->Type5.BusAddress = Virtual_to_Bus(RequestBuffer);
+      CommandMailbox->Type5.BusAddress = Virtual_to_Bus(Command->RequestBuffer);
     }
   else
     {
-      DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-      DAC960_ScatterGatherSegment_T
-	*ScatterGatherList = Command->ScatterGatherList;
+      DAC960_V1_ScatterGatherSegment_T
+	*ScatterGatherList = Command->V1.ScatterGatherList;
       BufferHeader_T *BufferHeader = Command->BufferHeader;
       char *LastDataEndPointer = NULL;
       int SegmentNumber = 0;
       if (Command->CommandType == DAC960_ReadCommand)
-	CommandMailbox->Type5.CommandOpcode = DAC960_ReadWithOldScatterGather;
+	CommandMailbox->Type5.CommandOpcode =
+	  DAC960_V1_ReadWithOldScatterGather;
       else
-	CommandMailbox->Type5.CommandOpcode = DAC960_WriteWithOldScatterGather;
+	CommandMailbox->Type5.CommandOpcode =
+	  DAC960_V1_WriteWithOldScatterGather;
       CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
       CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
       CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
@@ -1453,7 +2582,97 @@
 	      ScatterGatherList[SegmentNumber].SegmentByteCount =
 		BufferHeader->b_size;
 	      LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
-	      if (SegmentNumber++ > Controller->MaxScatterGatherSegments)
+	      if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
+		panic("DAC960: Scatter/Gather Segment Overflow\n");
+	    }
+	  BufferHeader = BufferHeader->b_reqnext;
+	}
+      if (SegmentNumber != Command->SegmentCount)
+	panic("DAC960: SegmentNumber != SegmentCount\n");
+    }
+  DAC960_QueueCommand(Command);
+}
+
+
+/*
+  DAC960_V2_QueueReadWriteCommand prepares and queues a Read/Write Command for
+  DAC960 V2 Firmware Controllers.
+*/
+
+static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_ClearCommand(Command);
+  CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10;
+  CommandMailbox->SCSI_10.CommandControlBits.DataTransferControllerToHost =
+    (Command->CommandType == DAC960_ReadCommand);
+  CommandMailbox->SCSI_10.DataTransferSize =
+    Command->BlockCount << DAC960_BlockSizeBits;
+  CommandMailbox->SCSI_10.RequestSenseBusAddress =
+    Virtual_to_Bus(&Command->V2.RequestSense);
+  CommandMailbox->SCSI_10.PhysicalDevice =
+    Controller->V2.LogicalDriveToVirtualDevice[Command->LogicalDriveNumber];
+  CommandMailbox->SCSI_10.RequestSenseSize =
+    sizeof(DAC960_SCSI_RequestSense_T);
+  CommandMailbox->SCSI_10.CDBLength = 10;
+  CommandMailbox->SCSI_10.SCSI_CDB[0] =
+    (Command->CommandType == DAC960_ReadCommand ? 0x28 : 0x2A);
+  CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
+  CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
+  CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
+  CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
+  CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
+  CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
+  if (Command->SegmentCount == 1)
+    {
+      CommandMailbox->SCSI_10.DataTransferMemoryAddress
+			     .ScatterGatherSegments[0]
+			     .SegmentDataPointer =
+	Virtual_to_Bus(Command->RequestBuffer);
+      CommandMailbox->SCSI_10.DataTransferMemoryAddress
+			     .ScatterGatherSegments[0]
+			     .SegmentByteCount =
+	CommandMailbox->SCSI_10.DataTransferSize;
+    }
+  else
+    {
+      DAC960_V2_ScatterGatherSegment_T
+	*ScatterGatherList = Command->V2.ScatterGatherList;
+      BufferHeader_T *BufferHeader = Command->BufferHeader;
+      char *LastDataEndPointer = NULL;
+      int SegmentNumber = 0;
+      if (Command->SegmentCount > 2)
+	{
+	  CommandMailbox->SCSI_10.CommandControlBits
+			 .AdditionalScatterGatherListMemory = true;
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+			 .ExtendedScatterGather.ScatterGatherList0Length =
+	    Command->SegmentCount;
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+			 .ExtendedScatterGather.ScatterGatherList0Address =
+	    Virtual_to_Bus(ScatterGatherList);
+	}
+      else
+	ScatterGatherList =
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				 .ScatterGatherSegments;
+      while (BufferHeader != NULL)
+	{
+	  if (BufferHeader->b_data == LastDataEndPointer)
+	    {
+	      ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
+		BufferHeader->b_size;
+	      LastDataEndPointer += BufferHeader->b_size;
+	    }
+	  else
+	    {
+	      ScatterGatherList[SegmentNumber].SegmentDataPointer =
+		Virtual_to_Bus(BufferHeader->b_data);
+	      ScatterGatherList[SegmentNumber].SegmentByteCount =
+		BufferHeader->b_size;
+	      LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
+	      if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
 		panic("DAC960: Scatter/Gather Segment Overflow\n");
 	    }
 	  BufferHeader = BufferHeader->b_reqnext;
@@ -1462,6 +2681,48 @@
 	panic("DAC960: SegmentNumber != SegmentCount\n");
     }
   DAC960_QueueCommand(Command);
+}
+
+
+/*
+  DAC960_ProcessRequest attempts to remove one I/O Request from Controller's
+  I/O Request Queue and queues it to the Controller.  WaitForCommand is true if
+  this function should wait for a Command to become available if necessary.
+  This function returns true if an I/O Request was queued and false otherwise.
+*/
+
+static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
+				     boolean WaitForCommand)
+{
+  IO_Request_T **RequestQueuePointer =
+    &blk_dev[DAC960_MAJOR + Controller->ControllerNumber].current_request;
+  IO_Request_T *Request;
+  DAC960_Command_T *Command;
+  while (true)
+    {
+      Request = *RequestQueuePointer;
+      if (Request == NULL || Request->rq_status == RQ_INACTIVE) return false;
+      Command = DAC960_AllocateCommand(Controller);
+      if (Command != NULL) break;
+      if (!WaitForCommand) return false;
+      DAC960_WaitForCommand(Controller);
+    }
+  if (Request->cmd == READ)
+    Command->CommandType = DAC960_ReadCommand;
+  else Command->CommandType = DAC960_WriteCommand;
+  Command->Semaphore = Request->sem;
+  Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev);
+  Command->BlockNumber =
+    Request->sector
+    + Controller->GenericDiskInfo.part[MINOR(Request->rq_dev)].start_sect;
+  Command->BlockCount = Request->nr_sectors;
+  Command->SegmentCount = Request->nr_segments;
+  Command->BufferHeader = Request->bh;
+  Command->RequestBuffer = Request->buffer;
+  Request->rq_status = RQ_INACTIVE;
+  *RequestQueuePointer = Request->next;
+  DAC960_QueueReadWriteCommand(Command);
+  wake_up(&wait_for_request);
   return true;
 }
 
@@ -1663,14 +2924,26 @@
 
 
 /*
-  DAC960_ReadWriteError prints an appropriate error message for Command when
-  an error occurs on a Read or Write operation.
+  DAC960_ProcessCompletedBuffer performs completion processing for an
+  individual Buffer.
+*/
+
+static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
+						 boolean SuccessfulIO)
+{
+  BufferHeader->b_end_io(BufferHeader, SuccessfulIO);
+}
+
+
+/*
+  DAC960_V1_ReadWriteError prints an appropriate error message for Command
+  when an error occurs on a Read or Write operation.
 */
 
-static void DAC960_ReadWriteError(DAC960_Command_T *Command)
+static void DAC960_V1_ReadWriteError(DAC960_Command_T *Command)
 {
   DAC960_Controller_T *Controller = Command->Controller;
-  char *CommandName = "UNKNOWN";
+  unsigned char *CommandName = "UNKNOWN";
   switch (Command->CommandType)
     {
     case DAC960_ReadCommand:
@@ -1686,26 +2959,26 @@
     case DAC960_QueuedCommand:
       break;
     }
-  switch (Command->CommandStatus)
+  switch (Command->V1.CommandStatus)
     {
-    case DAC960_IrrecoverableDataError:
+    case DAC960_V1_IrrecoverableDataError:
       DAC960_Error("Irrecoverable Data Error on %s:\n",
 		   Controller, CommandName);
       break;
-    case DAC960_LogicalDriveNonexistentOrOffline:
+    case DAC960_V1_LogicalDriveNonexistentOrOffline:
       DAC960_Error("Logical Drive Nonexistent or Offline on %s:\n",
 		   Controller, CommandName);
       break;
-    case DAC960_AccessBeyondEndOfLogicalDrive:
+    case DAC960_V1_AccessBeyondEndOfLogicalDrive:
       DAC960_Error("Attempt to Access Beyond End of Logical Drive "
 		   "on %s:\n", Controller, CommandName);
       break;
-    case DAC960_BadDataEncountered:
+    case DAC960_V1_BadDataEncountered:
       DAC960_Error("Bad Data Encountered on %s:\n", Controller, CommandName);
       break;
     default:
       DAC960_Error("Unexpected Error Status %04X on %s:\n",
-		   Controller, Command->CommandStatus, CommandName);
+		   Controller, Command->V1.CommandStatus, CommandName);
       break;
     }
   DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %d..%d\n",
@@ -1723,33 +2996,22 @@
 
 
 /*
-  DAC960_ProcessCompletedBuffer performs completion processing for an
-  individual Buffer.
-*/
-
-static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
-						 boolean SuccessfulIO)
-{
-  BufferHeader->b_end_io(BufferHeader, SuccessfulIO);
-}
-
-
-/*
-  DAC960_ProcessCompletedCommand performs completion processing for Command.
+  DAC960_V1_ProcessCompletedCommand performs completion processing for Command
+  for DAC960 V1 Firmware Controllers.
 */
 
-static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
+static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
 {
   DAC960_Controller_T *Controller = Command->Controller;
   DAC960_CommandType_T CommandType = Command->CommandType;
-  DAC960_CommandOpcode_T CommandOpcode =
-    Command->CommandMailbox.Common.CommandOpcode;
-  DAC960_CommandStatus_T CommandStatus = Command->CommandStatus;
+  DAC960_V1_CommandOpcode_T CommandOpcode =
+    Command->V1.CommandMailbox.Common.CommandOpcode;
+  DAC960_V1_CommandStatus_T CommandStatus = Command->V1.CommandStatus;
   BufferHeader_T *BufferHeader = Command->BufferHeader;
   if (CommandType == DAC960_ReadCommand ||
       CommandType == DAC960_WriteCommand)
     {
-      if (CommandStatus == DAC960_NormalCompletion)
+      if (CommandStatus == DAC960_V1_NormalCompletion)
 	{
 	  /*
 	    Perform completion processing for all buffers in this I/O Request.
@@ -1771,21 +3033,22 @@
 	    }
 	  add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
 	}
-      else if ((CommandStatus == DAC960_IrrecoverableDataError ||
-		CommandStatus == DAC960_BadDataEncountered) &&
+      else if ((CommandStatus == DAC960_V1_IrrecoverableDataError ||
+		CommandStatus == DAC960_V1_BadDataEncountered) &&
 	       BufferHeader != NULL &&
 	       BufferHeader->b_reqnext != NULL)
 	{
-	  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
+	  DAC960_V1_CommandMailbox_T *CommandMailbox =
+	    &Command->V1.CommandMailbox;
 	  if (CommandType == DAC960_ReadCommand)
 	    {
 	      Command->CommandType = DAC960_ReadRetryCommand;
-	      CommandMailbox->Type5.CommandOpcode = DAC960_Read;
+	      CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
 	    }
 	  else
 	    {
 	      Command->CommandType = DAC960_WriteRetryCommand;
-	      CommandMailbox->Type5.CommandOpcode = DAC960_Write;
+	      CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
 	    }
 	  Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
 	  CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
@@ -1796,8 +3059,8 @@
 	}
       else
 	{
-	  if (CommandStatus != DAC960_LogicalDriveNonexistentOrOffline)
-	    DAC960_ReadWriteError(Command);
+	  if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
+	    DAC960_V1_ReadWriteError(Command);
 	  /*
 	    Perform completion processing for all buffers in this I/O Request.
 	  */
@@ -1826,17 +3089,18 @@
       /*
 	Perform completion processing for this single buffer.
       */
-      if (CommandStatus == DAC960_NormalCompletion)
+      if (CommandStatus == DAC960_V1_NormalCompletion)
 	DAC960_ProcessCompletedBuffer(BufferHeader, true);
       else
 	{
-	  if (CommandStatus != DAC960_LogicalDriveNonexistentOrOffline)
-	    DAC960_ReadWriteError(Command);
+	  if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
+	    DAC960_V1_ReadWriteError(Command);
 	  DAC960_ProcessCompletedBuffer(BufferHeader, false);
 	}
       if (NextBufferHeader != NULL)
 	{
-	  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
+	  DAC960_V1_CommandMailbox_T *CommandMailbox =
+	    &Command->V1.CommandMailbox;
 	  Command->BlockNumber +=
 	    BufferHeader->b_size >> DAC960_BlockSizeBits;
 	  Command->BlockCount =
@@ -1851,30 +3115,43 @@
 	}
     }
   else if (CommandType == DAC960_MonitoringCommand ||
-	   CommandOpcode == DAC960_Enquiry ||
-	   CommandOpcode == DAC960_GetRebuildProgress)
+	   CommandOpcode == DAC960_V1_Enquiry ||
+	   CommandOpcode == DAC960_V1_GetRebuildProgress)
     {
       if (CommandType != DAC960_MonitoringCommand)
 	{
-	  if (CommandOpcode == DAC960_Enquiry)
-	    memcpy(&Controller->Enquiry[Controller->EnquiryIndex ^ 1],
-		   Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress),
-		   sizeof(DAC960_Enquiry_T));
-	  else if (CommandOpcode == DAC960_GetRebuildProgress)
-	    memcpy(&Controller->RebuildProgress,
-		   Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress),
-		   sizeof(DAC960_RebuildProgress_T));
-	}
-      if (CommandOpcode == DAC960_Enquiry)
-	{
-	  DAC960_Enquiry_T *OldEnquiry =
-	    &Controller->Enquiry[Controller->EnquiryIndex];
-	  DAC960_Enquiry_T *NewEnquiry =
-	    &Controller->Enquiry[Controller->EnquiryIndex ^= 1];
+	  if (CommandOpcode == DAC960_V1_Enquiry)
+	    memcpy(&Controller->V1.NewEnquiry,
+		   Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress),
+		   sizeof(DAC960_V1_Enquiry_T));
+	  else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
+	    memcpy(&Controller->V1.RebuildProgress,
+		   Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress),
+		   sizeof(DAC960_V1_RebuildProgress_T));
+	}
+      if (CommandOpcode == DAC960_V1_Enquiry &&
+	  Controller->ControllerInitialized)
+	{
+	  DAC960_V1_Enquiry_T *OldEnquiry = &Controller->V1.Enquiry;
+	  DAC960_V1_Enquiry_T *NewEnquiry = &Controller->V1.NewEnquiry;
 	  unsigned int OldCriticalLogicalDriveCount =
 	    OldEnquiry->CriticalLogicalDriveCount;
 	  unsigned int NewCriticalLogicalDriveCount =
 	    NewEnquiry->CriticalLogicalDriveCount;
+	  if (NewEnquiry->NumberOfLogicalDrives > Controller->LogicalDriveCount)
+	    {
+	      int LogicalDriveNumber = Controller->LogicalDriveCount;
+	      while (LogicalDriveNumber < NewEnquiry->NumberOfLogicalDrives)
+		{
+		  DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
+				  "Now Exists\n", Controller,
+				  LogicalDriveNumber,
+				  Controller->ControllerNumber,
+				  LogicalDriveNumber);
+		  LogicalDriveNumber++;
+		}
+	      Controller->LogicalDriveCount = LogicalDriveNumber;
+	    }
 	  if (NewEnquiry->StatusFlags.DeferredWriteError !=
 	      OldEnquiry->StatusFlags.DeferredWriteError)
 	    DAC960_Critical("Deferred Write Error Flag is now %s\n", Controller,
@@ -1894,72 +3171,86 @@
 	      (jiffies - Controller->SecondaryMonitoringTime
 	       >= DAC960_SecondaryMonitoringInterval))
 	    {
-	      Controller->NeedLogicalDriveInformation = true;
-	      Controller->NewEventLogSequenceNumber =
+	      Controller->V1.NeedLogicalDriveInformation = true;
+	      Controller->V1.NewEventLogSequenceNumber =
 		NewEnquiry->EventLogSequenceNumber;
-	      Controller->NeedErrorTableInformation = true;
-	      Controller->NeedDeviceStateInformation = true;
-	      Controller->DeviceStateChannel = 0;
-	      Controller->DeviceStateTargetID = -1;
+	      Controller->V1.NeedErrorTableInformation = true;
+	      Controller->V1.NeedDeviceStateInformation = true;
+	      Controller->V1.DeviceStateChannel = 0;
+	      Controller->V1.DeviceStateTargetID = -1;
 	      Controller->SecondaryMonitoringTime = jiffies;
 	    }
-	  if (NewEnquiry->RebuildFlag == DAC960_StandbyRebuildInProgress ||
-	      NewEnquiry->RebuildFlag == DAC960_BackgroundRebuildInProgress ||
-	      OldEnquiry->RebuildFlag == DAC960_StandbyRebuildInProgress ||
-	      OldEnquiry->RebuildFlag == DAC960_BackgroundRebuildInProgress)
-	    Controller->NeedRebuildProgress = true;
-	  if (OldEnquiry->RebuildFlag == DAC960_BackgroundCheckInProgress)
+	  if (NewEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
+	      NewEnquiry->RebuildFlag
+	      == DAC960_V1_BackgroundRebuildInProgress ||
+	      OldEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
+	      OldEnquiry->RebuildFlag == DAC960_V1_BackgroundRebuildInProgress)
+	    {
+	      Controller->V1.NeedRebuildProgress = true;
+	      Controller->V1.RebuildProgressFirst =
+		(NewEnquiry->CriticalLogicalDriveCount <
+		 OldEnquiry->CriticalLogicalDriveCount);
+	    }
+	  if (OldEnquiry->RebuildFlag == DAC960_V1_BackgroundCheckInProgress)
 	    switch (NewEnquiry->RebuildFlag)
 	      {
-	      case DAC960_NoStandbyRebuildOrCheckInProgress:
+	      case DAC960_V1_NoStandbyRebuildOrCheckInProgress:
 		DAC960_Progress("Consistency Check Completed Successfully\n",
 				Controller);
 		break;
-	      case DAC960_StandbyRebuildInProgress:
-	      case DAC960_BackgroundRebuildInProgress:
+	      case DAC960_V1_StandbyRebuildInProgress:
+	      case DAC960_V1_BackgroundRebuildInProgress:
 		break;
-	      case DAC960_BackgroundCheckInProgress:
-		Controller->NeedConsistencyCheckProgress = true;
+	      case DAC960_V1_BackgroundCheckInProgress:
+		Controller->V1.NeedConsistencyCheckProgress = true;
 		break;
-	      case DAC960_StandbyRebuildCompletedWithError:
+	      case DAC960_V1_StandbyRebuildCompletedWithError:
 		DAC960_Progress("Consistency Check Completed with Error\n",
 				Controller);
 		break;
-	      case DAC960_BackgroundRebuildOrCheckFailed_DriveFailed:
+	      case DAC960_V1_BackgroundRebuildOrCheckFailed_DriveFailed:
 		DAC960_Progress("Consistency Check Failed - "
-				"Physical Drive Failed\n", Controller);
+				"Physical Device Failed\n", Controller);
 		break;
-	      case DAC960_BackgroundRebuildOrCheckFailed_LogicalDriveFailed:
+	      case DAC960_V1_BackgroundRebuildOrCheckFailed_LogicalDriveFailed:
 		DAC960_Progress("Consistency Check Failed - "
 				"Logical Drive Failed\n", Controller);
 		break;
-	      case DAC960_BackgroundRebuildOrCheckFailed_OtherCauses:
+	      case DAC960_V1_BackgroundRebuildOrCheckFailed_OtherCauses:
 		DAC960_Progress("Consistency Check Failed - Other Causes\n",
 				Controller);
 		break;
-	      case DAC960_BackgroundRebuildOrCheckSuccessfullyTerminated:
+	      case DAC960_V1_BackgroundRebuildOrCheckSuccessfullyTerminated:
 		DAC960_Progress("Consistency Check Successfully Terminated\n",
 				Controller);
 		break;
 	      }
-	  else if (NewEnquiry->RebuildFlag == DAC960_BackgroundCheckInProgress)
-	    Controller->NeedConsistencyCheckProgress = true;
+	  else if (NewEnquiry->RebuildFlag
+		   == DAC960_V1_BackgroundCheckInProgress)
+	    Controller->V1.NeedConsistencyCheckProgress = true;
+	  Controller->MonitoringAlertMode =
+	    (NewEnquiry->CriticalLogicalDriveCount > 0 ||
+	     NewEnquiry->OfflineLogicalDriveCount > 0 ||
+	     NewEnquiry->DeadDriveCount > 0);
 	  if (CommandType != DAC960_MonitoringCommand &&
-	      Controller->RebuildFlagPending)
+	      Controller->V1.RebuildFlagPending)
 	    {
-	      DAC960_Enquiry_T *Enquiry = (DAC960_Enquiry_T *)
-		Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress);
-	      Enquiry->RebuildFlag = Controller->PendingRebuildFlag;
-	      Controller->RebuildFlagPending = false;
+	      DAC960_V1_Enquiry_T *Enquiry = (DAC960_V1_Enquiry_T *)
+		Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress);
+	      Enquiry->RebuildFlag = Controller->V1.PendingRebuildFlag;
+	      Controller->V1.RebuildFlagPending = false;
 	    }
 	  else if (CommandType == DAC960_MonitoringCommand &&
-		   NewEnquiry->RebuildFlag > DAC960_BackgroundCheckInProgress)
+		   NewEnquiry->RebuildFlag >
+		   DAC960_V1_BackgroundCheckInProgress)
 	    {
-	      Controller->PendingRebuildFlag = NewEnquiry->RebuildFlag;
-	      Controller->RebuildFlagPending = true;
+	      Controller->V1.PendingRebuildFlag = NewEnquiry->RebuildFlag;
+	      Controller->V1.RebuildFlagPending = true;
 	    }
+	  memcpy(&Controller->V1.Enquiry, &Controller->V1.NewEnquiry,
+		 sizeof(DAC960_V1_Enquiry_T));
 	}
-      else if (CommandOpcode == DAC960_PerformEventLogOperation)
+      else if (CommandOpcode == DAC960_V1_PerformEventLogOperation)
 	{
 	  static char
 	    *DAC960_EventMessages[] =
@@ -1976,37 +3267,39 @@
 		 "killed because of selection timeout",
 		 "killed due to SCSI phase sequence error",
 		 "killed due to unknown status" };
-	  DAC960_EventLogEntry_T *EventLogEntry = &Controller->EventLogEntry;
+	  DAC960_V1_EventLogEntry_T *EventLogEntry =
+	    &Controller->V1.EventLogEntry;
 	  if (EventLogEntry->SequenceNumber ==
-	      Controller->OldEventLogSequenceNumber)
+	      Controller->V1.OldEventLogSequenceNumber)
 	    {
 	      unsigned char SenseKey = EventLogEntry->SenseKey;
 	      unsigned char AdditionalSenseCode =
 		EventLogEntry->AdditionalSenseCode;
 	      unsigned char AdditionalSenseCodeQualifier =
 		EventLogEntry->AdditionalSenseCodeQualifier;
-	      if (SenseKey == 9 &&
+	      if (SenseKey == DAC960_SenseKey_VendorSpecific &&
 		  AdditionalSenseCode == 0x80 &&
 		  AdditionalSenseCodeQualifier <
 		  sizeof(DAC960_EventMessages) / sizeof(char *))
-		DAC960_Critical("Physical Drive %d:%d %s\n", Controller,
+		DAC960_Critical("Physical Device %d:%d %s\n", Controller,
 				EventLogEntry->Channel,
 				EventLogEntry->TargetID,
 				DAC960_EventMessages[
 				  AdditionalSenseCodeQualifier]);
-	      else if (SenseKey == 6 && AdditionalSenseCode == 0x29)
+	      else if (SenseKey == DAC960_SenseKey_UnitAttention &&
+		       AdditionalSenseCode == 0x29)
 		{
 		  if (Controller->MonitoringTimerCount > 0)
-		    Controller->DeviceResetCount[EventLogEntry->Channel]
-						[EventLogEntry->TargetID]++;
+		    Controller->V1.DeviceResetCount[EventLogEntry->Channel]
+						   [EventLogEntry->TargetID]++;
 		}
-	      else if (!(SenseKey == 0 ||
-			 (SenseKey == 2 &&
+	      else if (!(SenseKey == DAC960_SenseKey_NoSense ||
+			 (SenseKey == DAC960_SenseKey_NotReady &&
 			  AdditionalSenseCode == 0x04 &&
 			  (AdditionalSenseCodeQualifier == 0x01 ||
 			   AdditionalSenseCodeQualifier == 0x02))))
 		{
-		  DAC960_Critical("Physical Drive %d:%d Error Log: "
+		  DAC960_Critical("Physical Device %d:%d Error Log: "
 				  "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
 				  Controller,
 				  EventLogEntry->Channel,
@@ -2014,7 +3307,7 @@
 				  SenseKey,
 				  AdditionalSenseCode,
 				  AdditionalSenseCodeQualifier);
-		  DAC960_Critical("Physical Drive %d:%d Error Log: "
+		  DAC960_Critical("Physical Device %d:%d Error Log: "
 				  "Information = %02X%02X%02X%02X "
 				  "%02X%02X%02X%02X\n",
 				  Controller,
@@ -2030,21 +3323,19 @@
 				  EventLogEntry->CommandSpecificInformation[3]);
 		}
 	    }
-	  Controller->OldEventLogSequenceNumber++;
+	  Controller->V1.OldEventLogSequenceNumber++;
 	}
-      else if (CommandOpcode == DAC960_GetErrorTable)
+      else if (CommandOpcode == DAC960_V1_GetErrorTable)
 	{
-	  DAC960_ErrorTable_T *OldErrorTable =
-	    &Controller->ErrorTable[Controller->ErrorTableIndex];
-	  DAC960_ErrorTable_T *NewErrorTable =
-	    &Controller->ErrorTable[Controller->ErrorTableIndex ^= 1];
+	  DAC960_V1_ErrorTable_T *OldErrorTable = &Controller->V1.ErrorTable;
+	  DAC960_V1_ErrorTable_T *NewErrorTable = &Controller->V1.NewErrorTable;
 	  int Channel, TargetID;
 	  for (Channel = 0; Channel < Controller->Channels; Channel++)
-	    for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
+	    for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
 	      {
-		DAC960_ErrorTableEntry_T *NewErrorEntry =
+		DAC960_V1_ErrorTableEntry_T *NewErrorEntry =
 		  &NewErrorTable->ErrorTableEntries[Channel][TargetID];
-		DAC960_ErrorTableEntry_T *OldErrorEntry =
+		DAC960_V1_ErrorTableEntry_T *OldErrorEntry =
 		  &OldErrorTable->ErrorTableEntries[Channel][TargetID];
 		if ((NewErrorEntry->ParityErrorCount !=
 		     OldErrorEntry->ParityErrorCount) ||
@@ -2054,7 +3345,7 @@
 		     OldErrorEntry->HardErrorCount) ||
 		    (NewErrorEntry->MiscErrorCount !=
 		     OldErrorEntry->MiscErrorCount))
-		  DAC960_Critical("Physical Drive %d:%d Errors: "
+		  DAC960_Critical("Physical Device %d:%d Errors: "
 				  "Parity = %d, Soft = %d, "
 				  "Hard = %d, Misc = %d\n",
 				  Controller, Channel, TargetID,
@@ -2063,51 +3354,49 @@
 				  NewErrorEntry->HardErrorCount,
 				  NewErrorEntry->MiscErrorCount);
 	      }
+	  memcpy(&Controller->V1.ErrorTable, &Controller->V1.NewErrorTable,
+		 sizeof(DAC960_V1_ErrorTable_T));
 	}
-      else if (CommandOpcode == DAC960_GetDeviceState)
+      else if (CommandOpcode == DAC960_V1_GetDeviceState)
 	{
-	  DAC960_DeviceState_T *OldDeviceState =
-	    &Controller->DeviceState[Controller->DeviceStateIndex]
-				    [Controller->DeviceStateChannel]
-				    [Controller->DeviceStateTargetID];
-	  DAC960_DeviceState_T *NewDeviceState =
-	    &Controller->DeviceState[Controller->DeviceStateIndex ^ 1]
-				    [Controller->DeviceStateChannel]
-				    [Controller->DeviceStateTargetID];
+	  DAC960_V1_DeviceState_T *OldDeviceState =
+	    &Controller->V1.DeviceState[Controller->V1.DeviceStateChannel]
+				       [Controller->V1.DeviceStateTargetID];
+	  DAC960_V1_DeviceState_T *NewDeviceState =
+	    &Controller->V1.NewDeviceState;
 	  if (NewDeviceState->DeviceState != OldDeviceState->DeviceState)
-	    DAC960_Critical("Physical Drive %d:%d is now %s\n", Controller,
-			    Controller->DeviceStateChannel,
-			    Controller->DeviceStateTargetID,
-			    (NewDeviceState->DeviceState == DAC960_Device_Dead
+	    DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
+			    Controller->V1.DeviceStateChannel,
+			    Controller->V1.DeviceStateTargetID,
+			    (NewDeviceState->DeviceState
+			     == DAC960_V1_Device_Dead
 			     ? "DEAD"
 			     : NewDeviceState->DeviceState
-			       == DAC960_Device_WriteOnly
+			       == DAC960_V1_Device_WriteOnly
 			       ? "WRITE-ONLY"
 			       : NewDeviceState->DeviceState
-				 == DAC960_Device_Online
+				 == DAC960_V1_Device_Online
 				 ? "ONLINE" : "STANDBY"));
-	  if (OldDeviceState->DeviceState == DAC960_Device_Dead &&
-	      NewDeviceState->DeviceState != DAC960_Device_Dead)
+	  if (OldDeviceState->DeviceState == DAC960_V1_Device_Dead &&
+	      NewDeviceState->DeviceState != DAC960_V1_Device_Dead)
 	    {
-	      Controller->NeedDeviceInquiryInformation = true;
-	      Controller->NeedDeviceSerialNumberInformation = true;
+	      Controller->V1.NeedDeviceInquiryInformation = true;
+	      Controller->V1.NeedDeviceSerialNumberInformation = true;
 	    }
+	  memcpy(OldDeviceState, NewDeviceState,
+		 sizeof(DAC960_V1_DeviceState_T));
 	}
-      else if (CommandOpcode == DAC960_GetLogicalDriveInformation)
+      else if (CommandOpcode == DAC960_V1_GetLogicalDriveInformation)
 	{
 	  int LogicalDriveNumber;
 	  for (LogicalDriveNumber = 0;
 	       LogicalDriveNumber < Controller->LogicalDriveCount;
 	       LogicalDriveNumber++)
 	    {
-	      DAC960_LogicalDriveInformation_T *OldLogicalDriveInformation =
-		&Controller->LogicalDriveInformation
-			     [Controller->LogicalDriveInformationIndex]
-			     [LogicalDriveNumber];
-	      DAC960_LogicalDriveInformation_T *NewLogicalDriveInformation =
-		&Controller->LogicalDriveInformation
-			     [Controller->LogicalDriveInformationIndex ^ 1]
-			     [LogicalDriveNumber];
+	      DAC960_V1_LogicalDriveInformation_T *OldLogicalDriveInformation =
+		&Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
+	      DAC960_V1_LogicalDriveInformation_T *NewLogicalDriveInformation =
+		&Controller->V1.NewLogicalDriveInformation[LogicalDriveNumber];
 	      if (NewLogicalDriveInformation->LogicalDriveState !=
 		  OldLogicalDriveInformation->LogicalDriveState)
 		DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
@@ -2116,11 +3405,11 @@
 				Controller->ControllerNumber,
 				LogicalDriveNumber,
 				(NewLogicalDriveInformation->LogicalDriveState
-				 == DAC960_LogicalDrive_Online
+				 == DAC960_V1_LogicalDrive_Online
 				 ? "ONLINE"
 				 : NewLogicalDriveInformation->LogicalDriveState
-				 == DAC960_LogicalDrive_Critical
-				 ? "CRITICAL" : "OFFLINE"));
+				   == DAC960_V1_LogicalDrive_Critical
+				   ? "CRITICAL" : "OFFLINE"));
 	      if (NewLogicalDriveInformation->WriteBack !=
 		  OldLogicalDriveInformation->WriteBack)
 		DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
@@ -2131,22 +3420,24 @@
 				(NewLogicalDriveInformation->WriteBack
 				 ? "WRITE BACK" : "WRITE THRU"));
 	    }
-	  Controller->LogicalDriveInformationIndex ^= 1;
+	  memcpy(&Controller->V1.LogicalDriveInformation,
+		 &Controller->V1.NewLogicalDriveInformation,
+		 sizeof(DAC960_V1_LogicalDriveInformationArray_T));
 	}
-      else if (CommandOpcode == DAC960_GetRebuildProgress)
+      else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
 	{
 	  unsigned int LogicalDriveNumber =
-	    Controller->RebuildProgress.LogicalDriveNumber;
+	    Controller->V1.RebuildProgress.LogicalDriveNumber;
 	  unsigned int LogicalDriveSize =
-	    Controller->RebuildProgress.LogicalDriveSize;
+	    Controller->V1.RebuildProgress.LogicalDriveSize;
 	  unsigned int BlocksCompleted =
-	    LogicalDriveSize - Controller->RebuildProgress.RemainingBlocks;
-	  if (CommandStatus == DAC960_NoRebuildOrCheckInProgress &&
-	      Controller->LastRebuildStatus == DAC960_NormalCompletion)
-	    CommandStatus = DAC960_RebuildSuccessful;
+	    LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
+	  if (CommandStatus == DAC960_V1_NoRebuildOrCheckInProgress &&
+	      Controller->V1.LastRebuildStatus == DAC960_V1_NormalCompletion)
+	    CommandStatus = DAC960_V1_RebuildSuccessful;
 	  switch (CommandStatus)
 	    {
-	    case DAC960_NormalCompletion:
+	    case DAC960_V1_NormalCompletion:
 	      Controller->EphemeralProgressMessage = true;
 	      DAC960_Progress("Rebuild in Progress: "
 			      "Logical Drive %d (/dev/rd/c%dd%d) "
@@ -2158,244 +3449,1061 @@
 			      / (LogicalDriveSize >> 7));
 	      Controller->EphemeralProgressMessage = false;
 	      break;
-	    case DAC960_RebuildFailed_LogicalDriveFailure:
+	    case DAC960_V1_RebuildFailed_LogicalDriveFailure:
 	      DAC960_Progress("Rebuild Failed due to "
 			      "Logical Drive Failure\n", Controller);
 	      break;
-	    case DAC960_RebuildFailed_BadBlocksOnOther:
+	    case DAC960_V1_RebuildFailed_BadBlocksOnOther:
 	      DAC960_Progress("Rebuild Failed due to "
 			      "Bad Blocks on Other Drives\n", Controller);
 	      break;
-	    case DAC960_RebuildFailed_NewDriveFailed:
+	    case DAC960_V1_RebuildFailed_NewDriveFailed:
 	      DAC960_Progress("Rebuild Failed due to "
 			      "Failure of Drive Being Rebuilt\n", Controller);
 	      break;
-	    case DAC960_NoRebuildOrCheckInProgress:
+	    case DAC960_V1_NoRebuildOrCheckInProgress:
 	      break;
-	    case DAC960_RebuildSuccessful:
+	    case DAC960_V1_RebuildSuccessful:
 	      DAC960_Progress("Rebuild Completed Successfully\n", Controller);
 	      break;
-	    case DAC960_RebuildSuccessfullyTerminated:
+	    case DAC960_V1_RebuildSuccessfullyTerminated:
 	      DAC960_Progress("Rebuild Successfully Terminated\n", Controller);
 	      break;
 	    }
-	  Controller->LastRebuildStatus = CommandStatus;
+	  Controller->V1.LastRebuildStatus = CommandStatus;
 	  if (CommandType != DAC960_MonitoringCommand &&
-	      Controller->RebuildStatusPending)
+	      Controller->V1.RebuildStatusPending)
+	    {
+	      Command->V1.CommandStatus = Controller->V1.PendingRebuildStatus;
+	      Controller->V1.RebuildStatusPending = false;
+	    }
+	  else if (CommandType == DAC960_MonitoringCommand &&
+		   CommandStatus != DAC960_V1_NormalCompletion &&
+		   CommandStatus != DAC960_V1_NoRebuildOrCheckInProgress)
+	    {
+	      Controller->V1.PendingRebuildStatus = CommandStatus;
+	      Controller->V1.RebuildStatusPending = true;
+	    }
+	}
+      else if (CommandOpcode == DAC960_V1_RebuildStat)
+	{
+	  unsigned int LogicalDriveNumber =
+	    Controller->V1.RebuildProgress.LogicalDriveNumber;
+	  unsigned int LogicalDriveSize =
+	    Controller->V1.RebuildProgress.LogicalDriveSize;
+	  unsigned int BlocksCompleted =
+	    LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
+	  if (CommandStatus == DAC960_V1_NormalCompletion)
+	    {
+	      Controller->EphemeralProgressMessage = true;
+	      DAC960_Progress("Consistency Check in Progress: "
+			      "Logical Drive %d (/dev/rd/c%dd%d) "
+			      "%d%% completed\n",
+			      Controller, LogicalDriveNumber,
+			      Controller->ControllerNumber,
+			      LogicalDriveNumber,
+			      (100 * (BlocksCompleted >> 7))
+			      / (LogicalDriveSize >> 7));
+	      Controller->EphemeralProgressMessage = false;
+	    }
+	}
+    }
+  if (CommandType == DAC960_MonitoringCommand)
+    {
+      if (Controller->V1.NewEventLogSequenceNumber
+	  - Controller->V1.OldEventLogSequenceNumber > 0)
+	{
+	  Command->V1.CommandMailbox.Type3E.CommandOpcode =
+	    DAC960_V1_PerformEventLogOperation;
+	  Command->V1.CommandMailbox.Type3E.OperationType =
+	    DAC960_V1_GetEventLogEntry;
+	  Command->V1.CommandMailbox.Type3E.OperationQualifier = 1;
+	  Command->V1.CommandMailbox.Type3E.SequenceNumber =
+	    Controller->V1.OldEventLogSequenceNumber;
+	  Command->V1.CommandMailbox.Type3E.BusAddress =
+	    Virtual_to_Bus(&Controller->V1.EventLogEntry);
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      if (Controller->V1.NeedErrorTableInformation)
+	{
+	  Controller->V1.NeedErrorTableInformation = false;
+	  Command->V1.CommandMailbox.Type3.CommandOpcode =
+	    DAC960_V1_GetErrorTable;
+	  Command->V1.CommandMailbox.Type3.BusAddress =
+	    Virtual_to_Bus(&Controller->V1.NewErrorTable);
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      if (Controller->V1.NeedRebuildProgress &&
+	  Controller->V1.RebuildProgressFirst)
+	{
+	  Controller->V1.NeedRebuildProgress = false;
+	  Command->V1.CommandMailbox.Type3.CommandOpcode =
+	    DAC960_V1_GetRebuildProgress;
+	  Command->V1.CommandMailbox.Type3.BusAddress =
+	    Virtual_to_Bus(&Controller->V1.RebuildProgress);
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      if (Controller->V1.NeedDeviceStateInformation)
+	{
+	  if (Controller->V1.NeedDeviceInquiryInformation)
+	    {
+	      DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
+	      DAC960_SCSI_Inquiry_T *InquiryStandardData =
+		&Controller->V1.InquiryStandardData
+				[Controller->V1.DeviceStateChannel]
+				[Controller->V1.DeviceStateTargetID];
+	      InquiryStandardData->PeripheralDeviceType = 0x1F;
+	      Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
+	      Command->V1.CommandMailbox.Type3.BusAddress =
+		Virtual_to_Bus(DCDB);
+	      DCDB->Channel = Controller->V1.DeviceStateChannel;
+	      DCDB->TargetID = Controller->V1.DeviceStateTargetID;
+	      DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
+	      DCDB->EarlyStatus = false;
+	      DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
+	      DCDB->NoAutomaticRequestSense = false;
+	      DCDB->DisconnectPermitted = true;
+	      DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
+	      DCDB->BusAddress = Virtual_to_Bus(InquiryStandardData);
+	      DCDB->CDBLength = 6;
+	      DCDB->TransferLengthHigh4 = 0;
+	      DCDB->SenseLength = sizeof(DCDB->SenseData);
+	      DCDB->CDB[0] = 0x12; /* INQUIRY */
+	      DCDB->CDB[1] = 0; /* EVPD = 0 */
+	      DCDB->CDB[2] = 0; /* Page Code */
+	      DCDB->CDB[3] = 0; /* Reserved */
+	      DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
+	      DCDB->CDB[5] = 0; /* Control */
+	      DAC960_QueueCommand(Command);
+	      Controller->V1.NeedDeviceInquiryInformation = false;
+	      return;
+	    }
+	  if (Controller->V1.NeedDeviceSerialNumberInformation)
+	    {
+	      DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
+	      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
+		&Controller->V1.InquiryUnitSerialNumber
+				[Controller->V1.DeviceStateChannel]
+				[Controller->V1.DeviceStateTargetID];
+	      InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+	      Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
+	      Command->V1.CommandMailbox.Type3.BusAddress =
+		Virtual_to_Bus(DCDB);
+	      DCDB->Channel = Controller->V1.DeviceStateChannel;
+	      DCDB->TargetID = Controller->V1.DeviceStateTargetID;
+	      DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
+	      DCDB->EarlyStatus = false;
+	      DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
+	      DCDB->NoAutomaticRequestSense = false;
+	      DCDB->DisconnectPermitted = true;
+	      DCDB->TransferLength =
+		sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+	      DCDB->BusAddress = Virtual_to_Bus(InquiryUnitSerialNumber);
+	      DCDB->CDBLength = 6;
+	      DCDB->TransferLengthHigh4 = 0;
+	      DCDB->SenseLength = sizeof(DCDB->SenseData);
+	      DCDB->CDB[0] = 0x12; /* INQUIRY */
+	      DCDB->CDB[1] = 1; /* EVPD = 1 */
+	      DCDB->CDB[2] = 0x80; /* Page Code */
+	      DCDB->CDB[3] = 0; /* Reserved */
+	      DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+	      DCDB->CDB[5] = 0; /* Control */
+	      DAC960_QueueCommand(Command);
+	      Controller->V1.NeedDeviceSerialNumberInformation = false;
+	      return;
+	    }
+	  if (++Controller->V1.DeviceStateTargetID == Controller->Targets)
+	    {
+	      Controller->V1.DeviceStateChannel++;
+	      Controller->V1.DeviceStateTargetID = 0;
+	    }
+	  while (Controller->V1.DeviceStateChannel < Controller->Channels)
+	    {
+	      DAC960_V1_DeviceState_T *OldDeviceState =
+		&Controller->V1.DeviceState[Controller->V1.DeviceStateChannel]
+					   [Controller->V1.DeviceStateTargetID];
+	      if (OldDeviceState->Present &&
+		  OldDeviceState->DeviceType == DAC960_V1_DiskType)
+		{
+		  Command->V1.CommandMailbox.Type3D.CommandOpcode =
+		    DAC960_V1_GetDeviceState;
+		  Command->V1.CommandMailbox.Type3D.Channel =
+		    Controller->V1.DeviceStateChannel;
+		  Command->V1.CommandMailbox.Type3D.TargetID =
+		    Controller->V1.DeviceStateTargetID;
+		  Command->V1.CommandMailbox.Type3D.BusAddress =
+		    Virtual_to_Bus(&Controller->V1.NewDeviceState);
+		  DAC960_QueueCommand(Command);
+		  return;
+		}
+	      if (++Controller->V1.DeviceStateTargetID == Controller->Targets)
+		{
+		  Controller->V1.DeviceStateChannel++;
+		  Controller->V1.DeviceStateTargetID = 0;
+		}
+	    }
+	  Controller->V1.NeedDeviceStateInformation = false;
+	}
+      if (Controller->V1.NeedLogicalDriveInformation)
+	{
+	  Controller->V1.NeedLogicalDriveInformation = false;
+	  Command->V1.CommandMailbox.Type3.CommandOpcode =
+	    DAC960_V1_GetLogicalDriveInformation;
+	  Command->V1.CommandMailbox.Type3.BusAddress =
+	    Virtual_to_Bus(&Controller->V1.NewLogicalDriveInformation);
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      if (Controller->V1.NeedRebuildProgress)
+	{
+	  Controller->V1.NeedRebuildProgress = false;
+	  Command->V1.CommandMailbox.Type3.CommandOpcode =
+	    DAC960_V1_GetRebuildProgress;
+	  Command->V1.CommandMailbox.Type3.BusAddress =
+	    Virtual_to_Bus(&Controller->V1.RebuildProgress);
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      if (Controller->V1.NeedConsistencyCheckProgress)
+	{
+	  Controller->V1.NeedConsistencyCheckProgress = false;
+	  Command->V1.CommandMailbox.Type3.CommandOpcode =
+	    DAC960_V1_RebuildStat;
+	  Command->V1.CommandMailbox.Type3.BusAddress =
+	    Virtual_to_Bus(&Controller->V1.RebuildProgress);
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      Controller->MonitoringTimerCount++;
+      Controller->MonitoringTimer.expires =
+	jiffies + DAC960_MonitoringTimerInterval;
+      add_timer(&Controller->MonitoringTimer);
+    }
+  if (CommandType == DAC960_ImmediateCommand)
+    {
+      up(Command->Semaphore);
+      Command->Semaphore = NULL;
+      return;
+    }
+  if (CommandType == DAC960_QueuedCommand)
+    {
+      DAC960_V1_KernelCommand_T *KernelCommand = Command->V1.KernelCommand;
+      KernelCommand->CommandStatus = Command->V1.CommandStatus;
+      Command->V1.KernelCommand = NULL;
+      if (CommandOpcode == DAC960_V1_DCDB)
+	Controller->V1.DirectCommandActive[KernelCommand->DCDB->Channel]
+					  [KernelCommand->DCDB->TargetID] =
+	  false;
+      DAC960_DeallocateCommand(Command);
+      KernelCommand->CompletionFunction(KernelCommand);
+      return;
+    }
+  /*
+    Queue a Status Monitoring Command to the Controller using the just
+    completed Command if one was deferred previously due to lack of a
+    free Command when the Monitoring Timer Function was called.
+  */
+  if (Controller->MonitoringCommandDeferred)
+    {
+      Controller->MonitoringCommandDeferred = false;
+      DAC960_V1_QueueMonitoringCommand(Command);
+      return;
+    }
+  /*
+    Deallocate the Command.
+  */
+  DAC960_DeallocateCommand(Command);
+  /*
+    Wake up any processes waiting on a free Command.
+  */
+  wake_up(&Controller->CommandWaitQueue);
+}
+
+
+/*
+  DAC960_V2_ReadWriteError prints an appropriate error message for Command
+  when an error occurs on a Read or Write operation.
+*/
+
+static void DAC960_V2_ReadWriteError(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  unsigned char *SenseErrors[] = { "NO SENSE", "RECOVERED ERROR",
+				   "NOT READY", "MEDIUM ERROR",
+				   "HARDWARE ERROR", "ILLEGAL REQUEST",
+				   "UNIT ATTENTION", "DATA PROTECT",
+				   "BLANK CHECK", "VENDOR-SPECIFIC",
+				   "COPY ABORTED", "ABORTED COMMAND",
+				   "EQUAL", "VOLUME OVERFLOW",
+				   "MISCOMPARE", "RESERVED" };
+  unsigned char *CommandName = "UNKNOWN";
+  switch (Command->CommandType)
+    {
+    case DAC960_ReadCommand:
+    case DAC960_ReadRetryCommand:
+      CommandName = "READ";
+      break;
+    case DAC960_WriteCommand:
+    case DAC960_WriteRetryCommand:
+      CommandName = "WRITE";
+      break;
+    case DAC960_MonitoringCommand:
+    case DAC960_ImmediateCommand:
+    case DAC960_QueuedCommand:
+      break;
+    }
+  DAC960_Error("Error Condition %s on %s:\n", Controller,
+	       SenseErrors[Command->V2.RequestSense.SenseKey], CommandName);
+  DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %d..%d\n",
+	       Controller, Controller->ControllerNumber,
+	       Command->LogicalDriveNumber, Command->BlockNumber,
+	       Command->BlockNumber + Command->BlockCount - 1);
+  if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
+    DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
+		 Controller, Controller->ControllerNumber,
+		 Command->LogicalDriveNumber,
+		 DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
+		 Command->BufferHeader->b_rsector,
+		 Command->BufferHeader->b_rsector + Command->BlockCount - 1);
+}
+
+
+/*
+  DAC960_V2_ReportEvent prints an appropriate message when a Controller Event
+  occurs.
+*/
+
+static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller,
+				  DAC960_V2_Event_T *Event)
+{
+  DAC960_SCSI_RequestSense_T *RequestSense =
+    (DAC960_SCSI_RequestSense_T *) &Event->RequestSenseData;
+  unsigned char MessageBuffer[DAC960_LineBufferSize];
+  static struct { int EventCode; unsigned char *EventMessage; } EventList[] =
+    { /* Physical Device Events (0x0000 - 0x007F) */
+      { 0x0001, "P Online" },
+      { 0x0002, "P Standby" },
+      { 0x0005, "P Automatic Rebuild Started" },
+      { 0x0006, "P Manual Rebuild Started" },
+      { 0x0007, "P Rebuild Completed" },
+      { 0x0008, "P Rebuild Cancelled" },
+      { 0x0009, "P Rebuild Failed for Unknown Reasons" },
+      { 0x000A, "P Rebuild Failed due to New Physical Device" },
+      { 0x000B, "P Rebuild Failed due to Logical Drive Failure" },
+      { 0x000C, "S Offline" },
+      { 0x000D, "P Found" },
+      { 0x000E, "P Gone" },
+      { 0x000F, "P Unconfigured" },
+      { 0x0010, "P Expand Capacity Started" },
+      { 0x0011, "P Expand Capacity Completed" },
+      { 0x0012, "P Expand Capacity Failed" },
+      { 0x0016, "P Parity Error" },
+      { 0x0017, "P Soft Error" },
+      { 0x0018, "P Miscellaneous Error" },
+      { 0x0019, "P Reset" },
+      { 0x001A, "P Active Spare Found" },
+      { 0x001B, "P Warm Spare Found" },
+      { 0x001C, "S Sense Data Received" },
+      { 0x001D, "P Initialization Started" },
+      { 0x001E, "P Initialization Completed" },
+      { 0x001F, "P Initialization Failed" },
+      { 0x0020, "P Initialization Cancelled" },
+      { 0x0021, "P Failed because Write Recovery Failed" },
+      { 0x0022, "P Failed because SCSI Bus Reset Failed" },
+      { 0x0023, "P Failed because of Double Check Condition" },
+      { 0x0024, "P Failed because Device Cannot Be Accessed" },
+      { 0x0025, "P Failed because of Gross Error on SCSI Processor" },
+      { 0x0026, "P Failed because of Bad Tag from Device" },
+      { 0x0027, "P Failed because of Command Timeout" },
+      { 0x0028, "P Failed because of System Reset" },
+      { 0x0029, "P Failed because of Busy Status or Parity Error" },
+      { 0x002A, "P Failed because Host Set Device to Failed State" },
+      { 0x002B, "P Failed because of Selection Timeout" },
+      { 0x002C, "P Failed because of SCSI Bus Phase Error" },
+      { 0x002D, "P Failed because Device Returned Unknown Status" },
+      { 0x002E, "P Failed because Device Not Ready" },
+      { 0x002F, "P Failed because Device Not Found at Startup" },
+      { 0x0030, "P Failed because COD Write Operation Failed" },
+      { 0x0031, "P Failed because BDT Write Operation Failed" },
+      { 0x0039, "P Missing at Startup" },
+      { 0x003A, "P Start Rebuild Failed due to Physical Drive Too Small" },
+      /* Logical Device Events (0x0080 - 0x00FF) */
+      { 0x0080, "M Consistency Check Started" },
+      { 0x0081, "M Consistency Check Completed" },
+      { 0x0082, "M Consistency Check Cancelled" },
+      { 0x0083, "M Consistency Check Completed With Errors" },
+      { 0x0084, "M Consistency Check Failed due to Logical Drive Failure" },
+      { 0x0085, "M Consistency Check Failed due to Physical Device Failure" },
+      { 0x0086, "L Offline" },
+      { 0x0087, "L Critical" },
+      { 0x0088, "L Online" },
+      { 0x0089, "M Automatic Rebuild Started" },
+      { 0x008A, "M Manual Rebuild Started" },
+      { 0x008B, "M Rebuild Completed" },
+      { 0x008C, "M Rebuild Cancelled" },
+      { 0x008D, "M Rebuild Failed for Unknown Reasons" },
+      { 0x008E, "M Rebuild Failed due to New Physical Device" },
+      { 0x008F, "M Rebuild Failed due to Logical Drive Failure" },
+      { 0x0090, "L Initialization Started" },
+      { 0x0091, "L Initialization Completed" },
+      { 0x0092, "L Initialization Cancelled" },
+      { 0x0093, "L Initialization Failed" },
+      { 0x0094, "L Found" },
+      { 0x0095, "L Gone" },
+      { 0x0096, "L Expand Capacity Started" },
+      { 0x0097, "L Expand Capacity Completed" },
+      { 0x0098, "L Expand Capacity Failed" },
+      { 0x0099, "L Bad Block Found" },
+      { 0x009A, "L Size Changed" },
+      { 0x009B, "L Type Changed" },
+      { 0x009C, "L Bad Data Block Found" },
+      { 0x009E, "L Read of Data Block in BDT" },
+      { 0x009F, "L Write Back Data for Disk Block Lost" },
+      /* Fault Management Events (0x0100 - 0x017F) */
+      { 0x0140, "E Fan %d Failed" },
+      { 0x0141, "E Fan %d OK" },
+      { 0x0142, "E Fan %d Not Present" },
+      { 0x0143, "E Power Supply %d Failed" },
+      { 0x0144, "E Power Supply %d OK" },
+      { 0x0145, "E Power Supply %d Not Present" },
+      { 0x0146, "E Temperature Sensor %d Failed" },
+      { 0x0147, "E Temperature Sensor %d Critical" },
+      { 0x0148, "E Temperature Sensor %d OK" },
+      { 0x0149, "E Temperature Sensor %d Not Present" },
+      { 0x014A, "E Unit %d Access Critical" },
+      { 0x014B, "E Unit %d Access OK" },
+      { 0x014C, "E Unit %d Access Offline" },
+      /* Controller Events (0x0180 - 0x01FF) */
+      { 0x0181, "C Cache Write Back Error" },
+      { 0x0188, "C Battery Backup Unit Found" },
+      { 0x0189, "C Battery Backup Unit Charge Level Low" },
+      { 0x018A, "C Battery Backup Unit Charge Level OK" },
+      { 0x0193, "C Installation Aborted" },
+      { 0x0195, "C Mirror Race Recovery In Progress" },
+      { 0x0196, "C Mirror Race on Critical Drive" },
+      { 0x019E, "C Memory Soft ECC Error" },
+      { 0x019F, "C Memory Hard ECC Error" },
+      { 0x01A2, "C Battery Backup Unit Failed" },
+      { 0, "" } };
+  int EventListIndex = 0, EventCode;
+  unsigned char EventType, *EventMessage;
+  while (true)
+    {
+      EventCode = EventList[EventListIndex].EventCode;
+      if (EventCode == Event->EventCode || EventCode == 0) break;
+      EventListIndex++;
+    }
+  EventType = EventList[EventListIndex].EventMessage[0];
+  EventMessage = &EventList[EventListIndex].EventMessage[2];
+  if (EventCode == 0)
+    {
+      DAC960_Critical("Unknown Controller Event Code %04X\n",
+		      Controller, Event->EventCode);
+      return;
+    }
+  switch (EventType)
+    {
+    case 'P':
+      DAC960_Critical("Physical Device %d:%d %s\n", Controller,
+		      Event->Channel, Event->TargetID, EventMessage);
+      break;
+    case 'L':
+      DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) %s\n", Controller,
+		      Event->LogicalUnit, Controller->ControllerNumber,
+		      Event->LogicalUnit, EventMessage);
+      break;
+    case 'M':
+      DAC960_Progress("Logical Drive %d (/dev/rd/c%dd%d) %s\n", Controller,
+		      Event->LogicalUnit, Controller->ControllerNumber,
+		      Event->LogicalUnit, EventMessage);
+      break;
+    case 'S':
+      if (RequestSense->SenseKey == DAC960_SenseKey_NoSense ||
+	  (RequestSense->SenseKey == DAC960_SenseKey_NotReady &&
+	   RequestSense->AdditionalSenseCode == 0x04 &&
+	   (RequestSense->AdditionalSenseCodeQualifier == 0x01 ||
+	    RequestSense->AdditionalSenseCodeQualifier == 0x02)))
+	break;
+      DAC960_Critical("Physical Device %d:%d %s\n", Controller,
+		      Event->Channel, Event->TargetID, EventMessage);
+      DAC960_Critical("Physical Device %d:%d Request Sense: "
+		      "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
+		      Controller,
+		      Event->Channel,
+		      Event->TargetID,
+		      RequestSense->SenseKey,
+		      RequestSense->AdditionalSenseCode,
+		      RequestSense->AdditionalSenseCodeQualifier);
+      DAC960_Critical("Physical Device %d:%d Request Sense: "
+		      "Information = %02X%02X%02X%02X "
+		      "%02X%02X%02X%02X\n",
+		      Controller,
+		      Event->Channel,
+		      Event->TargetID,
+		      RequestSense->Information[0],
+		      RequestSense->Information[1],
+		      RequestSense->Information[2],
+		      RequestSense->Information[3],
+		      RequestSense->CommandSpecificInformation[0],
+		      RequestSense->CommandSpecificInformation[1],
+		      RequestSense->CommandSpecificInformation[2],
+		      RequestSense->CommandSpecificInformation[3]);
+      break;
+    case 'E':
+      sprintf(MessageBuffer, EventMessage, Event->LogicalUnit);
+      DAC960_Critical("Enclosure %d %s\n", Controller,
+		      Event->TargetID, MessageBuffer);
+      break;
+    case 'C':
+      DAC960_Critical("Controller %s\n", Controller, EventMessage);
+      break;
+    default:
+      DAC960_Critical("Unknown Controller Event Code %04X\n",
+		      Controller, Event->EventCode);
+      break;
+    }
+}
+
+
+/*
+  DAC960_V2_ReportProgress prints an appropriate progress message for
+  Logical Device Long Operations.
+*/
+
+static void DAC960_V2_ReportProgress(DAC960_Controller_T *Controller,
+				     unsigned char *MessageString,
+				     unsigned int LogicalDeviceNumber,
+				     unsigned long BlocksCompleted,
+				     unsigned long LogicalDeviceSize)
+{
+  Controller->EphemeralProgressMessage = true;
+  DAC960_Progress("%s in Progress: Logical Drive %d (/dev/rd/c%dd%d) "
+		  "%d%% completed\n", Controller,
+		  MessageString,
+		  LogicalDeviceNumber,
+		  Controller->ControllerNumber,
+		  LogicalDeviceNumber,
+		  (100 * (BlocksCompleted >> 7)) / (LogicalDeviceSize >> 7));
+  Controller->EphemeralProgressMessage = false;
+}
+
+
+/*
+  DAC960_V2_ProcessCompletedCommand performs completion processing for Command
+  for DAC960 V2 Firmware Controllers.
+*/
+
+static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  DAC960_CommandType_T CommandType = Command->CommandType;
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_IOCTL_Opcode_T CommandOpcode = CommandMailbox->Common.IOCTL_Opcode;
+  DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus;
+  BufferHeader_T *BufferHeader = Command->BufferHeader;
+  if (CommandType == DAC960_ReadCommand ||
+      CommandType == DAC960_WriteCommand)
+    {
+      if (CommandStatus == DAC960_V2_NormalCompletion)
+	{
+	  /*
+	    Perform completion processing for all buffers in this I/O Request.
+	  */
+	  while (BufferHeader != NULL)
 	    {
-	      Command->CommandStatus = Controller->PendingRebuildStatus;
-	      Controller->RebuildStatusPending = false;
+	      BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
+	      BufferHeader->b_reqnext = NULL;
+	      DAC960_ProcessCompletedBuffer(BufferHeader, true);
+	      BufferHeader = NextBufferHeader;
 	    }
-	  else if (CommandType == DAC960_MonitoringCommand &&
-		   CommandStatus != DAC960_NormalCompletion &&
-		   CommandStatus != DAC960_NoRebuildOrCheckInProgress)
+	  /*
+	    Wake up requestor for swap file paging requests.
+	  */
+	  if (Command->Semaphore != NULL)
 	    {
-	      Controller->PendingRebuildStatus = CommandStatus;
-	      Controller->RebuildStatusPending = true;
+	      up(Command->Semaphore);
+	      Command->Semaphore = NULL;
 	    }
+	  add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
 	}
-      else if (CommandOpcode == DAC960_RebuildStat)
+      else if (Command->V2.RequestSense.SenseKey
+	       == DAC960_SenseKey_MediumError &&
+	       BufferHeader != NULL &&
+	       BufferHeader->b_reqnext != NULL)
 	{
-	  unsigned int LogicalDriveNumber =
-	    Controller->RebuildProgress.LogicalDriveNumber;
-	  unsigned int LogicalDriveSize =
-	    Controller->RebuildProgress.LogicalDriveSize;
-	  unsigned int BlocksCompleted =
-	    LogicalDriveSize - Controller->RebuildProgress.RemainingBlocks;
-	  if (CommandStatus == DAC960_NormalCompletion)
+	  if (CommandType == DAC960_ReadCommand)
+	    Command->CommandType = DAC960_ReadRetryCommand;
+	  else Command->CommandType = DAC960_WriteRetryCommand;
+	  Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
+	  CommandMailbox->SCSI_10.CommandControlBits
+				 .AdditionalScatterGatherListMemory = false;
+	  CommandMailbox->SCSI_10.DataTransferSize =
+	    Command->BlockCount << DAC960_BlockSizeBits;
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				 .ScatterGatherSegments[0].SegmentDataPointer =
+	    Virtual_to_Bus(BufferHeader->b_data);
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				 .ScatterGatherSegments[0].SegmentByteCount =
+	    CommandMailbox->SCSI_10.DataTransferSize;
+	  CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
+	  CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      else
+	{
+	  if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
+	    DAC960_V2_ReadWriteError(Command);
+	  /*
+	    Perform completion processing for all buffers in this I/O Request.
+	  */
+	  while (BufferHeader != NULL)
 	    {
-	      Controller->EphemeralProgressMessage = true;
-	      DAC960_Progress("Consistency Check in Progress: "
-			      "Logical Drive %d (/dev/rd/c%dd%d) "
-			      "%d%% completed\n",
-			      Controller, LogicalDriveNumber,
-			      Controller->ControllerNumber,
-			      LogicalDriveNumber,
-			      (100 * (BlocksCompleted >> 7))
-			      / (LogicalDriveSize >> 7));
-	      Controller->EphemeralProgressMessage = false;
+	      BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
+	      BufferHeader->b_reqnext = NULL;
+	      DAC960_ProcessCompletedBuffer(BufferHeader, false);
+	      BufferHeader = NextBufferHeader;
+	    }
+	  /*
+	    Wake up requestor for swap file paging requests.
+	  */
+	  if (Command->Semaphore != NULL)
+	    {
+	      up(Command->Semaphore);
+	      Command->Semaphore = NULL;
 	    }
 	}
     }
-  if (CommandType == DAC960_MonitoringCommand)
+  else if (CommandType == DAC960_ReadRetryCommand ||
+	   CommandType == DAC960_WriteRetryCommand)
     {
-      if (Controller->NewEventLogSequenceNumber
-	  - Controller->OldEventLogSequenceNumber > 0)
+      BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
+      BufferHeader->b_reqnext = NULL;
+      /*
+	Perform completion processing for this single buffer.
+      */
+      if (CommandStatus == DAC960_V2_NormalCompletion)
+	DAC960_ProcessCompletedBuffer(BufferHeader, true);
+      else
 	{
-	  Command->CommandMailbox.Type3E.CommandOpcode =
-	    DAC960_PerformEventLogOperation;
-	  Command->CommandMailbox.Type3E.OperationType =
-	    DAC960_GetEventLogEntry;
-	  Command->CommandMailbox.Type3E.OperationQualifier = 1;
-	  Command->CommandMailbox.Type3E.SequenceNumber =
-	    Controller->OldEventLogSequenceNumber;
-	  Command->CommandMailbox.Type3E.BusAddress =
-	    Virtual_to_Bus(&Controller->EventLogEntry);
-	  DAC960_QueueCommand(Command);
-	  return;
+	  if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
+	    DAC960_V2_ReadWriteError(Command);
+	  DAC960_ProcessCompletedBuffer(BufferHeader, false);
 	}
-      if (Controller->NeedErrorTableInformation)
+      if (NextBufferHeader != NULL)
 	{
-	  Controller->NeedErrorTableInformation = false;
-	  Command->CommandMailbox.Type3.CommandOpcode = DAC960_GetErrorTable;
-	  Command->CommandMailbox.Type3.BusAddress =
-	    Virtual_to_Bus(
-	      &Controller->ErrorTable[Controller->ErrorTableIndex ^ 1]);
-	  DAC960_QueueCommand(Command);
-	  return;
-	}
-      if (Controller->NeedRebuildProgress && 
-	  Controller->Enquiry[Controller->EnquiryIndex]
-		      .CriticalLogicalDriveCount <
-	  Controller->Enquiry[Controller->EnquiryIndex ^ 1]
-		      .CriticalLogicalDriveCount)
-	{
-	  Controller->NeedRebuildProgress = false;
-	  Command->CommandMailbox.Type3.CommandOpcode =
-	    DAC960_GetRebuildProgress;
-	  Command->CommandMailbox.Type3.BusAddress =
-	    Virtual_to_Bus(&Controller->RebuildProgress);
+	  Command->BlockNumber +=
+	    BufferHeader->b_size >> DAC960_BlockSizeBits;
+	  Command->BlockCount =
+	    NextBufferHeader->b_size >> DAC960_BlockSizeBits;
+	  Command->BufferHeader = NextBufferHeader;
+	  CommandMailbox->SCSI_10.DataTransferSize =
+	    Command->BlockCount << DAC960_BlockSizeBits;
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				 .ScatterGatherSegments[0]
+				 .SegmentDataPointer =
+	    Virtual_to_Bus(NextBufferHeader->b_data);
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				 .ScatterGatherSegments[0]
+				 .SegmentByteCount =
+	    CommandMailbox->SCSI_10.DataTransferSize;
+	  CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
+	  CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
+	  CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
+	  CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
+	  CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
+	  CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
 	  DAC960_QueueCommand(Command);
 	  return;
 	}
-      if (Controller->NeedDeviceStateInformation)
+    }
+  else if (CommandType == DAC960_MonitoringCommand)
+    {
+      if (CommandOpcode == DAC960_V2_GetControllerInfo)
 	{
-	  if (Controller->NeedDeviceInquiryInformation)
+	  DAC960_V2_ControllerInfo_T *NewControllerInfo =
+	    &Controller->V2.NewControllerInformation;
+	  DAC960_V2_ControllerInfo_T *ControllerInfo =
+	    &Controller->V2.ControllerInformation;
+	  Controller->LogicalDriveCount =
+	    NewControllerInfo->LogicalDevicesPresent;
+	  Controller->V2.NeedLogicalDeviceInformation = true;
+	  Controller->V2.NewLogicalDeviceInformation.LogicalDeviceNumber = 0;
+	  Controller->V2.NeedPhysicalDeviceInformation = true;
+	  Controller->V2.PhysicalDeviceIndex = 0;
+	  Controller->V2.NewPhysicalDeviceInformation.Channel = 0;
+	  Controller->V2.NewPhysicalDeviceInformation.TargetID = 0;
+	  Controller->V2.NewPhysicalDeviceInformation.LogicalUnit = 0;
+	  Controller->MonitoringAlertMode =
+	    (NewControllerInfo->LogicalDevicesCritical > 0 ||
+	     NewControllerInfo->LogicalDevicesOffline > 0 ||
+	     NewControllerInfo->PhysicalDisksCritical > 0 ||
+	     NewControllerInfo->PhysicalDisksOffline > 0);
+	  memcpy(ControllerInfo, NewControllerInfo,
+		 sizeof(DAC960_V2_ControllerInfo_T));
+	}
+      else if (CommandOpcode == DAC960_V2_GetEvent)
+	{
+	  if (CommandStatus == DAC960_V2_NormalCompletion)
+	    DAC960_V2_ReportEvent(Controller, &Controller->V2.Event);
+	  Controller->V2.NextEventSequenceNumber++;
+	}
+      else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid &&
+	       CommandStatus == DAC960_V2_NormalCompletion)
+	{
+	  DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
+	    &Controller->V2.NewPhysicalDeviceInformation;
+	  unsigned int PhysicalDeviceIndex = Controller->V2.PhysicalDeviceIndex;
+	  DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
+	    Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
+	  DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber;
+	  if (PhysicalDeviceInfo == NULL ||
+	      (NewPhysicalDeviceInfo->Channel !=
+	       PhysicalDeviceInfo->Channel) ||
+	      (NewPhysicalDeviceInfo->TargetID !=
+	       PhysicalDeviceInfo->TargetID) ||
+	      (NewPhysicalDeviceInfo->LogicalUnit !=
+	       PhysicalDeviceInfo->LogicalUnit))
 	    {
-	      DAC960_DCDB_T *DCDB = &Controller->MonitoringDCDB;
-	      DAC960_SCSI_Inquiry_T *InquiryStandardData =
-		&Controller->InquiryStandardData
-			       [Controller->DeviceStateChannel]
-			       [Controller->DeviceStateTargetID];
-	      InquiryStandardData->PeripheralDeviceType = 0x1F;
-	      Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
-	      Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
-	      DCDB->Channel = Controller->DeviceStateChannel;
-	      DCDB->TargetID = Controller->DeviceStateTargetID;
-	      DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
-	      DCDB->EarlyStatus = false;
-	      DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
-	      DCDB->NoAutomaticRequestSense = false;
-	      DCDB->DisconnectPermitted = true;
-	      DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
-	      DCDB->BusAddress = Virtual_to_Bus(InquiryStandardData);
-	      DCDB->CDBLength = 6;
-	      DCDB->TransferLengthHigh4 = 0;
-	      DCDB->SenseLength = sizeof(DCDB->SenseData);
-	      DCDB->CDB[0] = 0x12; /* INQUIRY */
-	      DCDB->CDB[1] = 0; /* EVPD = 0 */
-	      DCDB->CDB[2] = 0; /* Page Code */
-	      DCDB->CDB[3] = 0; /* Reserved */
-	      DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
-	      DCDB->CDB[5] = 0; /* Control */
-	      DAC960_QueueCommand(Command);
-	      Controller->NeedDeviceInquiryInformation = false;
-	      return;
+	      unsigned int DeviceIndex;
+	      PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
+		kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
+	      InquiryUnitSerialNumber =
+		(DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
+		  kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T),
+			  GFP_ATOMIC);
+	      if (InquiryUnitSerialNumber == NULL)
+		{
+		  kfree(PhysicalDeviceInfo);
+		  PhysicalDeviceInfo = NULL;
+		}
+	      DAC960_Critical("Physical Device %d:%d Now Exists%s\n",
+			      Controller,
+			      NewPhysicalDeviceInfo->Channel,
+			      NewPhysicalDeviceInfo->TargetID,
+			      (PhysicalDeviceInfo != NULL
+			       ? "" : " - Allocation Failed"));
+	      if (PhysicalDeviceInfo != NULL)
+		{
+		  for (DeviceIndex = PhysicalDeviceIndex;
+		       DeviceIndex < DAC960_V2_MaxPhysicalDevices - 1;
+		       DeviceIndex++)
+		    {
+		      Controller->V2.PhysicalDeviceInformation[DeviceIndex+1] =
+			Controller->V2.PhysicalDeviceInformation[DeviceIndex];
+		      Controller->V2.InquiryUnitSerialNumber[DeviceIndex+1] =
+			Controller->V2.InquiryUnitSerialNumber[DeviceIndex];
+		      Controller->V2.PhysicalDeviceInformation
+				     [PhysicalDeviceIndex] =
+			PhysicalDeviceInfo;
+		      Controller->V2.InquiryUnitSerialNumber
+				     [PhysicalDeviceIndex] =
+			InquiryUnitSerialNumber;
+		    }
+		  memset(PhysicalDeviceInfo, 0,
+			 sizeof(DAC960_V2_PhysicalDeviceInfo_T));
+		  PhysicalDeviceInfo->PhysicalDeviceState =
+		    DAC960_V2_Device_InvalidState;
+		  memset(InquiryUnitSerialNumber, 0,
+			 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
+		  InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+		  Controller->V2.NeedDeviceSerialNumberInformation = true;
+		}
 	    }
-	  if (Controller->NeedDeviceSerialNumberInformation)
+	  if (PhysicalDeviceInfo != NULL)
 	    {
-	      DAC960_DCDB_T *DCDB = &Controller->MonitoringDCDB;
-	      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
-		&Controller->InquiryUnitSerialNumber
-			       [Controller->DeviceStateChannel]
-			       [Controller->DeviceStateTargetID];
-	      InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
-	      Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
-	      Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
-	      DCDB->Channel = Controller->DeviceStateChannel;
-	      DCDB->TargetID = Controller->DeviceStateTargetID;
-	      DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
-	      DCDB->EarlyStatus = false;
-	      DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
-	      DCDB->NoAutomaticRequestSense = false;
-	      DCDB->DisconnectPermitted = true;
-	      DCDB->TransferLength =
-		sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
-	      DCDB->BusAddress = Virtual_to_Bus(InquiryUnitSerialNumber);
-	      DCDB->CDBLength = 6;
-	      DCDB->TransferLengthHigh4 = 0;
-	      DCDB->SenseLength = sizeof(DCDB->SenseData);
-	      DCDB->CDB[0] = 0x12; /* INQUIRY */
-	      DCDB->CDB[1] = 1; /* EVPD = 1 */
-	      DCDB->CDB[2] = 0x80; /* Page Code */
-	      DCDB->CDB[3] = 0; /* Reserved */
-	      DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
-	      DCDB->CDB[5] = 0; /* Control */
-	      DAC960_QueueCommand(Command);
-	      Controller->NeedDeviceSerialNumberInformation = false;
-	      return;
+	      if (NewPhysicalDeviceInfo->PhysicalDeviceState !=
+		  PhysicalDeviceInfo->PhysicalDeviceState)
+		DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
+				NewPhysicalDeviceInfo->Channel,
+				NewPhysicalDeviceInfo->TargetID,
+				(NewPhysicalDeviceInfo->PhysicalDeviceState
+				 == DAC960_V2_Device_Unconfigured
+				 ? "UNCONFIGURED"
+				 : NewPhysicalDeviceInfo->PhysicalDeviceState
+				   == DAC960_V2_Device_Online
+				   ? "ONLINE"
+				   : NewPhysicalDeviceInfo->PhysicalDeviceState
+				     == DAC960_V2_Device_WriteOnly
+				     ? "WRITE-ONLY"
+				     : NewPhysicalDeviceInfo
+				       ->PhysicalDeviceState
+				       == DAC960_V2_Device_Dead
+				       ? "DEAD" : "STANDBY"));
+	      if ((NewPhysicalDeviceInfo->ParityErrors !=
+		   PhysicalDeviceInfo->ParityErrors) ||
+		  (NewPhysicalDeviceInfo->SoftErrors !=
+		   PhysicalDeviceInfo->SoftErrors) ||
+		  (NewPhysicalDeviceInfo->HardErrors !=
+		   PhysicalDeviceInfo->HardErrors) ||
+		  (NewPhysicalDeviceInfo->MiscellaneousErrors !=
+		   PhysicalDeviceInfo->MiscellaneousErrors) ||
+		  (NewPhysicalDeviceInfo->CommandTimeouts !=
+		   PhysicalDeviceInfo->CommandTimeouts) ||
+		  (NewPhysicalDeviceInfo->Retries !=
+		   PhysicalDeviceInfo->Retries) ||
+		  (NewPhysicalDeviceInfo->Aborts !=
+		   PhysicalDeviceInfo->Aborts) ||
+		  (NewPhysicalDeviceInfo->PredictedFailuresDetected !=
+		   PhysicalDeviceInfo->PredictedFailuresDetected))
+		{
+		  DAC960_Critical("Physical Device %d:%d Errors: "
+				  "Parity = %d, Soft = %d, "
+				  "Hard = %d, Misc = %d\n",
+				  Controller,
+				  NewPhysicalDeviceInfo->Channel,
+				  NewPhysicalDeviceInfo->TargetID,
+				  NewPhysicalDeviceInfo->ParityErrors,
+				  NewPhysicalDeviceInfo->SoftErrors,
+				  NewPhysicalDeviceInfo->HardErrors,
+				  NewPhysicalDeviceInfo->MiscellaneousErrors);
+		  DAC960_Critical("Physical Device %d:%d Errors: "
+				  "Timeouts = %d, Retries = %d, "
+				  "Aborts = %d, Predicted = %d\n",
+				  Controller,
+				  NewPhysicalDeviceInfo->Channel,
+				  NewPhysicalDeviceInfo->TargetID,
+				  NewPhysicalDeviceInfo->CommandTimeouts,
+				  NewPhysicalDeviceInfo->Retries,
+				  NewPhysicalDeviceInfo->Aborts,
+				  NewPhysicalDeviceInfo
+				  ->PredictedFailuresDetected);
+		}
+	      if (PhysicalDeviceInfo->PhysicalDeviceState
+		  == DAC960_V2_Device_Dead &&
+		  NewPhysicalDeviceInfo->PhysicalDeviceState
+		  != DAC960_V2_Device_Dead)
+		Controller->V2.NeedDeviceSerialNumberInformation = true;
+	      memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
+		     sizeof(DAC960_V2_PhysicalDeviceInfo_T));
 	    }
-	  if (++Controller->DeviceStateTargetID == DAC960_MaxTargets)
+	  NewPhysicalDeviceInfo->LogicalUnit++;
+	  Controller->V2.PhysicalDeviceIndex++;
+	}
+      else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid)
+	Controller->V2.NeedPhysicalDeviceInformation = false;
+      else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid &&
+	       CommandStatus == DAC960_V2_NormalCompletion)
+	{
+	  DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
+	    &Controller->V2.NewLogicalDeviceInformation;
+	  unsigned short LogicalDeviceNumber =
+	    NewLogicalDeviceInfo->LogicalDeviceNumber;
+	  DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+	    Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber];
+	  if (LogicalDeviceInfo == NULL)
 	    {
-	      Controller->DeviceStateChannel++;
-	      Controller->DeviceStateTargetID = 0;
+	      DAC960_V2_PhysicalDevice_T PhysicalDevice;
+	      PhysicalDevice.Controller = 0;
+	      PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
+	      PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
+	      PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
+	      Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
+		PhysicalDevice;
+	      LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
+		kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
+	      Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
+		LogicalDeviceInfo;
+	      DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
+			      "Now Exists%s\n", Controller,
+			      LogicalDeviceNumber,
+			      Controller->ControllerNumber,
+			      LogicalDeviceNumber,
+			      (LogicalDeviceInfo != NULL
+			       ? "" : " - Allocation Failed"));
+	      if (LogicalDeviceInfo != NULL)
+		memset(LogicalDeviceInfo, 0,
+		       sizeof(DAC960_V2_LogicalDeviceInfo_T));
 	    }
-	  while (Controller->DeviceStateChannel < Controller->Channels)
+	  if (LogicalDeviceInfo != NULL)
 	    {
-	      DAC960_DeviceState_T *OldDeviceState =
-		&Controller->DeviceState[Controller->DeviceStateIndex]
-					[Controller->DeviceStateChannel]
-					[Controller->DeviceStateTargetID];
-	      if (OldDeviceState->Present &&
-		  OldDeviceState->DeviceType == DAC960_DiskType)
-		{
-		  Command->CommandMailbox.Type3D.CommandOpcode =
-		    DAC960_GetDeviceState;
-		  Command->CommandMailbox.Type3D.Channel =
-		    Controller->DeviceStateChannel;
-		  Command->CommandMailbox.Type3D.TargetID =
-		    Controller->DeviceStateTargetID;
-		  Command->CommandMailbox.Type3D.BusAddress =
-		    Virtual_to_Bus(&Controller->DeviceState
-				      [Controller->DeviceStateIndex ^ 1]
-				      [Controller->DeviceStateChannel]
-				      [Controller->DeviceStateTargetID]);
-		  DAC960_QueueCommand(Command);
-		  return;
-		}
-	      if (++Controller->DeviceStateTargetID == DAC960_MaxTargets)
-		{
-		  Controller->DeviceStateChannel++;
-		  Controller->DeviceStateTargetID = 0;
-		}
+	      unsigned long LogicalDeviceSize =
+		NewLogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB;
+	      if (NewLogicalDeviceInfo->LogicalDeviceState !=
+		  LogicalDeviceInfo->LogicalDeviceState)
+		DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
+				"is now %s\n", Controller,
+				LogicalDeviceNumber,
+				Controller->ControllerNumber,
+				LogicalDeviceNumber,
+				(NewLogicalDeviceInfo->LogicalDeviceState
+				 == DAC960_V2_LogicalDevice_Online
+				 ? "ONLINE"
+				 : NewLogicalDeviceInfo->LogicalDeviceState
+				   == DAC960_V2_LogicalDevice_Critical
+				   ? "CRITICAL" : "OFFLINE"));
+	      if ((NewLogicalDeviceInfo->SoftErrors !=
+		   LogicalDeviceInfo->SoftErrors) ||
+		  (NewLogicalDeviceInfo->CommandsFailed !=
+		   LogicalDeviceInfo->CommandsFailed) ||
+		  (NewLogicalDeviceInfo->DeferredWriteErrors !=
+		   LogicalDeviceInfo->DeferredWriteErrors))
+		DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) Errors: "
+				"Soft = %d, Failed = %d, Deferred Write = %d\n",
+				Controller, LogicalDeviceNumber,
+				Controller->ControllerNumber,
+				LogicalDeviceNumber,
+				NewLogicalDeviceInfo->SoftErrors,
+				NewLogicalDeviceInfo->CommandsFailed,
+				NewLogicalDeviceInfo->DeferredWriteErrors);
+	      if (NewLogicalDeviceInfo->ConsistencyCheckInProgress)
+		DAC960_V2_ReportProgress(Controller,
+					 "Consistency Check",
+					 LogicalDeviceNumber,
+					 NewLogicalDeviceInfo
+					 ->ConsistencyCheckBlockNumber,
+					 LogicalDeviceSize);
+	      else if (NewLogicalDeviceInfo->RebuildInProgress)
+		DAC960_V2_ReportProgress(Controller,
+					 "Rebuild",
+					 LogicalDeviceNumber,
+					 NewLogicalDeviceInfo
+					 ->RebuildBlockNumber,
+					 LogicalDeviceSize);
+	      else if (NewLogicalDeviceInfo->BackgroundInitializationInProgress)
+		DAC960_V2_ReportProgress(Controller,
+					 "BackgroundInitialization",
+					 LogicalDeviceNumber,
+					 NewLogicalDeviceInfo
+					 ->BackgroundInitializationBlockNumber,
+					 LogicalDeviceSize);
+	      else if (NewLogicalDeviceInfo->ForegroundInitializationInProgress)
+		DAC960_V2_ReportProgress(Controller,
+					 "Foreground Initialization",
+					 LogicalDeviceNumber,
+					 NewLogicalDeviceInfo
+					 ->ForegroundInitializationBlockNumber,
+					 LogicalDeviceSize);
+	      else if (NewLogicalDeviceInfo->DataMigrationInProgress)
+		DAC960_V2_ReportProgress(Controller,
+					 "Data Migration",
+					 LogicalDeviceNumber,
+					 NewLogicalDeviceInfo
+					 ->DataMigrationBlockNumber,
+					 LogicalDeviceSize);
+	      else if (NewLogicalDeviceInfo->PatrolOperationInProgress)
+		DAC960_V2_ReportProgress(Controller,
+					 "Patrol Operation",
+					 LogicalDeviceNumber,
+					 NewLogicalDeviceInfo
+					 ->PatrolOperationBlockNumber,
+					 LogicalDeviceSize);
+	      memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
+		     sizeof(DAC960_V2_LogicalDeviceInfo_T));
 	    }
-	  Controller->NeedDeviceStateInformation = false;
-	  Controller->DeviceStateIndex ^= 1;
+	  NewLogicalDeviceInfo->LogicalDeviceNumber++;
 	}
-      if (Controller->NeedLogicalDriveInformation)
-	{
-	  Controller->NeedLogicalDriveInformation = false;
-	  Command->CommandMailbox.Type3.CommandOpcode =
-	    DAC960_GetLogicalDriveInformation;
-	  Command->CommandMailbox.Type3.BusAddress =
-	    Virtual_to_Bus(
-	      &Controller->LogicalDriveInformation
-			   [Controller->LogicalDriveInformationIndex ^ 1]);
+      else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid)
+	Controller->V2.NeedLogicalDeviceInformation = false;
+      if (Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
+	  - Controller->V2.NextEventSequenceNumber > 0)
+	{
+	  CommandMailbox->GetEvent.CommandOpcode = DAC960_V2_IOCTL;
+	  CommandMailbox->GetEvent.DataTransferSize = sizeof(DAC960_V2_Event_T);
+	  CommandMailbox->GetEvent.EventSequenceNumberHigh16 =
+	    Controller->V2.NextEventSequenceNumber >> 16;
+	  CommandMailbox->GetEvent.ControllerNumber = 0;
+	  CommandMailbox->GetEvent.IOCTL_Opcode =
+	    DAC960_V2_GetEvent;
+	  CommandMailbox->GetEvent.EventSequenceNumberLow16 =
+	    Controller->V2.NextEventSequenceNumber & 0xFFFF;
+	  CommandMailbox->GetEvent.DataTransferMemoryAddress
+				  .ScatterGatherSegments[0]
+				  .SegmentDataPointer =
+	    Virtual_to_Bus(&Controller->V2.Event);
+	  CommandMailbox->GetEvent.DataTransferMemoryAddress
+				  .ScatterGatherSegments[0]
+				  .SegmentByteCount =
+	    CommandMailbox->GetEvent.DataTransferSize;
 	  DAC960_QueueCommand(Command);
 	  return;
 	}
-      if (Controller->NeedRebuildProgress)
+      if (Controller->V2.NeedPhysicalDeviceInformation)
 	{
-	  Controller->NeedRebuildProgress = false;
-	  Command->CommandMailbox.Type3.CommandOpcode =
-	    DAC960_GetRebuildProgress;
-	  Command->CommandMailbox.Type3.BusAddress =
-	    Virtual_to_Bus(&Controller->RebuildProgress);
+	  if (Controller->V2.NeedDeviceSerialNumberInformation)
+	    {
+	      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
+		Controller->V2.InquiryUnitSerialNumber
+			       [Controller->V2.PhysicalDeviceIndex - 1];
+	      InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+	      CommandMailbox->SCSI_10.CommandOpcode =
+		DAC960_V2_SCSI_10_Passthru;
+	      CommandMailbox->SCSI_10.DataTransferSize =
+		sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+	      CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit =
+		Controller->V2.NewPhysicalDeviceInformation.LogicalUnit - 1;
+	      CommandMailbox->SCSI_10.PhysicalDevice.TargetID =
+		Controller->V2.NewPhysicalDeviceInformation.TargetID;
+	      CommandMailbox->SCSI_10.PhysicalDevice.Channel =
+		Controller->V2.NewPhysicalDeviceInformation.Channel;
+	      CommandMailbox->SCSI_10.CDBLength = 6;
+	      CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
+	      CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
+	      CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
+	      CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
+	      CommandMailbox->SCSI_10.SCSI_CDB[4] =
+		sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+	      CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
+	      CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				     .ScatterGatherSegments[0]
+				     .SegmentDataPointer =
+		Virtual_to_Bus(InquiryUnitSerialNumber);
+	      CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				     .ScatterGatherSegments[0]
+				     .SegmentByteCount =
+		CommandMailbox->SCSI_10.DataTransferSize;
+	      DAC960_QueueCommand(Command);
+	      Controller->V2.NeedDeviceSerialNumberInformation = false;
+	      return;
+	    }
+	  CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+	  CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
+	    sizeof(DAC960_V2_PhysicalDeviceInfo_T);
+	  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit =
+	    Controller->V2.NewPhysicalDeviceInformation.LogicalUnit;
+	  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID =
+	    Controller->V2.NewPhysicalDeviceInformation.TargetID;
+	  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel =
+	    Controller->V2.NewPhysicalDeviceInformation.Channel;
+	  CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
+	    DAC960_V2_GetPhysicalDeviceInfoValid;
+	  CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
+					    .ScatterGatherSegments[0]
+					    .SegmentDataPointer =
+	    Virtual_to_Bus(&Controller->V2.NewPhysicalDeviceInformation);
+	  CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
+					    .ScatterGatherSegments[0]
+					    .SegmentByteCount =
+	    CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
 	  DAC960_QueueCommand(Command);
 	  return;
 	}
-      if (Controller->NeedConsistencyCheckProgress)
+      if (Controller->V2.NeedLogicalDeviceInformation)
 	{
-	  Controller->NeedConsistencyCheckProgress = false;
-	  Command->CommandMailbox.Type3.CommandOpcode = DAC960_RebuildStat;
-	  Command->CommandMailbox.Type3.BusAddress =
-	    Virtual_to_Bus(&Controller->RebuildProgress);
+	  CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+	  CommandMailbox->LogicalDeviceInfo.DataTransferSize =
+	    sizeof(DAC960_V2_LogicalDeviceInfo_T);
+	  CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
+	    Controller->V2.NewLogicalDeviceInformation.LogicalDeviceNumber;
+	  CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
+	    DAC960_V2_GetLogicalDeviceInfoValid;
+	  CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
+					   .ScatterGatherSegments[0]
+					   .SegmentDataPointer =
+	    Virtual_to_Bus(&Controller->V2.NewLogicalDeviceInformation);
+	  CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
+					   .ScatterGatherSegments[0]
+					   .SegmentByteCount =
+	    CommandMailbox->LogicalDeviceInfo.DataTransferSize;
 	  DAC960_QueueCommand(Command);
 	  return;
 	}
       Controller->MonitoringTimerCount++;
       Controller->MonitoringTimer.expires =
-	jiffies + DAC960_MonitoringTimerInterval;
+	jiffies + DAC960_HealthStatusMonitoringInterval;
       add_timer(&Controller->MonitoringTimer);
     }
   if (CommandType == DAC960_ImmediateCommand)
@@ -2406,12 +4514,11 @@
     }
   if (CommandType == DAC960_QueuedCommand)
     {
-      DAC960_KernelCommand_T *KernelCommand = Command->KernelCommand;
-      KernelCommand->CommandStatus = Command->CommandStatus;
-      Command->KernelCommand = NULL;
-      if (CommandOpcode == DAC960_DCDB)
-	Controller->DirectCommandActive[KernelCommand->DCDB->Channel]
-				       [KernelCommand->DCDB->TargetID] = false;
+      DAC960_V2_KernelCommand_T *KernelCommand = Command->V2.KernelCommand;
+      KernelCommand->CommandStatus = CommandStatus;
+      KernelCommand->RequestSenseLength = Command->V2.RequestSenseLength;
+      KernelCommand->DataTransferLength = Command->V2.DataTransferResidue;
+      Command->V2.KernelCommand = NULL;
       DAC960_DeallocateCommand(Command);
       KernelCommand->CompletionFunction(KernelCommand);
       return;
@@ -2424,7 +4531,7 @@
   if (Controller->MonitoringCommandDeferred)
     {
       Controller->MonitoringCommandDeferred = false;
-      DAC960_QueueMonitoringCommand(Command);
+      DAC960_V2_QueueMonitoringCommand(Command);
       return;
     }
   /*
@@ -2439,16 +4546,163 @@
 
 
 /*
-  DAC960_InterruptHandler handles hardware interrupts from DAC960 Controllers.
+  DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series
+  Controllers.
+*/
+
+static void DAC960_BA_InterruptHandler(int IRQ_Channel,
+				       void *DeviceIdentifier,
+				       Registers_T *InterruptRegisters)
+{
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V2_StatusMailbox_T *NextStatusMailbox;
+  ProcessorFlags_T ProcessorFlags;
+  /*
+    Acquire exclusive access to Controller.
+  */
+  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
+  /*
+    Process Hardware Interrupts for Controller.
+  */
+  DAC960_BA_AcknowledgeInterrupt(ControllerBaseAddress);
+  NextStatusMailbox = Controller->V2.NextStatusMailbox;
+  while (NextStatusMailbox->Fields.CommandIdentifier > 0)
+    {
+      DAC960_V2_CommandIdentifier_T CommandIdentifier =
+	NextStatusMailbox->Fields.CommandIdentifier;
+      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+      Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+      Command->V2.RequestSenseLength =
+	NextStatusMailbox->Fields.RequestSenseLength;
+      Command->V2.DataTransferResidue =
+	NextStatusMailbox->Fields.DataTransferResidue;
+      NextStatusMailbox->Words[0] = 0;
+      if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
+	NextStatusMailbox = Controller->V2.FirstStatusMailbox;
+      DAC960_V2_ProcessCompletedCommand(Command);
+    }
+  Controller->V2.NextStatusMailbox = NextStatusMailbox;
+  /*
+    Attempt to remove additional I/O Requests from the Controller's
+    I/O Request Queue and queue them to the Controller.
+  */
+  while (DAC960_ProcessRequest(Controller, false)) ;
+  /*
+    Release exclusive access to Controller.
+  */
+  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
+}
+
+
+/*
+  DAC960_LP_InterruptHandler handles hardware interrupts from DAC960 LP Series
+  Controllers.
+*/
+
+static void DAC960_LP_InterruptHandler(int IRQ_Channel,
+				       void *DeviceIdentifier,
+				       Registers_T *InterruptRegisters)
+{
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V2_StatusMailbox_T *NextStatusMailbox;
+  ProcessorFlags_T ProcessorFlags;
+  /*
+    Acquire exclusive access to Controller.
+  */
+  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
+  /*
+    Process Hardware Interrupts for Controller.
+  */
+  DAC960_LP_AcknowledgeInterrupt(ControllerBaseAddress);
+  NextStatusMailbox = Controller->V2.NextStatusMailbox;
+  while (NextStatusMailbox->Fields.CommandIdentifier > 0)
+    {
+      DAC960_V2_CommandIdentifier_T CommandIdentifier =
+	NextStatusMailbox->Fields.CommandIdentifier;
+      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+      Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+      Command->V2.RequestSenseLength =
+	NextStatusMailbox->Fields.RequestSenseLength;
+      Command->V2.DataTransferResidue =
+	NextStatusMailbox->Fields.DataTransferResidue;
+      NextStatusMailbox->Words[0] = 0;
+      if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
+	NextStatusMailbox = Controller->V2.FirstStatusMailbox;
+      DAC960_V2_ProcessCompletedCommand(Command);
+    }
+  Controller->V2.NextStatusMailbox = NextStatusMailbox;
+  /*
+    Attempt to remove additional I/O Requests from the Controller's
+    I/O Request Queue and queue them to the Controller.
+  */
+  while (DAC960_ProcessRequest(Controller, false)) ;
+  /*
+    Release exclusive access to Controller.
+  */
+  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
+}
+
+
+/*
+  DAC960_LA_InterruptHandler handles hardware interrupts from DAC960 LA Series
+  Controllers.
+*/
+
+static void DAC960_LA_InterruptHandler(int IRQ_Channel,
+				       void *DeviceIdentifier,
+				       Registers_T *InterruptRegisters)
+{
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_StatusMailbox_T *NextStatusMailbox;
+  ProcessorFlags_T ProcessorFlags;
+  /*
+    Acquire exclusive access to Controller.
+  */
+  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
+  /*
+    Process Hardware Interrupts for Controller.
+  */
+  DAC960_LA_AcknowledgeInterrupt(ControllerBaseAddress);
+  NextStatusMailbox = Controller->V1.NextStatusMailbox;
+  while (NextStatusMailbox->Fields.Valid)
+    {
+      DAC960_V1_CommandIdentifier_T CommandIdentifier =
+	NextStatusMailbox->Fields.CommandIdentifier;
+      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+      Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+      NextStatusMailbox->Word = 0;
+      if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
+	NextStatusMailbox = Controller->V1.FirstStatusMailbox;
+      DAC960_V1_ProcessCompletedCommand(Command);
+    }
+  Controller->V1.NextStatusMailbox = NextStatusMailbox;
+  /*
+    Attempt to remove additional I/O Requests from the Controller's
+    I/O Request Queue and queue them to the Controller.
+  */
+  while (DAC960_ProcessRequest(Controller, false)) ;
+  /*
+    Release exclusive access to Controller.
+  */
+  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
+}
+
+
+/*
+  DAC960_PG_InterruptHandler handles hardware interrupts from DAC960 PG Series
+  Controllers.
 */
 
-static void DAC960_InterruptHandler(int IRQ_Channel,
-				    void *DeviceIdentifier,
-				    Registers_T *InterruptRegisters)
+static void DAC960_PG_InterruptHandler(int IRQ_Channel,
+				       void *DeviceIdentifier,
+				       Registers_T *InterruptRegisters)
 {
   DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
   void *ControllerBaseAddress = Controller->BaseAddress;
-  DAC960_StatusMailbox_T *NextStatusMailbox;
+  DAC960_V1_StatusMailbox_T *NextStatusMailbox;
   ProcessorFlags_T ProcessorFlags;
   /*
     Acquire exclusive access to Controller.
@@ -2457,53 +4711,61 @@
   /*
     Process Hardware Interrupts for Controller.
   */
-  switch (Controller->ControllerType)
+  DAC960_PG_AcknowledgeInterrupt(ControllerBaseAddress);
+  NextStatusMailbox = Controller->V1.NextStatusMailbox;
+  while (NextStatusMailbox->Fields.Valid)
+    {
+      DAC960_V1_CommandIdentifier_T CommandIdentifier =
+	NextStatusMailbox->Fields.CommandIdentifier;
+      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+      Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+      NextStatusMailbox->Word = 0;
+      if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
+	NextStatusMailbox = Controller->V1.FirstStatusMailbox;
+      DAC960_V1_ProcessCompletedCommand(Command);
+    }
+  Controller->V1.NextStatusMailbox = NextStatusMailbox;
+  /*
+    Attempt to remove additional I/O Requests from the Controller's
+    I/O Request Queue and queue them to the Controller.
+  */
+  while (DAC960_ProcessRequest(Controller, false)) ;
+  /*
+    Release exclusive access to Controller.
+  */
+  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
+}
+
+
+/*
+  DAC960_PD_InterruptHandler handles hardware interrupts from DAC960 PD Series
+  Controllers.
+*/
+
+static void DAC960_PD_InterruptHandler(int IRQ_Channel,
+				       void *DeviceIdentifier,
+				       Registers_T *InterruptRegisters)
+{
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  ProcessorFlags_T ProcessorFlags;
+  /*
+    Acquire exclusive access to Controller.
+  */
+  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
+  /*
+    Process Hardware Interrupts for Controller.
+  */
+  while (DAC960_PD_StatusAvailableP(ControllerBaseAddress))
     {
-    case DAC960_V5_Controller:
-      DAC960_V5_AcknowledgeInterrupt(ControllerBaseAddress);
-      NextStatusMailbox = Controller->NextStatusMailbox;
-      while (NextStatusMailbox->Fields.Valid)
-	{
-	  DAC960_CommandIdentifier_T CommandIdentifier =
-	    NextStatusMailbox->Fields.CommandIdentifier;
-	  DAC960_Command_T *Command = &Controller->Commands[CommandIdentifier];
-	  Command->CommandStatus = NextStatusMailbox->Fields.CommandStatus;
-	  NextStatusMailbox->Word = 0;
-	  if (++NextStatusMailbox > Controller->LastStatusMailbox)
-	    NextStatusMailbox = Controller->FirstStatusMailbox;
-	  DAC960_ProcessCompletedCommand(Command);
-	}
-      Controller->NextStatusMailbox = NextStatusMailbox;
-      break;
-    case DAC960_V4_Controller:
-      DAC960_V4_AcknowledgeInterrupt(ControllerBaseAddress);
-      NextStatusMailbox = Controller->NextStatusMailbox;
-      while (NextStatusMailbox->Fields.Valid)
-	{
-	  DAC960_CommandIdentifier_T CommandIdentifier =
-	    NextStatusMailbox->Fields.CommandIdentifier;
-	  DAC960_Command_T *Command = &Controller->Commands[CommandIdentifier];
-	  Command->CommandStatus = NextStatusMailbox->Fields.CommandStatus;
-	  NextStatusMailbox->Word = 0;
-	  if (++NextStatusMailbox > Controller->LastStatusMailbox)
-	    NextStatusMailbox = Controller->FirstStatusMailbox;
-	  DAC960_ProcessCompletedCommand(Command);
-	}
-      Controller->NextStatusMailbox = NextStatusMailbox;
-      break;
-    case DAC960_V3_Controller:
-      while (DAC960_V3_StatusAvailableP(ControllerBaseAddress))
-	{
-	  DAC960_CommandIdentifier_T CommandIdentifier =
-	    DAC960_V3_ReadStatusCommandIdentifier(ControllerBaseAddress);
-	  DAC960_Command_T *Command = &Controller->Commands[CommandIdentifier];
-	  Command->CommandStatus =
-	    DAC960_V3_ReadStatusRegister(ControllerBaseAddress);
-	  DAC960_V3_AcknowledgeInterrupt(ControllerBaseAddress);
-	  DAC960_V3_AcknowledgeStatus(ControllerBaseAddress);
-	  DAC960_ProcessCompletedCommand(Command);
-	}
-      break;
+      DAC960_V1_CommandIdentifier_T CommandIdentifier =
+	DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress);
+      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+      Command->V1.CommandStatus =
+	DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
+      DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
+      DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
+      DAC960_V1_ProcessCompletedCommand(Command);
     }
   /*
     Attempt to remove additional I/O Requests from the Controller's
@@ -2518,18 +4780,50 @@
 
 
 /*
-  DAC960_QueueMonitoringCommand queues a Monitoring Command to Controller.
+  DAC960_V1_QueueMonitoringCommand queues a Monitoring Command to DAC960 V1
+  Firmware Controllers.
+*/
+
+static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_ClearCommand(Command);
+  Command->CommandType = DAC960_MonitoringCommand;
+  CommandMailbox->Type3.CommandOpcode = DAC960_V1_Enquiry;
+  CommandMailbox->Type3.BusAddress = Virtual_to_Bus(&Controller->V1.NewEnquiry);
+  DAC960_QueueCommand(Command);
+}
+
+
+/*
+  DAC960_V2_QueueMonitoringCommand queues a Monitoring Command to DAC960 V2
+  Firmware Controllers.
 */
 
-static void DAC960_QueueMonitoringCommand(DAC960_Command_T *Command)
+static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *Command)
 {
   DAC960_Controller_T *Controller = Command->Controller;
-  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-  DAC960_ClearCommand(Command);
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_ClearCommand(Command);
   Command->CommandType = DAC960_MonitoringCommand;
-  CommandMailbox->Type3.CommandOpcode = DAC960_Enquiry;
-  CommandMailbox->Type3.BusAddress =
-    Virtual_to_Bus(&Controller->Enquiry[Controller->EnquiryIndex ^ 1]);
+  CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->ControllerInfo.CommandControlBits
+				.DataTransferControllerToHost = true;
+  CommandMailbox->ControllerInfo.CommandControlBits
+				.NoAutoRequestSense = true;
+  CommandMailbox->ControllerInfo.DataTransferSize =
+    sizeof(DAC960_V2_ControllerInfo_T);
+  CommandMailbox->ControllerInfo.ControllerNumber = 0;
+  CommandMailbox->ControllerInfo.IOCTL_Opcode = DAC960_V2_GetControllerInfo;
+  CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+				.ScatterGatherSegments[0]
+				.SegmentDataPointer =
+    Virtual_to_Bus(&Controller->V2.NewControllerInformation);
+  CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+				.ScatterGatherSegments[0]
+				.SegmentByteCount =
+    CommandMailbox->ControllerInfo.DataTransferSize;
   DAC960_QueueCommand(Command);
 }
 
@@ -2544,21 +4838,69 @@
   DAC960_Controller_T *Controller = (DAC960_Controller_T *) TimerData;
   DAC960_Command_T *Command;
   ProcessorFlags_T ProcessorFlags;
-  /*
-    Acquire exclusive access to Controller.
-  */
-  DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
-  /*
-    Queue a Status Monitoring Command to Controller.
-  */
-  Command = DAC960_AllocateCommand(Controller);
-  if (Command != NULL)
-    DAC960_QueueMonitoringCommand(Command);
-  else Controller->MonitoringCommandDeferred = true;
-  /*
-    Release exclusive access to Controller.
-  */
-  DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+    {
+      /*
+	Acquire exclusive access to Controller.
+      */
+      DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+      /*
+	Queue a Status Monitoring Command to Controller.
+      */
+      Command = DAC960_AllocateCommand(Controller);
+      if (Command != NULL)
+	DAC960_V1_QueueMonitoringCommand(Command);
+      else Controller->MonitoringCommandDeferred = true;
+      /*
+	Release exclusive access to Controller.
+      */
+      DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+    }
+  else
+    {
+      DAC960_V2_ControllerInfo_T *ControllerInfo =
+	&Controller->V2.ControllerInformation;
+      unsigned int StatusChangeCounter =
+	Controller->V2.HealthStatusBuffer->StatusChangeCounter;
+      if (StatusChangeCounter == Controller->V2.StatusChangeCounter &&
+	  Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
+	  == Controller->V2.NextEventSequenceNumber &&
+	  (ControllerInfo->BackgroundInitializationsActive +
+	   ControllerInfo->LogicalDeviceInitializationsActive +
+	   ControllerInfo->PhysicalDeviceInitializationsActive +
+	   ControllerInfo->ConsistencyChecksActive +
+	   ControllerInfo->RebuildsActive +
+	   ControllerInfo->OnlineExpansionsActive == 0 ||
+	   jiffies - Controller->PrimaryMonitoringTime
+	   < DAC960_MonitoringTimerInterval))
+	{
+	  Controller->MonitoringTimer.expires =
+	    jiffies + DAC960_HealthStatusMonitoringInterval;
+	  add_timer(&Controller->MonitoringTimer);
+	  return;
+	}
+      Controller->V2.StatusChangeCounter = StatusChangeCounter;
+      Controller->PrimaryMonitoringTime = jiffies;
+      /*
+	Acquire exclusive access to Controller.
+      */
+      DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+      /*
+	Queue a Status Monitoring Command to Controller.
+      */
+      Command = DAC960_AllocateCommand(Controller);
+      if (Command != NULL)
+	DAC960_V2_QueueMonitoringCommand(Command);
+      else Controller->MonitoringCommandDeferred = true;
+      /*
+	Release exclusive access to Controller.
+      */
+      DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+      /*
+	Wake up any processes waiting on a Health Status Buffer change.
+      */
+      wake_up(&Controller->HealthStatusWaitQueue);
+    }
 }
 
 
@@ -2577,19 +4919,28 @@
   if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
     return -ENXIO;
   Controller = DAC960_Controllers[ControllerNumber];
-  if (Controller == NULL ||
-      LogicalDriveNumber > Controller->LogicalDriveCount - 1)
-    return -ENXIO;
-  if (Controller->LogicalDriveInformation
-		  [Controller->LogicalDriveInformationIndex]
-		  [LogicalDriveNumber].LogicalDriveState
-      == DAC960_LogicalDrive_Offline)
-    return -ENXIO;
-  if (Controller->LogicalDriveInitialState[LogicalDriveNumber]
-      == DAC960_LogicalDrive_Offline)
+  if (Controller == NULL) return -ENXIO;
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+    {
+      if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
+	return -ENXIO;
+      if (Controller->V1.LogicalDriveInformation
+			 [LogicalDriveNumber].LogicalDriveState
+	  == DAC960_V1_LogicalDrive_Offline)
+	return -ENXIO;
+    }
+  else
+    {
+      DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+	Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+      if (LogicalDeviceInfo == NULL ||
+	  LogicalDeviceInfo->LogicalDeviceState
+	  == DAC960_V2_LogicalDevice_Offline)
+	return -ENXIO;
+    }
+  if (!Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber])
     {
-      Controller->LogicalDriveInitialState[LogicalDriveNumber] =
-	DAC960_LogicalDrive_Online;
+      Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
       DAC960_InitializeGenericDiskInfo(&Controller->GenericDiskInfo);
       resetup_one_dev(&Controller->GenericDiskInfo, LogicalDriveNumber);
     }
@@ -2650,25 +5001,51 @@
   if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
     return -ENXIO;
   Controller = DAC960_Controllers[ControllerNumber];
-  if (Controller == NULL ||
-      LogicalDriveNumber > Controller->LogicalDriveCount - 1)
-    return -ENXIO;
+  if (Controller == NULL) return -ENXIO;
   switch (Request)
     {
     case HDIO_GETGEO:
       /* Get BIOS Disk Geometry. */
       UserGeometry = (DiskGeometry_T *) Argument;
       if (UserGeometry == NULL) return -EINVAL;
-      Geometry.heads = Controller->GeometryTranslationHeads;
-      Geometry.sectors = Controller->GeometryTranslationSectors;
-      Geometry.cylinders =
-	Controller->LogicalDriveInformation
-		    [Controller->LogicalDriveInformationIndex]
-		    [LogicalDriveNumber].LogicalDriveSize
-	/ (Controller->GeometryTranslationHeads *
-	   Controller->GeometryTranslationSectors);
-      Geometry.start = Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)]
-						  .start_sect;
+      if (Controller->FirmwareType == DAC960_V1_Controller)
+	{
+	  if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
+	    return -ENXIO;
+	  Geometry.heads = Controller->V1.GeometryTranslationHeads;
+	  Geometry.sectors = Controller->V1.GeometryTranslationSectors;
+	  Geometry.cylinders =
+	    Controller->V1.LogicalDriveInformation[LogicalDriveNumber]
+						  .LogicalDriveSize
+	    / (Geometry.heads * Geometry.sectors);
+	}
+      else
+	{
+	  DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+	    Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+	  if (LogicalDeviceInfo == NULL)
+	    return -EINVAL;
+	  switch(LogicalDeviceInfo->DriveGeometry)
+	    {
+	    case DAC960_V2_Geometry_128_32:
+	      Geometry.heads = 128;
+	      Geometry.sectors = 32;
+	      break;
+	    case DAC960_V2_Geometry_255_63:
+	      Geometry.heads = 255;
+	      Geometry.sectors = 63;
+	      break;
+	    default:
+	      DAC960_Error("Illegal Logical Device Geometry %d\n",
+			   Controller, LogicalDeviceInfo->DriveGeometry);
+	      return -EINVAL;
+	    }
+	  Geometry.cylinders =
+	    LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB
+	    / (Geometry.heads * Geometry.sectors);
+	}
+      Geometry.start =
+	Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)].start_sect;
       return copy_to_user(UserGeometry, &Geometry, sizeof(DiskGeometry_T));
     case BLKGETSIZE:
       /* Get Device Size. */
@@ -2764,59 +5141,63 @@
 	    ControllerNumber > DAC960_ControllerCount - 1)
 	  return -ENXIO;
 	Controller = DAC960_Controllers[ControllerNumber];
-	if (Controller == NULL)
-	  return -ENXIO;
+	if (Controller == NULL) return -ENXIO;
 	memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
 	ControllerInfo.ControllerNumber = ControllerNumber;
+	ControllerInfo.FirmwareType = Controller->FirmwareType;
+	ControllerInfo.Channels = Controller->Channels;
+	ControllerInfo.Targets = Controller->Targets;
 	ControllerInfo.PCI_Bus = Controller->Bus;
 	ControllerInfo.PCI_Device = Controller->Device;
 	ControllerInfo.PCI_Function = Controller->Function;
 	ControllerInfo.IRQ_Channel = Controller->IRQ_Channel;
-	ControllerInfo.Channels = Controller->Channels;
 	ControllerInfo.PCI_Address = Controller->PCI_Address;
 	strcpy(ControllerInfo.ModelName, Controller->ModelName);
 	strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion);
 	return copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
 			    sizeof(DAC960_ControllerInfo_T));
       }
-    case DAC960_IOCTL_EXECUTE_COMMAND:
+    case DAC960_IOCTL_V1_EXECUTE_COMMAND:
       {
-	DAC960_UserCommand_T *UserSpaceUserCommand =
-	  (DAC960_UserCommand_T *) Argument;
-	DAC960_UserCommand_T UserCommand;
+	DAC960_V1_UserCommand_T *UserSpaceUserCommand =
+	  (DAC960_V1_UserCommand_T *) Argument;
+	DAC960_V1_UserCommand_T UserCommand;
 	DAC960_Controller_T *Controller;
 	DAC960_Command_T *Command = NULL;
-	DAC960_CommandOpcode_T CommandOpcode;
-	DAC960_CommandStatus_T CommandStatus;
-	DAC960_DCDB_T DCDB;
+	DAC960_V1_CommandOpcode_T CommandOpcode;
+	DAC960_V1_CommandStatus_T CommandStatus;
+	DAC960_V1_DCDB_T DCDB;
 	ProcessorFlags_T ProcessorFlags;
 	int ControllerNumber, DataTransferLength;
 	unsigned char *DataTransferBuffer = NULL;
 	if (UserSpaceUserCommand == NULL) return -EINVAL;
 	ErrorCode = copy_from_user(&UserCommand, UserSpaceUserCommand,
-				   sizeof(DAC960_UserCommand_T));
-	if (ErrorCode != 0) goto Failure;
+				   sizeof(DAC960_V1_UserCommand_T));
+	if (ErrorCode != 0) goto Failure1;
 	ControllerNumber = UserCommand.ControllerNumber;
 	if (ControllerNumber < 0 ||
 	    ControllerNumber > DAC960_ControllerCount - 1)
 	  return -ENXIO;
 	Controller = DAC960_Controllers[ControllerNumber];
-	if (Controller == NULL)
-	  return -ENXIO;
+	if (Controller == NULL) return -ENXIO;
+	if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
 	CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode;
 	DataTransferLength = UserCommand.DataTransferLength;
 	if (CommandOpcode & 0x80) return -EINVAL;
-	if (CommandOpcode == DAC960_DCDB)
+	if (CommandOpcode == DAC960_V1_DCDB)
 	  {
 	    ErrorCode =
-	      copy_from_user(&DCDB, UserCommand.DCDB, sizeof(DAC960_DCDB_T));
-	    if (ErrorCode != 0) goto Failure;
+	      copy_from_user(&DCDB, UserCommand.DCDB, sizeof(DAC960_V1_DCDB_T));
+	    if (ErrorCode != 0) goto Failure1;
 	    if (!((DataTransferLength == 0 &&
-		   DCDB.Direction == DAC960_DCDB_NoDataTransfer) ||
+		   DCDB.Direction
+		   == DAC960_V1_DCDB_NoDataTransfer) ||
 		  (DataTransferLength > 0 &&
-		   DCDB.Direction == DAC960_DCDB_DataTransferDeviceToSystem) ||
+		   DCDB.Direction
+		   == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
 		  (DataTransferLength < 0 &&
-		   DCDB.Direction == DAC960_DCDB_DataTransferSystemToDevice)))
+		   DCDB.Direction
+		   == DAC960_V1_DCDB_DataTransferSystemToDevice)))
 	      return -EINVAL;
 	    if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
 		!= abs(DataTransferLength))
@@ -2835,23 +5216,24 @@
 	    ErrorCode = copy_from_user(DataTransferBuffer,
 				       UserCommand.DataTransferBuffer,
 				       -DataTransferLength);
-	    if (ErrorCode != 0) goto Failure;
+	    if (ErrorCode != 0) goto Failure1;
 	  }
-	if (CommandOpcode == DAC960_DCDB)
+	if (CommandOpcode == DAC960_V1_DCDB)
 	  {
 	    DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
-	    while (Controller->DirectCommandActive[DCDB.Channel]
-						  [DCDB.TargetID] ||
+	    while (Controller->V1.DirectCommandActive[DCDB.Channel]
+						     [DCDB.TargetID] ||
 		   (Command = DAC960_AllocateCommand(Controller)) == NULL)
 	      DAC960_WaitForCommand(Controller);
-	    Controller->DirectCommandActive[DCDB.Channel]
-					   [DCDB.TargetID] = true;
+	    Controller->V1.DirectCommandActive[DCDB.Channel]
+					      [DCDB.TargetID] = true;
 	    DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
-	    DAC960_ClearCommand(Command);
+	    DAC960_V1_ClearCommand(Command);
 	    Command->CommandType = DAC960_ImmediateCommand;
-	    memcpy(&Command->CommandMailbox, &UserCommand.CommandMailbox,
-		   sizeof(DAC960_CommandMailbox_T));
-	    Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(&DCDB);
+	    memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
+		   sizeof(DAC960_V1_CommandMailbox_T));
+	    Command->V1.CommandMailbox.Type3.BusAddress =
+	      Virtual_to_Bus(&DCDB);
 	    DCDB.BusAddress = Virtual_to_Bus(DataTransferBuffer);
 	  }
 	else
@@ -2860,38 +5242,211 @@
 	    while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
 	      DAC960_WaitForCommand(Controller);
 	    DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
-	    DAC960_ClearCommand(Command);
+	    DAC960_V1_ClearCommand(Command);
 	    Command->CommandType = DAC960_ImmediateCommand;
-	    memcpy(&Command->CommandMailbox, &UserCommand.CommandMailbox,
-		   sizeof(DAC960_CommandMailbox_T));
+	    memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
+		   sizeof(DAC960_V1_CommandMailbox_T));
 	    if (DataTransferBuffer != NULL)
-	      Command->CommandMailbox.Type3.BusAddress =
+	      Command->V1.CommandMailbox.Type3.BusAddress =
 		Virtual_to_Bus(DataTransferBuffer);
 	  }
 	DAC960_ExecuteCommand(Command);
-	CommandStatus = Command->CommandStatus;
+	CommandStatus = Command->V1.CommandStatus;
 	DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
 	DAC960_DeallocateCommand(Command);
 	DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
-	if (CommandStatus == DAC960_NormalCompletion &&
-	    DataTransferLength > 0)
+	if (DataTransferLength > 0)
 	  {
 	    ErrorCode = copy_to_user(UserCommand.DataTransferBuffer,
 				     DataTransferBuffer, DataTransferLength);
-	    if (ErrorCode != 0) goto Failure;
+	    if (ErrorCode != 0) goto Failure1;
 	  }
-	if (CommandOpcode == DAC960_DCDB)
+	if (CommandOpcode == DAC960_V1_DCDB)
 	  {
-	    Controller->DirectCommandActive[DCDB.Channel]
-					   [DCDB.TargetID] = false;
+	    Controller->V1.DirectCommandActive[DCDB.Channel]
+					      [DCDB.TargetID] = false;
 	    ErrorCode =
-	      copy_to_user(UserCommand.DCDB, &DCDB, sizeof(DAC960_DCDB_T));
-	    if (ErrorCode != 0) goto Failure;
+	      copy_to_user(UserCommand.DCDB, &DCDB, sizeof(DAC960_V1_DCDB_T));
+	    if (ErrorCode != 0) goto Failure1;
+	  }
+	ErrorCode = CommandStatus;
+      Failure1:
+	if (DataTransferBuffer != NULL)
+	  kfree(DataTransferBuffer);
+	return ErrorCode;
+      }
+    case DAC960_IOCTL_V2_EXECUTE_COMMAND:
+      {
+	DAC960_V2_UserCommand_T *UserSpaceUserCommand =
+	  (DAC960_V2_UserCommand_T *) Argument;
+	DAC960_V2_UserCommand_T UserCommand;
+	DAC960_Controller_T *Controller;
+	DAC960_Command_T *Command = NULL;
+	DAC960_V2_CommandMailbox_T *CommandMailbox;
+	DAC960_V2_CommandStatus_T CommandStatus;
+	ProcessorFlags_T ProcessorFlags;
+	int ControllerNumber, DataTransferLength;
+	int DataTransferResidue, RequestSenseLength;
+	unsigned char *DataTransferBuffer = NULL;
+	unsigned char *RequestSenseBuffer = NULL;
+	if (UserSpaceUserCommand == NULL) return -EINVAL;
+	ErrorCode = copy_from_user(&UserCommand, UserSpaceUserCommand,
+				   sizeof(DAC960_V2_UserCommand_T));
+	if (ErrorCode != 0) goto Failure2;
+	ControllerNumber = UserCommand.ControllerNumber;
+	if (ControllerNumber < 0 ||
+	    ControllerNumber > DAC960_ControllerCount - 1)
+	  return -ENXIO;
+	Controller = DAC960_Controllers[ControllerNumber];
+	if (Controller == NULL) return -ENXIO;
+	if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
+	DataTransferLength = UserCommand.DataTransferLength;
+	if (DataTransferLength > 0)
+	  {
+	    DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
+	    if (DataTransferBuffer == NULL) return -ENOMEM;
+	    memset(DataTransferBuffer, 0, DataTransferLength);
+	  }
+	else if (DataTransferLength < 0)
+	  {
+	    DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
+	    if (DataTransferBuffer == NULL) return -ENOMEM;
+	    ErrorCode = copy_from_user(DataTransferBuffer,
+				       UserCommand.DataTransferBuffer,
+				       -DataTransferLength);
+	    if (ErrorCode != 0) goto Failure2;
+	  }
+	RequestSenseLength = UserCommand.RequestSenseLength;
+	if (RequestSenseLength > 0)
+	  {
+	    RequestSenseBuffer = kmalloc(RequestSenseLength, GFP_KERNEL);
+	    if (RequestSenseBuffer == NULL)
+	      {
+		ErrorCode = -ENOMEM;
+		goto Failure2;
+	      }
+	    memset(RequestSenseBuffer, 0, RequestSenseLength);
+	  }
+	DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+	while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
+	  DAC960_WaitForCommand(Controller);
+	DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+	DAC960_V2_ClearCommand(Command);
+	Command->CommandType = DAC960_ImmediateCommand;
+	CommandMailbox = &Command->V2.CommandMailbox;
+	memcpy(CommandMailbox, &UserCommand.CommandMailbox,
+	       sizeof(DAC960_V2_CommandMailbox_T));
+	CommandMailbox->Common.CommandControlBits
+			      .AdditionalScatterGatherListMemory = false;
+	CommandMailbox->Common.CommandControlBits
+			      .NoAutoRequestSense = true;
+	CommandMailbox->Common.DataTransferSize = 0;
+	CommandMailbox->Common.DataTransferPageNumber = 0;
+	memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
+	       sizeof(DAC960_V2_DataTransferMemoryAddress_T));
+	if (DataTransferLength != 0)
+	  {
+	    if (DataTransferLength > 0)
+	      {
+		CommandMailbox->Common.CommandControlBits
+				      .DataTransferControllerToHost = true;
+		CommandMailbox->Common.DataTransferSize = DataTransferLength;
+	      }
+	    else
+	      {
+		CommandMailbox->Common.CommandControlBits
+				      .DataTransferControllerToHost = false;
+		CommandMailbox->Common.DataTransferSize = -DataTransferLength;
+	      }
+	    CommandMailbox->Common.DataTransferMemoryAddress
+				  .ScatterGatherSegments[0]
+				  .SegmentDataPointer =
+	      Virtual_to_Bus(DataTransferBuffer);
+	    CommandMailbox->Common.DataTransferMemoryAddress
+				  .ScatterGatherSegments[0]
+				  .SegmentByteCount =
+	      CommandMailbox->Common.DataTransferSize;
+	  }
+	if (RequestSenseLength > 0)
+	  {
+	    CommandMailbox->Common.CommandControlBits
+				  .NoAutoRequestSense = false;
+	    CommandMailbox->Common.RequestSenseSize = RequestSenseLength;
+	    CommandMailbox->Common.RequestSenseBusAddress =
+	      Virtual_to_Bus(RequestSenseBuffer);
+	  }
+	DAC960_ExecuteCommand(Command);
+	CommandStatus = Command->V2.CommandStatus;
+	RequestSenseLength = Command->V2.RequestSenseLength;
+	DataTransferResidue = Command->V2.DataTransferResidue;
+	DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+	DAC960_DeallocateCommand(Command);
+	DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+	if (RequestSenseLength > UserCommand.RequestSenseLength)
+	  RequestSenseLength = UserCommand.RequestSenseLength;
+	ErrorCode = copy_to_user(&UserSpaceUserCommand->DataTransferLength,
+				 &DataTransferResidue,
+				 sizeof(DataTransferResidue));
+	if (ErrorCode != 0) goto Failure2;
+	ErrorCode = copy_to_user(&UserSpaceUserCommand->RequestSenseLength,
+				 &RequestSenseLength,
+				 sizeof(RequestSenseLength));
+	if (ErrorCode != 0) goto Failure2;
+	if (DataTransferLength > 0)
+	  {
+	    ErrorCode = copy_to_user(UserCommand.DataTransferBuffer,
+				     DataTransferBuffer, DataTransferLength);
+	    if (ErrorCode != 0) goto Failure2;
+	  }
+	if (RequestSenseLength > 0)
+	  {
+	    ErrorCode = copy_to_user(UserCommand.RequestSenseBuffer,
+				     RequestSenseBuffer, RequestSenseLength);
+	    if (ErrorCode != 0) goto Failure2;
 	  }
 	ErrorCode = CommandStatus;
-      Failure:
+      Failure2:
 	if (DataTransferBuffer != NULL)
 	  kfree(DataTransferBuffer);
+	if (RequestSenseBuffer != NULL)
+	  kfree(RequestSenseBuffer);
+	return ErrorCode;
+      }
+    case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
+      {
+	DAC960_V2_GetHealthStatus_T *UserSpaceGetHealthStatus =
+	  (DAC960_V2_GetHealthStatus_T *) Argument;
+	DAC960_V2_GetHealthStatus_T GetHealthStatus;
+	DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
+	DAC960_Controller_T *Controller;
+	int ControllerNumber;
+	if (UserSpaceGetHealthStatus == NULL) return -EINVAL;
+	ErrorCode = copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus,
+				   sizeof(DAC960_V2_GetHealthStatus_T));
+	if (ErrorCode != 0) return ErrorCode;
+	ControllerNumber = GetHealthStatus.ControllerNumber;
+	if (ControllerNumber < 0 ||
+	    ControllerNumber > DAC960_ControllerCount - 1)
+	  return -ENXIO;
+	Controller = DAC960_Controllers[ControllerNumber];
+	if (Controller == NULL) return -ENXIO;
+	if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
+	ErrorCode = copy_from_user(&HealthStatusBuffer,
+				   GetHealthStatus.HealthStatusBuffer,
+				   sizeof(DAC960_V2_HealthStatusBuffer_T));
+	if (ErrorCode != 0) return ErrorCode;
+	while (Controller->V2.HealthStatusBuffer->StatusChangeCounter
+	       == HealthStatusBuffer.StatusChangeCounter &&
+	       Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
+	       == HealthStatusBuffer.NextEventSequenceNumber)
+	  {
+	    interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue,
+					   DAC960_MonitoringTimerInterval);
+	    if (signal_pending(current)) return -EINTR;
+	  }
+	ErrorCode = copy_to_user(GetHealthStatus.HealthStatusBuffer,
+				 Controller->V2.HealthStatusBuffer,
+				 sizeof(DAC960_V2_HealthStatusBuffer_T));
 	return ErrorCode;
       }
     }
@@ -2921,28 +5476,29 @@
 	    ControllerNumber > DAC960_ControllerCount - 1)
 	  return -ENXIO;
 	Controller = DAC960_Controllers[ControllerNumber];
-	if (Controller == NULL)
-	  return -ENXIO;
+	if (Controller == NULL) return -ENXIO;
 	memset(ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
 	ControllerInfo->ControllerNumber = ControllerNumber;
+	ControllerInfo->FirmwareType = Controller->FirmwareType;
+	ControllerInfo->Channels = Controller->Channels;
+	ControllerInfo->Targets = Controller->Targets;
 	ControllerInfo->PCI_Bus = Controller->Bus;
 	ControllerInfo->PCI_Device = Controller->Device;
 	ControllerInfo->PCI_Function = Controller->Function;
 	ControllerInfo->IRQ_Channel = Controller->IRQ_Channel;
-	ControllerInfo->Channels = Controller->Channels;
 	ControllerInfo->PCI_Address = Controller->PCI_Address;
 	strcpy(ControllerInfo->ModelName, Controller->ModelName);
 	strcpy(ControllerInfo->FirmwareVersion, Controller->FirmwareVersion);
 	return 0;
       }
-    case DAC960_IOCTL_EXECUTE_COMMAND:
+    case DAC960_IOCTL_V1_EXECUTE_COMMAND:
       {
-	DAC960_KernelCommand_T *KernelCommand =
-	  (DAC960_KernelCommand_T *) Argument;
+	DAC960_V1_KernelCommand_T *KernelCommand =
+	  (DAC960_V1_KernelCommand_T *) Argument;
 	DAC960_Controller_T *Controller;
 	DAC960_Command_T *Command = NULL;
-	DAC960_CommandOpcode_T CommandOpcode;
-	DAC960_DCDB_T *DCDB = NULL;
+	DAC960_V1_CommandOpcode_T CommandOpcode;
+	DAC960_V1_DCDB_T *DCDB = NULL;
 	ProcessorFlags_T ProcessorFlags;
 	int ControllerNumber, DataTransferLength;
 	unsigned char *DataTransferBuffer = NULL;
@@ -2952,21 +5508,23 @@
 	    ControllerNumber > DAC960_ControllerCount - 1)
 	  return -ENXIO;
 	Controller = DAC960_Controllers[ControllerNumber];
-	if (Controller == NULL)
-	  return -ENXIO;
+	if (Controller == NULL) return -ENXIO;
+	if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
 	CommandOpcode = KernelCommand->CommandMailbox.Common.CommandOpcode;
 	DataTransferLength = KernelCommand->DataTransferLength;
 	DataTransferBuffer = KernelCommand->DataTransferBuffer;
 	if (CommandOpcode & 0x80) return -EINVAL;
-	if (CommandOpcode == DAC960_DCDB)
+	if (CommandOpcode == DAC960_V1_DCDB)
 	  {
 	    DCDB = KernelCommand->DCDB;
 	    if (!((DataTransferLength == 0 &&
-		   DCDB->Direction == DAC960_DCDB_NoDataTransfer) ||
+		   DCDB->Direction == DAC960_V1_DCDB_NoDataTransfer) ||
 		  (DataTransferLength > 0 &&
-		   DCDB->Direction == DAC960_DCDB_DataTransferDeviceToSystem) ||
+		   DCDB->Direction
+		   == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
 		  (DataTransferLength < 0 &&
-		   DCDB->Direction == DAC960_DCDB_DataTransferSystemToDevice)))
+		   DCDB->Direction
+		   == DAC960_V1_DCDB_DataTransferSystemToDevice)))
 	      return -EINVAL;
 	    if (((DCDB->TransferLengthHigh4 << 16) | DCDB->TransferLength)
 		!= abs(DataTransferLength))
@@ -2976,25 +5534,26 @@
 	  return -EINVAL;
 	if (DataTransferLength > 0)
 	  memset(DataTransferBuffer, 0, DataTransferLength);
-	if (CommandOpcode == DAC960_DCDB)
+	if (CommandOpcode == DAC960_V1_DCDB)
 	  {
 	    DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
-	    if (!Controller->DirectCommandActive[DCDB->Channel]
-						[DCDB->TargetID])
+	    if (!Controller->V1.DirectCommandActive[DCDB->Channel]
+						   [DCDB->TargetID])
 	      Command = DAC960_AllocateCommand(Controller);
 	    if (Command == NULL)
 	      {
 		DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
 		return -EBUSY;
 	      }
-	    else Controller->DirectCommandActive[DCDB->Channel]
-						[DCDB->TargetID] = true;
-	    DAC960_ClearCommand(Command);
+	    else Controller->V1.DirectCommandActive[DCDB->Channel]
+						   [DCDB->TargetID] = true;
+	    DAC960_V1_ClearCommand(Command);
 	    Command->CommandType = DAC960_QueuedCommand;
-	    memcpy(&Command->CommandMailbox, &KernelCommand->CommandMailbox,
-		   sizeof(DAC960_CommandMailbox_T));
-	    Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
-	    Command->KernelCommand = KernelCommand;
+	    memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
+		   sizeof(DAC960_V1_CommandMailbox_T));
+	    Command->V1.CommandMailbox.Type3.BusAddress =
+	      Virtual_to_Bus(DCDB);
+	    Command->V1.KernelCommand = KernelCommand;
 	    DCDB->BusAddress = Virtual_to_Bus(DataTransferBuffer);
 	    DAC960_QueueCommand(Command);
 	    DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
@@ -3008,42 +5567,153 @@
 		DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
 		return -EBUSY;
 	      }
-	    DAC960_ClearCommand(Command);
+	    DAC960_V1_ClearCommand(Command);
 	    Command->CommandType = DAC960_QueuedCommand;
-	    memcpy(&Command->CommandMailbox, &KernelCommand->CommandMailbox,
-		   sizeof(DAC960_CommandMailbox_T));
+	    memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
+		   sizeof(DAC960_V1_CommandMailbox_T));
 	    if (DataTransferBuffer != NULL)
-	      Command->CommandMailbox.Type3.BusAddress =
+	      Command->V1.CommandMailbox.Type3.BusAddress =
 		Virtual_to_Bus(DataTransferBuffer);
-	    Command->KernelCommand = KernelCommand;
+	    Command->V1.KernelCommand = KernelCommand;
 	    DAC960_QueueCommand(Command);
 	    DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
 	  }
 	return 0;
       }
+    case DAC960_IOCTL_V2_EXECUTE_COMMAND:
+      {
+	DAC960_V2_KernelCommand_T *KernelCommand =
+	  (DAC960_V2_KernelCommand_T *) Argument;
+	DAC960_Controller_T *Controller;
+	DAC960_Command_T *Command = NULL;
+	DAC960_V2_CommandMailbox_T *CommandMailbox;
+	ProcessorFlags_T ProcessorFlags;
+	int ControllerNumber, DataTransferLength, RequestSenseLength;
+	unsigned char *DataTransferBuffer = NULL;
+	unsigned char *RequestSenseBuffer = NULL;
+	if (KernelCommand == NULL) return -EINVAL;
+	ControllerNumber = KernelCommand->ControllerNumber;
+	if (ControllerNumber < 0 ||
+	    ControllerNumber > DAC960_ControllerCount - 1)
+	  return -ENXIO;
+	Controller = DAC960_Controllers[ControllerNumber];
+	if (Controller == NULL) return -ENXIO;
+	if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
+	DataTransferLength = KernelCommand->DataTransferLength;
+	RequestSenseLength = KernelCommand->RequestSenseLength;
+	DataTransferBuffer = KernelCommand->DataTransferBuffer;
+	RequestSenseBuffer = KernelCommand->RequestSenseBuffer;
+	if (DataTransferLength != 0 && DataTransferBuffer == NULL)
+	  return -EINVAL;
+	if (RequestSenseLength < 0)
+	  return -EINVAL;
+	if (RequestSenseLength > 0 && RequestSenseBuffer == NULL)
+	  return -EINVAL;
+	if (DataTransferLength > 0)
+	  memset(DataTransferBuffer, 0, DataTransferLength);
+	if (RequestSenseLength > 0)
+	  memset(RequestSenseBuffer, 0, RequestSenseLength);
+	DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+	Command = DAC960_AllocateCommand(Controller);
+	if (Command == NULL)
+	  {
+	    DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+	    return -EBUSY;
+	  }
+	DAC960_V2_ClearCommand(Command);
+	Command->CommandType = DAC960_QueuedCommand;
+	CommandMailbox = &Command->V2.CommandMailbox;
+	memcpy(CommandMailbox, &KernelCommand->CommandMailbox,
+	       sizeof(DAC960_V2_CommandMailbox_T));
+	CommandMailbox->Common.CommandControlBits
+			      .AdditionalScatterGatherListMemory = false;
+	CommandMailbox->Common.CommandControlBits
+			      .NoAutoRequestSense = true;
+	CommandMailbox->Common.DataTransferSize = 0;
+	CommandMailbox->Common.DataTransferPageNumber = 0;
+	memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
+	       sizeof(DAC960_V2_DataTransferMemoryAddress_T));
+	if (DataTransferLength != 0)
+	  {
+	    if (DataTransferLength > 0)
+	      {
+		CommandMailbox->Common.CommandControlBits
+				      .DataTransferControllerToHost = true;
+		CommandMailbox->Common.DataTransferSize = DataTransferLength;
+	      }
+	    else
+	      {
+		CommandMailbox->Common.CommandControlBits
+				      .DataTransferControllerToHost = false;
+		CommandMailbox->Common.DataTransferSize = -DataTransferLength;
+	      }
+	    CommandMailbox->Common.DataTransferMemoryAddress
+				  .ScatterGatherSegments[0]
+				  .SegmentDataPointer =
+	      Virtual_to_Bus(DataTransferBuffer);
+	    CommandMailbox->Common.DataTransferMemoryAddress
+				  .ScatterGatherSegments[0]
+				  .SegmentByteCount =
+	      CommandMailbox->Common.DataTransferSize;
+	  }
+	if (RequestSenseLength > 0)
+	  {
+	    CommandMailbox->Common.CommandControlBits
+				  .NoAutoRequestSense = false;
+	    CommandMailbox->Common.RequestSenseBusAddress =
+	      Virtual_to_Bus(RequestSenseBuffer);
+	  }
+	Command->V2.KernelCommand = KernelCommand;
+	DAC960_QueueCommand(Command);
+	DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+	return 0;
+      }
     }
   return -EINVAL;
 }
 
 
 /*
-  DAC960_GenericDiskInit is the Generic Disk Information Initialization
-  Function for the DAC960 Driver.
-*/
-
-static void DAC960_InitializeGenericDiskInfo(GenericDiskInfo_T *GenericDiskInfo)
-{
-  DAC960_Controller_T *Controller =
-    (DAC960_Controller_T *) GenericDiskInfo->real_devices;
-  DAC960_LogicalDriveInformation_T *LogicalDriveInformation =
-    Controller->LogicalDriveInformation
-		[Controller->LogicalDriveInformationIndex];
-  int LogicalDriveNumber;
-  for (LogicalDriveNumber = 0;
-       LogicalDriveNumber < Controller->LogicalDriveCount;
-       LogicalDriveNumber++)
-    GenericDiskInfo->part[DAC960_MinorNumber(LogicalDriveNumber, 0)].nr_sects =
-      LogicalDriveInformation[LogicalDriveNumber].LogicalDriveSize;
+  DAC960_CheckStatusBuffer verifies that there is room to hold ByteCount
+  additional bytes in the Combined Status Buffer and grows the buffer if
+  necessary.  It returns true if there is enough room and false otherwise.
+*/
+
+static boolean DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
+					unsigned int ByteCount)
+{
+  unsigned char *NewStatusBuffer;
+  if (Controller->InitialStatusLength + 1 +
+      Controller->CurrentStatusLength + ByteCount + 1 <=
+      Controller->CombinedStatusBufferLength)
+    return true;
+  if (Controller->CombinedStatusBufferLength == 0)
+    {
+      unsigned int NewStatusBufferLength = DAC960_InitialStatusBufferSize;
+      while (NewStatusBufferLength < ByteCount)
+	NewStatusBufferLength *= 2;
+      Controller->CombinedStatusBuffer =
+	(unsigned char *) kmalloc(NewStatusBufferLength, GFP_ATOMIC);
+      if (Controller->CombinedStatusBuffer == NULL) return false;
+      Controller->CombinedStatusBufferLength = NewStatusBufferLength;
+      return true;
+    }
+  NewStatusBuffer = (unsigned char *)
+    kmalloc(2 * Controller->CombinedStatusBufferLength, GFP_ATOMIC);
+  if (NewStatusBuffer == NULL)
+    {
+      DAC960_Warning("Unable to expand Combined Status Buffer - Truncating\n",
+		     Controller);
+      return false;
+    }
+  memcpy(NewStatusBuffer, Controller->CombinedStatusBuffer,
+	 Controller->CombinedStatusBufferLength);
+  kfree(Controller->CombinedStatusBuffer);
+  Controller->CombinedStatusBuffer = NewStatusBuffer;
+  Controller->CombinedStatusBufferLength *= 2;
+  Controller->CurrentStatusBuffer =
+    &NewStatusBuffer[Controller->InitialStatusLength + 1];
+  return true;
 }
 
 
@@ -3052,11 +5722,11 @@
 */
 
 static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
-			   char *Format,
+			   unsigned char *Format,
 			   DAC960_Controller_T *Controller,
 			   ...)
 {
-  static char Buffer[DAC960_LineBufferSize];
+  static unsigned char Buffer[DAC960_LineBufferSize];
   static boolean BeginningOfLine = true;
   va_list Arguments;
   int Length = 0;
@@ -3071,9 +5741,16 @@
     {
       if (!Controller->ControllerInitialized)
 	{
-	  strcpy(&Controller->InitialStatusBuffer[
-		    Controller->InitialStatusLength], Buffer);
-	  Controller->InitialStatusLength += Length;
+	  if (DAC960_CheckStatusBuffer(Controller, Length))
+	    {
+	      strcpy(&Controller->CombinedStatusBuffer
+				  [Controller->InitialStatusLength],
+		     Buffer);
+	      Controller->InitialStatusLength += Length;
+	      Controller->CurrentStatusBuffer =
+		&Controller->CombinedStatusBuffer
+			     [Controller->InitialStatusLength + 1];
+	    }
 	  if (MessageLevel == DAC960_AnnounceLevel)
 	    {
 	      static int AnnouncementLines = 0;
@@ -3093,7 +5770,7 @@
 	      else printk("%s", Buffer);
 	    }
 	}
-      else
+      else if (DAC960_CheckStatusBuffer(Controller, Length))
 	{
 	  strcpy(&Controller->CurrentStatusBuffer[
 		    Controller->CurrentStatusLength], Buffer);
@@ -3102,8 +5779,8 @@
     }
   else if (MessageLevel == DAC960_ProgressLevel)
     {
-      strcpy(Controller->RebuildProgressBuffer, Buffer);
-      Controller->RebuildProgressLength = Length;
+      strcpy(Controller->ProgressBuffer, Buffer);
+      Controller->ProgressBufferLength = Length;
       if (Controller->EphemeralProgressMessage)
 	{
 	  if (jiffies - Controller->LastProgressReportTime
@@ -3138,15 +5815,15 @@
 
 
 /*
-  DAC960_ParsePhysicalDrive parses spaces followed by a Physical Drive
+  DAC960_ParsePhysicalDevice parses spaces followed by a Physical Device
   Channel:TargetID specification from a User Command string.  It updates
-  Channel and TargetID and returns true on success and returns false otherwise.
+  Channel and TargetID and returns true on success and false on failure.
 */
 
-static boolean DAC960_ParsePhysicalDrive(DAC960_Controller_T *Controller,
-					 char *UserCommandString,
-					 unsigned char *Channel,
-					 unsigned char *TargetID)
+static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
+					  char *UserCommandString,
+					  unsigned char *Channel,
+					  unsigned char *TargetID)
 {
   char *NewUserCommandString = UserCommandString;
   unsigned long XChannel, XTargetID;
@@ -3162,7 +5839,7 @@
   XTargetID = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
   if (NewUserCommandString == UserCommandString ||
       *NewUserCommandString != '\0' ||
-      XTargetID >= DAC960_MaxTargets)
+      XTargetID >= Controller->Targets)
     return false;
   *Channel = XChannel;
   *TargetID = XTargetID;
@@ -3173,7 +5850,7 @@
 /*
   DAC960_ParseLogicalDrive parses spaces followed by a Logical Drive Number
   specification from a User Command string.  It updates LogicalDriveNumber and
-  returns true on success and returns false otherwise.
+  returns true on success and false on failure.
 */
 
 static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
@@ -3189,7 +5866,7 @@
     simple_strtoul(UserCommandString, &NewUserCommandString, 10);
   if (NewUserCommandString == UserCommandString ||
       *NewUserCommandString != '\0' ||
-      XLogicalDriveNumber >= Controller->LogicalDriveCount)
+      XLogicalDriveNumber > DAC960_MaxLogicalDrives - 1)
     return false;
   *LogicalDriveNumber = XLogicalDriveNumber;
   return true;
@@ -3197,68 +5874,71 @@
 
 
 /*
-  DAC960_SetDeviceState sets the Device State for a Physical Drive.
+  DAC960_V1_SetDeviceState sets the Device State for a Physical Device for
+  DAC960 V1 Firmware Controllers.
 */
 
-static void DAC960_SetDeviceState(DAC960_Controller_T *Controller,
-				  DAC960_Command_T *Command,
-				  unsigned char Channel,
-				  unsigned char TargetID,
-				  DAC960_PhysicalDeviceState_T DeviceState,
-				  const char *DeviceStateString)
+static void DAC960_V1_SetDeviceState(DAC960_Controller_T *Controller,
+				     DAC960_Command_T *Command,
+				     unsigned char Channel,
+				     unsigned char TargetID,
+				     DAC960_V1_PhysicalDeviceState_T
+				       DeviceState,
+				     const unsigned char *DeviceStateString)
 {
-  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-  CommandMailbox->Type3D.CommandOpcode = DAC960_StartDevice;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  CommandMailbox->Type3D.CommandOpcode = DAC960_V1_StartDevice;
   CommandMailbox->Type3D.Channel = Channel;
   CommandMailbox->Type3D.TargetID = TargetID;
   CommandMailbox->Type3D.DeviceState = DeviceState;
   CommandMailbox->Type3D.Modifier = 0;
   DAC960_ExecuteCommand(Command);
-  switch (Command->CommandStatus)
+  switch (Command->V1.CommandStatus)
     {
-    case DAC960_NormalCompletion:
-      DAC960_UserCritical("%s of Physical Drive %d:%d Succeeded\n", Controller,
+    case DAC960_V1_NormalCompletion:
+      DAC960_UserCritical("%s of Physical Device %d:%d Succeeded\n", Controller,
 			  DeviceStateString, Channel, TargetID);
       break;
-    case DAC960_UnableToStartDevice:
-      DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+    case DAC960_V1_UnableToStartDevice:
+      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
 			  "Unable to Start Device\n", Controller,
 			  DeviceStateString, Channel, TargetID);
       break;
-    case DAC960_NoDeviceAtAddress:
-      DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+    case DAC960_V1_NoDeviceAtAddress:
+      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
 			  "No Device at Address\n", Controller,
 			  DeviceStateString, Channel, TargetID);
       break;
-    case DAC960_InvalidChannelOrTargetOrModifier:
-      DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+    case DAC960_V1_InvalidChannelOrTargetOrModifier:
+      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
 			  "Invalid Channel or Target or Modifier\n",
 			  Controller, DeviceStateString, Channel, TargetID);
       break;
-    case DAC960_ChannelBusy:
-      DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+    case DAC960_V1_ChannelBusy:
+      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
 			  "Channel Busy\n", Controller,
 			  DeviceStateString, Channel, TargetID);
       break;
     default:
-      DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
 			  "Unexpected Status %04X\n", Controller,
 			  DeviceStateString, Channel, TargetID,
-			  Command->CommandStatus);
+			  Command->V1.CommandStatus);
       break;
     }
 }
 
 
 /*
-  DAC960_ExecuteUserCommand executes a User Command.
+  DAC960_V1_ExecuteUserCommand executes a User Command for DAC960 V1 Firmware
+  Controllers.
 */
 
-static boolean DAC960_ExecuteUserCommand(DAC960_Controller_T *Controller,
-					 char *UserCommand)
+static boolean DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
+					    unsigned char *UserCommand)
 {
   DAC960_Command_T *Command;
-  DAC960_CommandMailbox_T *CommandMailbox;
+  DAC960_V1_CommandMailbox_T *CommandMailbox;
   ProcessorFlags_T ProcessorFlags;
   unsigned char Channel, TargetID, LogicalDriveNumber;
   DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
@@ -3266,100 +5946,98 @@
     DAC960_WaitForCommand(Controller);
   DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
   Controller->UserStatusLength = 0;
-  DAC960_ClearCommand(Command);
+  DAC960_V1_ClearCommand(Command);
   Command->CommandType = DAC960_ImmediateCommand;
-  CommandMailbox = &Command->CommandMailbox;
+  CommandMailbox = &Command->V1.CommandMailbox;
   if (strcmp(UserCommand, "flush-cache") == 0)
     {
-      CommandMailbox->Type3.CommandOpcode = DAC960_Flush;
+      CommandMailbox->Type3.CommandOpcode = DAC960_V1_Flush;
       DAC960_ExecuteCommand(Command);
       DAC960_UserCritical("Cache Flush Completed\n", Controller);
     }
   else if (strncmp(UserCommand, "kill", 4) == 0 &&
-	   DAC960_ParsePhysicalDrive(Controller, &UserCommand[4],
-				     &Channel, &TargetID))
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
+				      &Channel, &TargetID))
     {
-      DAC960_DeviceState_T *DeviceState =
-	&Controller->DeviceState[Controller->DeviceStateIndex]
-				[Channel][TargetID];
+      DAC960_V1_DeviceState_T *DeviceState =
+	&Controller->V1.DeviceState[Channel][TargetID];
       if (DeviceState->Present &&
-	  DeviceState->DeviceType == DAC960_DiskType &&
-	  DeviceState->DeviceState != DAC960_Device_Dead)
-	DAC960_SetDeviceState(Controller, Command, Channel, TargetID,
-			      DAC960_Device_Dead, "Kill");
-      else DAC960_UserCritical("Kill of Physical Drive %d:%d Illegal\n",
+	  DeviceState->DeviceType == DAC960_V1_DiskType &&
+	  DeviceState->DeviceState != DAC960_V1_Device_Dead)
+	DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
+				 DAC960_V1_Device_Dead, "Kill");
+      else DAC960_UserCritical("Kill of Physical Device %d:%d Illegal\n",
 			       Controller, Channel, TargetID);
     }
   else if (strncmp(UserCommand, "make-online", 11) == 0 &&
-	   DAC960_ParsePhysicalDrive(Controller, &UserCommand[11],
-				     &Channel, &TargetID))
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
+				      &Channel, &TargetID))
     {
-      DAC960_DeviceState_T *DeviceState =
-	&Controller->DeviceState[Controller->DeviceStateIndex]
-				[Channel][TargetID];
+      DAC960_V1_DeviceState_T *DeviceState =
+	&Controller->V1.DeviceState[Channel][TargetID];
       if (DeviceState->Present &&
-	  DeviceState->DeviceType == DAC960_DiskType &&
-	  DeviceState->DeviceState == DAC960_Device_Dead)
-	DAC960_SetDeviceState(Controller, Command, Channel, TargetID,
-			      DAC960_Device_Online, "Make Online");
-      else DAC960_UserCritical("Make Online of Physical Drive %d:%d Illegal\n",
+	  DeviceState->DeviceType == DAC960_V1_DiskType &&
+	  DeviceState->DeviceState == DAC960_V1_Device_Dead)
+	DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
+				 DAC960_V1_Device_Online, "Make Online");
+      else DAC960_UserCritical("Make Online of Physical Device %d:%d Illegal\n",
 			       Controller, Channel, TargetID);
 
     }
   else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
-	   DAC960_ParsePhysicalDrive(Controller, &UserCommand[12],
-				     &Channel, &TargetID))
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
+				      &Channel, &TargetID))
     {
-      DAC960_DeviceState_T *DeviceState =
-	&Controller->DeviceState[Controller->DeviceStateIndex]
-				[Channel][TargetID];
+      DAC960_V1_DeviceState_T *DeviceState =
+	&Controller->V1.DeviceState[Channel][TargetID];
       if (DeviceState->Present &&
-	  DeviceState->DeviceType == DAC960_DiskType &&
-	  DeviceState->DeviceState == DAC960_Device_Dead)
-	DAC960_SetDeviceState(Controller, Command, Channel, TargetID,
-			      DAC960_Device_Standby, "Make Standby");
-      else DAC960_UserCritical("Make Standby of Physical Drive %d:%d Illegal\n",
+	  DeviceState->DeviceType == DAC960_V1_DiskType &&
+	  DeviceState->DeviceState == DAC960_V1_Device_Dead)
+	DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
+				 DAC960_V1_Device_Standby, "Make Standby");
+      else DAC960_UserCritical("Make Standby of Physical "
+			       "Device %d:%d Illegal\n",
 			       Controller, Channel, TargetID);
     }
   else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
-	   DAC960_ParsePhysicalDrive(Controller, &UserCommand[7],
-				     &Channel, &TargetID))
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
+				      &Channel, &TargetID))
     {
-      CommandMailbox->Type3D.CommandOpcode = DAC960_RebuildAsync;
+      CommandMailbox->Type3D.CommandOpcode = DAC960_V1_RebuildAsync;
       CommandMailbox->Type3D.Channel = Channel;
       CommandMailbox->Type3D.TargetID = TargetID;
       DAC960_ExecuteCommand(Command);
-      switch (Command->CommandStatus)
+      switch (Command->V1.CommandStatus)
 	{
-	case DAC960_NormalCompletion:
-	  DAC960_UserCritical("Rebuild of Physical Drive %d:%d Initiated\n",
+	case DAC960_V1_NormalCompletion:
+	  DAC960_UserCritical("Rebuild of Physical Device %d:%d Initiated\n",
 			      Controller, Channel, TargetID);
 	  break;
-	case DAC960_AttemptToRebuildOnlineDrive:
-	  DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+	case DAC960_V1_AttemptToRebuildOnlineDrive:
+	  DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
 			      "Attempt to Rebuild Online or "
 			      "Unresponsive Drive\n",
 			      Controller, Channel, TargetID);
 	  break;
-	case DAC960_NewDiskFailedDuringRebuild:
-	  DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+	case DAC960_V1_NewDiskFailedDuringRebuild:
+	  DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
 			      "New Disk Failed During Rebuild\n",
 			      Controller, Channel, TargetID);
 	  break;
-	case DAC960_InvalidDeviceAddress:
-	  DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+	case DAC960_V1_InvalidDeviceAddress:
+	  DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
 			      "Invalid Device Address\n",
 			      Controller, Channel, TargetID);
 	  break;
-	case DAC960_RebuildOrCheckAlreadyInProgress:
-	  DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+	case DAC960_V1_RebuildOrCheckAlreadyInProgress:
+	  DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
 			      "Rebuild or Consistency Check Already "
 			      "in Progress\n", Controller, Channel, TargetID);
 	  break;
 	default:
-	  DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+	  DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
 			      "Unexpected Status %04X\n", Controller,
-			      Channel, TargetID, Command->CommandStatus);
+			      Channel, TargetID, Command->V1.CommandStatus);
 	  break;
 	}
     }
@@ -3367,28 +6045,28 @@
 	   DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
 				    &LogicalDriveNumber))
     {
-      CommandMailbox->Type3C.CommandOpcode = DAC960_CheckConsistencyAsync;
+      CommandMailbox->Type3C.CommandOpcode = DAC960_V1_CheckConsistencyAsync;
       CommandMailbox->Type3C.LogicalDriveNumber = LogicalDriveNumber;
       CommandMailbox->Type3C.AutoRestore = true;
       DAC960_ExecuteCommand(Command);
-      switch (Command->CommandStatus)
+      switch (Command->V1.CommandStatus)
 	{
-	case DAC960_NormalCompletion:
+	case DAC960_V1_NormalCompletion:
 	  DAC960_UserCritical("Consistency Check of Logical Drive %d "
 			      "(/dev/rd/c%dd%d) Initiated\n",
 			      Controller, LogicalDriveNumber,
 			      Controller->ControllerNumber,
 			      LogicalDriveNumber);
 	  break;
-	case DAC960_DependentDiskIsDead:
+	case DAC960_V1_DependentDiskIsDead:
 	  DAC960_UserCritical("Consistency Check of Logical Drive %d "
 			      "(/dev/rd/c%dd%d) Failed - "
-			      "Dependent Physical Drive is DEAD\n",
+			      "Dependent Physical Device is DEAD\n",
 			      Controller, LogicalDriveNumber,
 			      Controller->ControllerNumber,
 			      LogicalDriveNumber);
 	  break;
-	case DAC960_InvalidOrNonredundantLogicalDrive:
+	case DAC960_V1_InvalidOrNonredundantLogicalDrive:
 	  DAC960_UserCritical("Consistency Check of Logical Drive %d "
 			      "(/dev/rd/c%dd%d) Failed - "
 			      "Invalid or Nonredundant Logical Drive\n",
@@ -3396,7 +6074,7 @@
 			      Controller->ControllerNumber,
 			      LogicalDriveNumber);
 	  break;
-	case DAC960_RebuildOrCheckAlreadyInProgress:
+	case DAC960_V1_RebuildOrCheckAlreadyInProgress:
 	  DAC960_UserCritical("Consistency Check of Logical Drive %d "
 			      "(/dev/rd/c%dd%d) Failed - Rebuild or "
 			      "Consistency Check Already in Progress\n",
@@ -3410,7 +6088,7 @@
 			      "Unexpected Status %04X\n",
 			      Controller, LogicalDriveNumber,
 			      Controller->ControllerNumber,
-			      LogicalDriveNumber, Command->CommandStatus);
+			      LogicalDriveNumber, Command->V1.CommandStatus);
 	  break;
 	}
     }
@@ -3418,14 +6096,14 @@
 	   strcmp(UserCommand, "cancel-consistency-check") == 0)
     {
       unsigned char OldRebuildRateConstant;
-      CommandMailbox->Type3R.CommandOpcode = DAC960_RebuildControl;
+      CommandMailbox->Type3R.CommandOpcode = DAC960_V1_RebuildControl;
       CommandMailbox->Type3R.RebuildRateConstant = 0xFF;
       CommandMailbox->Type3R.BusAddress =
 	Virtual_to_Bus(&OldRebuildRateConstant);
       DAC960_ExecuteCommand(Command);
-      switch (Command->CommandStatus)
+      switch (Command->V1.CommandStatus)
 	{
-	case DAC960_NormalCompletion:
+	case DAC960_V1_NormalCompletion:
 	  DAC960_UserCritical("Rebuild or Consistency Check Cancelled\n",
 			      Controller);
 	  break;
@@ -3433,7 +6111,7 @@
 	  DAC960_UserCritical("Cancellation of Rebuild or "
 			      "Consistency Check Failed - "
 			      "Unexpected Status %04X\n",
-			      Controller, Command->CommandStatus);
+			      Controller, Command->V1.CommandStatus);
 	  break;
 	}
     }
@@ -3447,25 +6125,235 @@
 
 
 /*
+  DAC960_V2_TranslatePhysicalDevice translates a Physical Device Channel and
+  TargetID into a Logical Device.  It returns true on success and false
+  on failure.
+*/
+
+static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
+						 unsigned char Channel,
+						 unsigned char TargetID,
+						 unsigned short
+						   *LogicalDeviceNumber)
+{
+  DAC960_V2_CommandMailbox_T SavedCommandMailbox, *CommandMailbox;
+  DAC960_V2_PhysicalToLogicalDevice_T PhysicalToLogicalDevice;
+  CommandMailbox = &Command->V2.CommandMailbox;
+  memcpy(&SavedCommandMailbox, CommandMailbox,
+	 sizeof(DAC960_V2_CommandMailbox_T));
+  CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->PhysicalDeviceInfo.CommandControlBits
+				    .DataTransferControllerToHost = true;
+  CommandMailbox->PhysicalDeviceInfo.CommandControlBits
+				    .NoAutoRequestSense = true;
+  CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
+    sizeof(DAC960_V2_PhysicalToLogicalDevice_T);
+  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
+  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
+  CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
+    DAC960_V2_TranslatePhysicalToLogicalDevice;
+  CommandMailbox->Common.DataTransferMemoryAddress
+			.ScatterGatherSegments[0]
+			.SegmentDataPointer =
+    Virtual_to_Bus(&PhysicalToLogicalDevice);
+  CommandMailbox->Common.DataTransferMemoryAddress
+			.ScatterGatherSegments[0]
+			.SegmentByteCount =
+    CommandMailbox->Common.DataTransferSize;
+  DAC960_ExecuteCommand(Command);
+  memcpy(CommandMailbox, &SavedCommandMailbox,
+	 sizeof(DAC960_V2_CommandMailbox_T));
+  *LogicalDeviceNumber = PhysicalToLogicalDevice.LogicalDeviceNumber;
+  return (Command->V2.CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+  DAC960_V2_ExecuteUserCommand executes a User Command for DAC960 V2 Firmware
+  Controllers.
+*/
+
+static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
+					    unsigned char *UserCommand)
+{
+  DAC960_Command_T *Command;
+  DAC960_V2_CommandMailbox_T *CommandMailbox;
+  ProcessorFlags_T ProcessorFlags;
+  unsigned char Channel, TargetID, LogicalDriveNumber;
+  unsigned short LogicalDeviceNumber;
+  DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+  while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
+    DAC960_WaitForCommand(Controller);
+  DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+  Controller->UserStatusLength = 0;
+  DAC960_V2_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox = &Command->V2.CommandMailbox;
+  CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->Common.CommandControlBits.DataTransferControllerToHost = true;
+  CommandMailbox->Common.CommandControlBits.NoAutoRequestSense = true;
+  if (strcmp(UserCommand, "flush-cache") == 0)
+    {
+      CommandMailbox->DeviceOperation.IOCTL_Opcode = DAC960_V2_PauseDevice;
+      CommandMailbox->DeviceOperation.OperationDevice =
+	DAC960_V2_RAID_Controller;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Cache Flush Completed\n", Controller);
+    }
+  else if (strncmp(UserCommand, "kill", 4) == 0 &&
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
+				      &Channel, &TargetID) &&
+	   DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+					     &LogicalDeviceNumber))
+    {
+      CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
+	LogicalDeviceNumber;
+      CommandMailbox->SetDeviceState.IOCTL_Opcode =
+	DAC960_V2_SetDeviceState;
+      CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
+	DAC960_V2_Device_Dead;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Kill of Physical Device %d:%d %s\n",
+			  Controller, Channel, TargetID,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Succeeded" : "Failed"));
+    }
+  else if (strncmp(UserCommand, "make-online", 11) == 0 &&
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
+				      &Channel, &TargetID) &&
+	   DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+					     &LogicalDeviceNumber))
+    {
+      CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
+	LogicalDeviceNumber;
+      CommandMailbox->SetDeviceState.IOCTL_Opcode =
+	DAC960_V2_SetDeviceState;
+      CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
+	DAC960_V2_Device_Online;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Make Online of Physical Device %d:%d %s\n",
+			  Controller, Channel, TargetID,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Succeeded" : "Failed"));
+    }
+  else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
+				      &Channel, &TargetID) &&
+	   DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+					     &LogicalDeviceNumber))
+    {
+      CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
+	LogicalDeviceNumber;
+      CommandMailbox->SetDeviceState.IOCTL_Opcode =
+	DAC960_V2_SetDeviceState;
+      CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
+	DAC960_V2_Device_Standby;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Make Standby of Physical Device %d:%d %s\n",
+			  Controller, Channel, TargetID,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Succeeded" : "Failed"));
+    }
+  else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
+				      &Channel, &TargetID) &&
+	   DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+					     &LogicalDeviceNumber))
+    {
+      CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
+	LogicalDeviceNumber;
+      CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
+	DAC960_V2_RebuildDeviceStart;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n",
+			  Controller, Channel, TargetID,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Initiated" : "Not Initiated"));
+    }
+  else if (strncmp(UserCommand, "cancel-rebuild", 14) == 0 &&
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[14],
+				      &Channel, &TargetID) &&
+	   DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+					     &LogicalDeviceNumber))
+    {
+      CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
+	LogicalDeviceNumber;
+      CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
+	DAC960_V2_RebuildDeviceStop;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n",
+			  Controller, Channel, TargetID,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Cancelled" : "Not Cancelled"));
+    }
+  else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
+	   DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
+				    &LogicalDriveNumber))
+    {
+      CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
+	LogicalDriveNumber;
+      CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
+	DAC960_V2_ConsistencyCheckStart;
+      CommandMailbox->ConsistencyCheck.RestoreConsistency = true;
+      CommandMailbox->ConsistencyCheck.InitializedAreaOnly = false;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Consistency Check of Logical Drive %d "
+			  "(/dev/rd/c%dd%d) %s\n",
+			  Controller, LogicalDriveNumber,
+			  Controller->ControllerNumber,
+			  LogicalDriveNumber,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Initiated" : "Not Initiated"));
+    }
+  else if (strncmp(UserCommand, "cancel-consistency-check", 24) == 0 &&
+	   DAC960_ParseLogicalDrive(Controller, &UserCommand[24],
+				    &LogicalDriveNumber))
+    {
+      CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
+	LogicalDriveNumber;
+      CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
+	DAC960_V2_ConsistencyCheckStop;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Consistency Check of Logical Drive %d "
+			  "(/dev/rd/c%dd%d) %s\n",
+			  Controller, LogicalDriveNumber,
+			  Controller->ControllerNumber,
+			  LogicalDriveNumber,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Cancelled" : "Not Cancelled"));
+    }
+  else DAC960_UserCritical("Illegal User Command: '%s'\n",
+			   Controller, UserCommand);
+  DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+  DAC960_DeallocateCommand(Command);
+  DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+  return true;
+}
+
+
+/*
   DAC960_ProcReadStatus implements reading /proc/rd/status.
 */
 
 static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
 				 int Count, int *EOF, void *Data)
 {
-  char *StatusMessage = "OK\n";
+  unsigned char *StatusMessage = "OK\n";
   int ControllerNumber, BytesAvailable;
   for (ControllerNumber = 0;
        ControllerNumber < DAC960_ControllerCount;
        ControllerNumber++)
     {
       DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
-      DAC960_Enquiry_T *Enquiry;
       if (Controller == NULL) continue;
-      Enquiry = &Controller->Enquiry[Controller->EnquiryIndex];
-      if (Enquiry->CriticalLogicalDriveCount > 0 ||
-	  Enquiry->OfflineLogicalDriveCount > 0 ||
-	  Enquiry->DeadDriveCount > 0)
+      if (Controller->MonitoringAlertMode)
 	{
 	  StatusMessage = "ALERT\n";
 	  break;
@@ -3500,7 +6388,7 @@
     }
   if (Count <= 0) return 0;
   *Start = Page;
-  memcpy(Page, &Controller->InitialStatusBuffer[Offset], Count);
+  memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count);
   return Count;
 }
 
@@ -3513,6 +6401,9 @@
 					int Count, int *EOF, void *Data)
 {
   DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
+  unsigned char *StatusMessage =
+    "No Rebuild or Consistency Check in Progress\n";
+  int ProgressMessageLength = strlen(StatusMessage);
   int BytesAvailable;
   if (jiffies != Controller->LastCurrentStatusTime)
     {
@@ -3520,22 +6411,20 @@
       DAC960_AnnounceDriver(Controller);
       DAC960_ReportControllerConfiguration(Controller);
       DAC960_ReportDeviceConfiguration(Controller);
-      Controller->CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
-      Controller->CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
-      if (Controller->RebuildProgressLength > 0)
-	{
-	  strcpy(&Controller->CurrentStatusBuffer
-			      [Controller->CurrentStatusLength],
-		 Controller->RebuildProgressBuffer);
-	  Controller->CurrentStatusLength += Controller->RebuildProgressLength;
-	}
-      else
-	{
-	  char *StatusMessage = "No Rebuild or Consistency Check in Progress\n";
-	  strcpy(&Controller->CurrentStatusBuffer
-			      [Controller->CurrentStatusLength],
-		 StatusMessage);
-	  Controller->CurrentStatusLength += strlen(StatusMessage);
+      if (Controller->ProgressBufferLength > 0)
+	ProgressMessageLength = Controller->ProgressBufferLength;
+      if (DAC960_CheckStatusBuffer(Controller, 2 + ProgressMessageLength))
+	{
+	  unsigned char *CurrentStatusBuffer = Controller->CurrentStatusBuffer;
+	  CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
+	  CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
+	  if (Controller->ProgressBufferLength > 0)
+	    strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
+		   Controller->ProgressBuffer);
+	  else
+	    strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
+		   StatusMessage);
+	  Controller->CurrentStatusLength += ProgressMessageLength;
 	}
       Controller->LastCurrentStatusTime = jiffies;
     }
@@ -3581,7 +6470,7 @@
 				       unsigned long Count, void *Data)
 {
   DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
-  char CommandBuffer[80];
+  unsigned char CommandBuffer[80];
   int Length;
   if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
   copy_from_user(CommandBuffer, Buffer, Count);
@@ -3589,8 +6478,12 @@
   Length = strlen(CommandBuffer);
   if (CommandBuffer[Length-1] == '\n')
     CommandBuffer[--Length] = '\0';
-  return (DAC960_ExecuteUserCommand(Controller, CommandBuffer)
-	  ? Count : -EBUSY);
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+    return (DAC960_V1_ExecuteUserCommand(Controller, CommandBuffer)
+	    ? Count : -EBUSY);
+  else
+    return (DAC960_V2_ExecuteUserCommand(Controller, CommandBuffer)
+	    ? Count : -EBUSY);
 }
 
 
diff -urN linux-2.2.17-pre15/drivers/block/DAC960.h linux/drivers/block/DAC960.h
--- linux-2.2.17-pre15/drivers/block/DAC960.h	Wed May  3 17:16:32 2000
+++ linux/drivers/block/DAC960.h	Mon Dec  3 22:10:50 2001
@@ -1,8 +1,8 @@
 /*
 
-  Linux Driver for Mylex DAC960 and DAC1100 PCI RAID Controllers
+  Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
 
-  Copyright 1998-1999 by Leonard N. Zubkoff <lnz@dandelion.com>
+  Copyright 1998-2000 by Leonard N. Zubkoff <lnz@dandelion.com>
 
   This program is free software; you may redistribute and/or modify it under
   the terms of the GNU General Public License Version 2 as published by the
@@ -27,27 +27,41 @@
 
 
 /*
-  Define the maximum number of Controller Channels supported by this driver.
+  Define the maximum number of Controller Channels supported by DAC960
+  V1 and V2 Firmware Controllers.
 */
 
-#define DAC960_MaxChannels			3
+#define DAC960_V1_MaxChannels			3
+#define DAC960_V2_MaxChannels			4
 
 
 /*
-  Define the maximum number of Targets per Channel supported by this driver.
+  Define the maximum number of Targets per Channel supported by DAC960
+  V1 and V2 Firmware Controllers.
 */
 
-#define DAC960_MaxTargets			16
+#define DAC960_V1_MaxTargets			16
+#define DAC960_V2_MaxTargets			128
 
 
 /*
-  Define the maximum number of Logical Drives supported by any DAC960 model.
+  Define the maximum number of Logical Drives supported by DAC960
+  V1 and V2 Firmware Controllers.
 */
 
 #define DAC960_MaxLogicalDrives			32
 
 
 /*
+  Define the maximum number of Physical Devices supported by DAC960
+  V1 and V2 Firmware Controllers.
+*/
+
+#define DAC960_V1_MaxPhysicalDevices		45
+#define DAC960_V2_MaxPhysicalDevices		272
+
+
+/*
   Define a Boolean data type.
 */
 
@@ -72,149 +86,264 @@
   Define a 32 bit Bus Address data type.
 */
 
-typedef unsigned int DAC960_BusAddress_T;
+typedef unsigned int DAC960_BusAddress32_T;
+
+
+/*
+  Define a 64 bit Bus Address data type.
+*/
+
+typedef unsigned long long DAC960_BusAddress64_T;
 
 
 /*
   Define a 32 bit Byte Count data type.
 */
 
-typedef unsigned int DAC960_ByteCount_T;
+typedef unsigned int DAC960_ByteCount32_T;
+
+
+/*
+  Define a 64 bit Byte Count data type.
+*/
+
+typedef unsigned long long DAC960_ByteCount64_T;
+
+
+/*
+  Define the SCSI INQUIRY Standard Data structure.
+*/
+
+typedef struct DAC960_SCSI_Inquiry
+{
+  unsigned char PeripheralDeviceType:5;			/* Byte 0 Bits 0-4 */
+  unsigned char PeripheralQualifier:3;			/* Byte 0 Bits 5-7 */
+  unsigned char DeviceTypeModifier:7;			/* Byte 1 Bits 0-6 */
+  boolean RMB:1;					/* Byte 1 Bit 7 */
+  unsigned char ANSI_ApprovedVersion:3;			/* Byte 2 Bits 0-2 */
+  unsigned char ECMA_Version:3;				/* Byte 2 Bits 3-5 */
+  unsigned char ISO_Version:2;				/* Byte 2 Bits 6-7 */
+  unsigned char ResponseDataFormat:4;			/* Byte 3 Bits 0-3 */
+  unsigned char :2;					/* Byte 3 Bits 4-5 */
+  boolean TrmIOP:1;					/* Byte 3 Bit 6 */
+  boolean AENC:1;					/* Byte 3 Bit 7 */
+  unsigned char AdditionalLength;			/* Byte 4 */
+  unsigned char :8;					/* Byte 5 */
+  unsigned char :8;					/* Byte 6 */
+  boolean SftRe:1;					/* Byte 7 Bit 0 */
+  boolean CmdQue:1;					/* Byte 7 Bit 1 */
+  boolean :1;						/* Byte 7 Bit 2 */
+  boolean Linked:1;					/* Byte 7 Bit 3 */
+  boolean Sync:1;					/* Byte 7 Bit 4 */
+  boolean WBus16:1;					/* Byte 7 Bit 5 */
+  boolean WBus32:1;					/* Byte 7 Bit 6 */
+  boolean RelAdr:1;					/* Byte 7 Bit 7 */
+  unsigned char VendorIdentification[8];		/* Bytes 8-15 */
+  unsigned char ProductIdentification[16];		/* Bytes 16-31 */
+  unsigned char ProductRevisionLevel[4];		/* Bytes 32-35 */
+}
+DAC960_SCSI_Inquiry_T;
+
+
+/*
+  Define the SCSI INQUIRY Unit Serial Number structure.
+*/
+
+typedef struct DAC960_SCSI_Inquiry_UnitSerialNumber
+{
+  unsigned char PeripheralDeviceType:5;			/* Byte 0 Bits 0-4 */
+  unsigned char PeripheralQualifier:3;			/* Byte 0 Bits 5-7 */
+  unsigned char PageCode;				/* Byte 1 */
+  unsigned char :8;					/* Byte 2 */
+  unsigned char PageLength;				/* Byte 3 */
+  unsigned char ProductSerialNumber[28];		/* Bytes 4-31 */
+}
+DAC960_SCSI_Inquiry_UnitSerialNumber_T;
+
+
+/*
+  Define the SCSI REQUEST SENSE Sense Key type.
+*/
+
+typedef enum
+{
+  DAC960_SenseKey_NoSense =			0x0,
+  DAC960_SenseKey_RecoveredError =		0x1,
+  DAC960_SenseKey_NotReady =			0x2,
+  DAC960_SenseKey_MediumError =			0x3,
+  DAC960_SenseKey_HardwareError =		0x4,
+  DAC960_SenseKey_IllegalRequest =		0x5,
+  DAC960_SenseKey_UnitAttention =		0x6,
+  DAC960_SenseKey_DataProtect =			0x7,
+  DAC960_SenseKey_BlankCheck =			0x8,
+  DAC960_SenseKey_VendorSpecific =		0x9,
+  DAC960_SenseKey_CopyAborted =			0xA,
+  DAC960_SenseKey_AbortedCommand =		0xB,
+  DAC960_SenseKey_Equal =			0xC,
+  DAC960_SenseKey_VolumeOverflow =		0xD,
+  DAC960_SenseKey_Miscompare =			0xE,
+  DAC960_SenseKey_Reserved =			0xF
+}
+__attribute__ ((packed))
+DAC960_SCSI_RequestSenseKey_T;
+
+
+/*
+  Define the SCSI REQUEST SENSE structure.
+*/
+
+typedef struct DAC960_SCSI_RequestSense
+{
+  unsigned char ErrorCode:7;				/* Byte 0 Bits 0-6 */
+  boolean Valid:1;					/* Byte 0 Bit 7 */
+  unsigned char SegmentNumber;				/* Byte 1 */
+  DAC960_SCSI_RequestSenseKey_T SenseKey:4;		/* Byte 2 Bits 0-3 */
+  unsigned char :1;					/* Byte 2 Bit 4 */
+  boolean ILI:1;					/* Byte 2 Bit 5 */
+  boolean EOM:1;					/* Byte 2 Bit 6 */
+  boolean Filemark:1;					/* Byte 2 Bit 7 */
+  unsigned char Information[4];				/* Bytes 3-6 */
+  unsigned char AdditionalSenseLength;			/* Byte 7 */
+  unsigned char CommandSpecificInformation[4];		/* Bytes 8-11 */
+  unsigned char AdditionalSenseCode;			/* Byte 12 */
+  unsigned char AdditionalSenseCodeQualifier;		/* Byte 13 */
+}
+DAC960_SCSI_RequestSense_T;
 
 
 /*
-  Define the DAC960 Command Opcodes.
+  Define the DAC960 V1 Firmware Command Opcodes.
 */
 
 typedef enum
 {
   /* I/O Commands */
-  DAC960_ReadExtended =				0x33,
-  DAC960_WriteExtended =			0x34,
-  DAC960_ReadAheadExtended =			0x35,
-  DAC960_ReadExtendedWithScatterGather =	0xB3,
-  DAC960_WriteExtendedWithScatterGather =	0xB4,
-  DAC960_Read =					0x36,
-  DAC960_ReadWithOldScatterGather =		0xB6,
-  DAC960_Write =				0x37,
-  DAC960_WriteWithOldScatterGather =		0xB7,
-  DAC960_DCDB =					0x04,
-  DAC960_DCDBWithScatterGather =		0x84,
-  DAC960_Flush =				0x0A,
+  DAC960_V1_ReadExtended =			0x33,
+  DAC960_V1_WriteExtended =			0x34,
+  DAC960_V1_ReadAheadExtended =			0x35,
+  DAC960_V1_ReadExtendedWithScatterGather =	0xB3,
+  DAC960_V1_WriteExtendedWithScatterGather =	0xB4,
+  DAC960_V1_Read =				0x36,
+  DAC960_V1_ReadWithOldScatterGather =		0xB6,
+  DAC960_V1_Write =				0x37,
+  DAC960_V1_WriteWithOldScatterGather =		0xB7,
+  DAC960_V1_DCDB =				0x04,
+  DAC960_V1_DCDBWithScatterGather =		0x84,
+  DAC960_V1_Flush =				0x0A,
   /* Controller Status Related Commands */
-  DAC960_Enquiry =				0x53,
-  DAC960_Enquiry2 =				0x1C,
-  DAC960_GetLogicalDriveElement =		0x55,
-  DAC960_GetLogicalDriveInformation =		0x19,
-  DAC960_IOPortRead =				0x39,
-  DAC960_IOPortWrite =				0x3A,
-  DAC960_GetSDStats =				0x3E,
-  DAC960_GetPDStats =				0x3F,
-  DAC960_PerformEventLogOperation =		0x72,
+  DAC960_V1_Enquiry =				0x53,
+  DAC960_V1_Enquiry2 =				0x1C,
+  DAC960_V1_GetLogicalDriveElement =		0x55,
+  DAC960_V1_GetLogicalDriveInformation =	0x19,
+  DAC960_V1_IOPortRead =			0x39,
+  DAC960_V1_IOPortWrite =			0x3A,
+  DAC960_V1_GetSDStats =			0x3E,
+  DAC960_V1_GetPDStats =			0x3F,
+  DAC960_V1_PerformEventLogOperation =		0x72,
   /* Device Related Commands */
-  DAC960_StartDevice =				0x10,
-  DAC960_GetDeviceState =			0x50,
-  DAC960_StopChannel =				0x13,
-  DAC960_StartChannel =				0x12,
-  DAC960_ResetChannel =				0x1A,
+  DAC960_V1_StartDevice =			0x10,
+  DAC960_V1_GetDeviceState =			0x50,
+  DAC960_V1_StopChannel =			0x13,
+  DAC960_V1_StartChannel =			0x12,
+  DAC960_V1_ResetChannel =			0x1A,
   /* Commands Associated with Data Consistency and Errors */
-  DAC960_Rebuild =				0x09,
-  DAC960_RebuildAsync =				0x16,
-  DAC960_CheckConsistency =			0x0F,
-  DAC960_CheckConsistencyAsync =		0x1E,
-  DAC960_RebuildStat =				0x0C,
-  DAC960_GetRebuildProgress =			0x27,
-  DAC960_RebuildControl =			0x1F,
-  DAC960_ReadBadBlockTable =			0x0B,
-  DAC960_ReadBadDataTable =			0x25,
-  DAC960_ClearBadDataTable =			0x26,
-  DAC960_GetErrorTable =			0x17,
-  DAC960_AddCapacityAsync =			0x2A,
+  DAC960_V1_Rebuild =				0x09,
+  DAC960_V1_RebuildAsync =			0x16,
+  DAC960_V1_CheckConsistency =			0x0F,
+  DAC960_V1_CheckConsistencyAsync =		0x1E,
+  DAC960_V1_RebuildStat =			0x0C,
+  DAC960_V1_GetRebuildProgress =		0x27,
+  DAC960_V1_RebuildControl =			0x1F,
+  DAC960_V1_ReadBadBlockTable =			0x0B,
+  DAC960_V1_ReadBadDataTable =			0x25,
+  DAC960_V1_ClearBadDataTable =			0x26,
+  DAC960_V1_GetErrorTable =			0x17,
+  DAC960_V1_AddCapacityAsync =			0x2A,
   /* Configuration Related Commands */
-  DAC960_ReadConfig2 =				0x3D,
-  DAC960_WriteConfig2 =				0x3C,
-  DAC960_ReadConfigurationOnDisk =		0x4A,
-  DAC960_WriteConfigurationOnDisk =		0x4B,
-  DAC960_ReadConfiguration =			0x4E,
-  DAC960_ReadBackupConfiguration =		0x4D,
-  DAC960_WriteConfiguration =			0x4F,
-  DAC960_AddConfiguration =			0x4C,
-  DAC960_ReadConfigurationLabel =		0x48,
-  DAC960_WriteConfigurationLabel =		0x49,
+  DAC960_V1_ReadConfig2 =			0x3D,
+  DAC960_V1_WriteConfig2 =			0x3C,
+  DAC960_V1_ReadConfigurationOnDisk =		0x4A,
+  DAC960_V1_WriteConfigurationOnDisk =		0x4B,
+  DAC960_V1_ReadConfiguration =			0x4E,
+  DAC960_V1_ReadBackupConfiguration =		0x4D,
+  DAC960_V1_WriteConfiguration =		0x4F,
+  DAC960_V1_AddConfiguration =			0x4C,
+  DAC960_V1_ReadConfigurationLabel =		0x48,
+  DAC960_V1_WriteConfigurationLabel =		0x49,
   /* Firmware Upgrade Related Commands */
-  DAC960_LoadImage =				0x20,
-  DAC960_StoreImage =				0x21,
-  DAC960_ProgramImage =				0x22,
+  DAC960_V1_LoadImage =				0x20,
+  DAC960_V1_StoreImage =			0x21,
+  DAC960_V1_ProgramImage =			0x22,
   /* Diagnostic Commands */
-  DAC960_SetDiagnosticMode =			0x31,
-  DAC960_RunDiagnostic =			0x32,
+  DAC960_V1_SetDiagnosticMode =			0x31,
+  DAC960_V1_RunDiagnostic =			0x32,
   /* Subsystem Service Commands */
-  DAC960_GetSubsystemData =			0x70,
-  DAC960_SetSubsystemParameters =		0x71
+  DAC960_V1_GetSubsystemData =			0x70,
+  DAC960_V1_SetSubsystemParameters =		0x71
 }
 __attribute__ ((packed))
-DAC960_CommandOpcode_T;
+DAC960_V1_CommandOpcode_T;
 
 
 /*
-  Define the DAC960 Command Identifier type.
+  Define the DAC960 V1 Firmware Command Identifier type.
 */
 
-typedef unsigned char DAC960_CommandIdentifier_T;
+typedef unsigned char DAC960_V1_CommandIdentifier_T;
 
 
 /*
-  Define the DAC960 Command Status Codes.
+  Define the DAC960 V1 Firmware Command Status Codes.
 */
 
-#define DAC960_NormalCompletion			0x0000	/* Common */
-#define DAC960_CheckConditionReceived		0x0002	/* Common */
-#define DAC960_NoDeviceAtAddress		0x0102	/* Common */
-#define DAC960_InvalidDeviceAddress		0x0105	/* Common */
-#define DAC960_InvalidParameter			0x0105	/* Common */
-#define DAC960_IrrecoverableDataError		0x0001	/* I/O */
-#define DAC960_LogicalDriveNonexistentOrOffline	0x0002	/* I/O */
-#define DAC960_AccessBeyondEndOfLogicalDrive	0x0105	/* I/O */
-#define DAC960_BadDataEncountered		0x010C	/* I/O */
-#define DAC960_DeviceBusy			0x0008	/* DCDB */
-#define DAC960_DeviceNonresponsive		0x000E	/* DCDB */
-#define DAC960_CommandTerminatedAbnormally	0x000F	/* DCDB */
-#define DAC960_UnableToStartDevice		0x0002	/* Device */
-#define DAC960_InvalidChannelOrTargetOrModifier	0x0105	/* Device */
-#define DAC960_ChannelBusy			0x0106	/* Device */
-#define DAC960_ChannelNotStopped		0x0002	/* Device */
-#define DAC960_AttemptToRebuildOnlineDrive	0x0002	/* Consistency */
-#define DAC960_RebuildBadBlocksEncountered	0x0003	/* Consistency */
-#define DAC960_NewDiskFailedDuringRebuild	0x0004	/* Consistency */
-#define DAC960_RebuildOrCheckAlreadyInProgress	0x0106	/* Consistency */
-#define DAC960_DependentDiskIsDead		0x0002	/* Consistency */
-#define DAC960_InconsistentBlocksFound		0x0003	/* Consistency */
-#define DAC960_InvalidOrNonredundantLogicalDrive 0x0105	/* Consistency */
-#define DAC960_NoRebuildOrCheckInProgress	0x0105	/* Consistency */
-#define DAC960_RebuildInProgress_DataValid	0x0000	/* Consistency */
-#define DAC960_RebuildFailed_LogicalDriveFailure 0x0002	/* Consistency */
-#define DAC960_RebuildFailed_BadBlocksOnOther	0x0003	/* Consistency */
-#define DAC960_RebuildFailed_NewDriveFailed	0x0004	/* Consistency */
-#define DAC960_RebuildSuccessful		0x0100	/* Consistency */
-#define DAC960_RebuildSuccessfullyTerminated	0x0107	/* Consistency */
-#define DAC960_AddCapacityInProgress		0x0004	/* Consistency */
-#define DAC960_AddCapacityFailedOrSuspended	0x00F4	/* Consistency */
-#define DAC960_Config2ChecksumError		0x0002	/* Configuration */
-#define DAC960_ConfigurationSuspended		0x0106	/* Configuration */
-#define DAC960_FailedToConfigureNVRAM		0x0105	/* Configuration */
-#define DAC960_ConfigurationNotSavedStateChange	0x0106	/* Configuration */
-#define DAC960_SubsystemNotInstalled		0x0001	/* Subsystem */
-#define DAC960_SubsystemFailed			0x0002	/* Subsystem */
-#define DAC960_SubsystemBusy			0x0106	/* Subsystem */
+#define DAC960_V1_NormalCompletion		0x0000	/* Common */
+#define DAC960_V1_CheckConditionReceived	0x0002	/* Common */
+#define DAC960_V1_NoDeviceAtAddress		0x0102	/* Common */
+#define DAC960_V1_InvalidDeviceAddress		0x0105	/* Common */
+#define DAC960_V1_InvalidParameter		0x0105	/* Common */
+#define DAC960_V1_IrrecoverableDataError	0x0001	/* I/O */
+#define DAC960_V1_LogicalDriveNonexistentOrOffline 0x0002 /* I/O */
+#define DAC960_V1_AccessBeyondEndOfLogicalDrive	0x0105	/* I/O */
+#define DAC960_V1_BadDataEncountered		0x010C	/* I/O */
+#define DAC960_V1_DeviceBusy			0x0008	/* DCDB */
+#define DAC960_V1_DeviceNonresponsive		0x000E	/* DCDB */
+#define DAC960_V1_CommandTerminatedAbnormally	0x000F	/* DCDB */
+#define DAC960_V1_UnableToStartDevice		0x0002	/* Device */
+#define DAC960_V1_InvalidChannelOrTargetOrModifier 0x0105 /* Device */
+#define DAC960_V1_ChannelBusy			0x0106	/* Device */
+#define DAC960_V1_ChannelNotStopped		0x0002	/* Device */
+#define DAC960_V1_AttemptToRebuildOnlineDrive	0x0002	/* Consistency */
+#define DAC960_V1_RebuildBadBlocksEncountered	0x0003	/* Consistency */
+#define DAC960_V1_NewDiskFailedDuringRebuild	0x0004	/* Consistency */
+#define DAC960_V1_RebuildOrCheckAlreadyInProgress 0x0106 /* Consistency */
+#define DAC960_V1_DependentDiskIsDead		0x0002	/* Consistency */
+#define DAC960_V1_InconsistentBlocksFound	0x0003	/* Consistency */
+#define DAC960_V1_InvalidOrNonredundantLogicalDrive 0x0105 /* Consistency */
+#define DAC960_V1_NoRebuildOrCheckInProgress	0x0105	/* Consistency */
+#define DAC960_V1_RebuildInProgress_DataValid	0x0000	/* Consistency */
+#define DAC960_V1_RebuildFailed_LogicalDriveFailure 0x0002 /* Consistency */
+#define DAC960_V1_RebuildFailed_BadBlocksOnOther 0x0003	/* Consistency */
+#define DAC960_V1_RebuildFailed_NewDriveFailed	0x0004	/* Consistency */
+#define DAC960_V1_RebuildSuccessful		0x0100	/* Consistency */
+#define DAC960_V1_RebuildSuccessfullyTerminated	0x0107	/* Consistency */
+#define DAC960_V1_AddCapacityInProgress		0x0004	/* Consistency */
+#define DAC960_V1_AddCapacityFailedOrSuspended	0x00F4	/* Consistency */
+#define DAC960_V1_Config2ChecksumError		0x0002	/* Configuration */
+#define DAC960_V1_ConfigurationSuspended	0x0106	/* Configuration */
+#define DAC960_V1_FailedToConfigureNVRAM	0x0105	/* Configuration */
+#define DAC960_V1_ConfigurationNotSavedStateChange 0x0106 /* Configuration */
+#define DAC960_V1_SubsystemNotInstalled		0x0001	/* Subsystem */
+#define DAC960_V1_SubsystemFailed		0x0002	/* Subsystem */
+#define DAC960_V1_SubsystemBusy			0x0106	/* Subsystem */
 
-typedef unsigned short DAC960_CommandStatus_T;
+typedef unsigned short DAC960_V1_CommandStatus_T;
 
 
 /*
-  Define the Enquiry reply structure.
+  Define the DAC960 V1 Firmware Enquiry Command reply structure.
 */
 
-typedef struct DAC960_Enquiry
+typedef struct DAC960_V1_Enquiry
 {
   unsigned char NumberOfLogicalDrives;			/* Byte 0 */
   unsigned int :24;					/* Bytes 1-3 */
@@ -229,15 +358,15 @@
   unsigned char MinorFirmwareVersion;			/* Byte 136 */
   unsigned char MajorFirmwareVersion;			/* Byte 137 */
   enum {
-    DAC960_NoStandbyRebuildOrCheckInProgress =			0x00,
-    DAC960_StandbyRebuildInProgress =				0x01,
-    DAC960_BackgroundRebuildInProgress =			0x02,
-    DAC960_BackgroundCheckInProgress =				0x03,
-    DAC960_StandbyRebuildCompletedWithError =			0xFF,
-    DAC960_BackgroundRebuildOrCheckFailed_DriveFailed =		0xF0,
-    DAC960_BackgroundRebuildOrCheckFailed_LogicalDriveFailed =	0xF1,
-    DAC960_BackgroundRebuildOrCheckFailed_OtherCauses =		0xF2,
-    DAC960_BackgroundRebuildOrCheckSuccessfullyTerminated =	0xF3
+    DAC960_V1_NoStandbyRebuildOrCheckInProgress =		    0x00,
+    DAC960_V1_StandbyRebuildInProgress =			    0x01,
+    DAC960_V1_BackgroundRebuildInProgress =			    0x02,
+    DAC960_V1_BackgroundCheckInProgress =			    0x03,
+    DAC960_V1_StandbyRebuildCompletedWithError =		    0xFF,
+    DAC960_V1_BackgroundRebuildOrCheckFailed_DriveFailed =	    0xF0,
+    DAC960_V1_BackgroundRebuildOrCheckFailed_LogicalDriveFailed =   0xF1,
+    DAC960_V1_BackgroundRebuildOrCheckFailed_OtherCauses =	    0xF2,
+    DAC960_V1_BackgroundRebuildOrCheckSuccessfullyTerminated =	    0xF3
   } __attribute__ ((packed)) RebuildFlag;		/* Byte 138 */
   unsigned char MaxCommands;				/* Byte 139 */
   unsigned char OfflineLogicalDriveCount;		/* Byte 140 */
@@ -261,40 +390,40 @@
   unsigned char Reserved[62];				/* Bytes 195-255 */
 }
 __attribute__ ((packed))
-DAC960_Enquiry_T;
+DAC960_V1_Enquiry_T;
 
 
 /*
-  Define the Enquiry2 reply structure.
+  Define the DAC960 V1 Firmware Enquiry2 Command reply structure.
 */
 
-typedef struct DAC960_Enquiry2
+typedef struct DAC960_V1_Enquiry2
 {
   struct {
     enum {
-      DAC960_P_PD_PU =				0x01,
-      DAC960_PL =				0x02,
-      DAC960_PG =				0x10,
-      DAC960_PJ =				0x11,
-      DAC960_PR =				0x12,
-      DAC960_PT =				0x13,
-      DAC960_PTL0 =				0x14,
-      DAC960_PRL =				0x15,
-      DAC960_PTL1 =				0x16,
-      DAC1164_P =				0x20
+      DAC960_V1_P_PD_PU =			0x01,
+      DAC960_V1_PL =				0x02,
+      DAC960_V1_PG =				0x10,
+      DAC960_V1_PJ =				0x11,
+      DAC960_V1_PR =				0x12,
+      DAC960_V1_PT =				0x13,
+      DAC960_V1_PTL0 =				0x14,
+      DAC960_V1_PRL =				0x15,
+      DAC960_V1_PTL1 =				0x16,
+      DAC960_V1_1164P =				0x20
     } __attribute__ ((packed)) SubModel;		/* Byte 0 */
     unsigned char ActualChannels;			/* Byte 1 */
     enum {
-      DAC960_FiveChannelBoard =			0x01,
-      DAC960_ThreeChannelBoard =		0x02,
-      DAC960_TwoChannelBoard =			0x03,
-      DAC960_ThreeChannelASIC_DAC =		0x04
+      DAC960_V1_FiveChannelBoard =		0x01,
+      DAC960_V1_ThreeChannelBoard =		0x02,
+      DAC960_V1_TwoChannelBoard =		0x03,
+      DAC960_V1_ThreeChannelASIC_DAC =		0x04
     } __attribute__ ((packed)) Model;			/* Byte 2 */
     enum {
-      DAC960_EISA_Controller =			0x01,
-      DAC960_MicroChannel_Controller =		0x02,
-      DAC960_PCI_Controller =			0x03,
-      DAC960_SCSItoSCSI_Controller =		0x08
+      DAC960_V1_EISA_Controller =		0x01,
+      DAC960_V1_MicroChannel_Controller =	0x02,
+      DAC960_V1_PCI_Controller =		0x03,
+      DAC960_V1_SCSItoSCSI_Controller =		0x08
     } __attribute__ ((packed)) ProductFamily;		/* Byte 3 */
   } HardwareID;						/* Bytes 0-3 */
   /* MajorVersion.MinorVersion-FirmwareType-TurnID */
@@ -321,14 +450,14 @@
   unsigned int NonVolatileMemorySize;			/* Bytes 36-39 */
   struct {
     enum {
-      DAC960_DRAM =				0x00,
-      DAC960_EDO =				0x01,
-      DAC960_SDRAM =				0x02
+      DAC960_V1_DRAM =				0x0,
+      DAC960_V1_EDO =				0x1,
+      DAC960_V1_SDRAM =				0x2
     } __attribute__ ((packed)) RamType:3;		/* Byte 40 Bits 0-2 */
     enum {
-      DAC960_None =				0x00,
-      DAC960_Parity =				0x01,
-      DAC960_ECC =				0x02
+      DAC960_V1_None =				0x0,
+      DAC960_V1_Parity =			0x1,
+      DAC960_V1_ECC =				0x2
     } __attribute__ ((packed)) ErrorCorrection:3;	/* Byte 40 Bits 3-5 */
     boolean FastPageMode:1;				/* Byte 40 Bit 6 */
     boolean LowPowerMemory:1;				/* Byte 40 Bit 7 */
@@ -367,14 +496,14 @@
   unsigned short CacheLineSize;				/* Bytes 104-105 */
   struct {
     enum {
-      DAC960_Narrow_8bit =			0x00,
-      DAC960_Wide_16bit =			0x01,
-      DAC960_Wide_32bit =			0x02
+      DAC960_V1_Narrow_8bit =			0x0,
+      DAC960_V1_Wide_16bit =			0x1,
+      DAC960_V1_Wide_32bit =			0x2
     } __attribute__ ((packed)) BusWidth:2;		/* Byte 106 Bits 0-1 */
     enum {
-      DAC960_Fast =				0x00,
-      DAC960_Ultra =				0x01,
-      DAC960_Ultra2 =				0x02
+      DAC960_V1_Fast =				0x0,
+      DAC960_V1_Ultra =				0x1,
+      DAC960_V1_Ultra2 =			0x2
     } __attribute__ ((packed)) BusSpeed:2;		/* Byte 106 Bits 2-3 */
     boolean Differential:1;				/* Byte 106 Bit 4 */
     unsigned char :3;					/* Byte 106 Bits 5-7 */
@@ -383,12 +512,12 @@
   unsigned int :32;					/* Bytes 108-111 */
   unsigned short FirmwareBuildNumber;			/* Bytes 112-113 */
   enum {
-    DAC960_AEMI =				0x01,
-    DAC960_OEM1 =				0x02,
-    DAC960_OEM2 =				0x04,
-    DAC960_OEM3 =				0x08,
-    DAC960_Conner =				0x10,
-    DAC960_SAFTE =				0x20
+    DAC960_V1_AEMI =				0x01,
+    DAC960_V1_OEM1 =				0x02,
+    DAC960_V1_OEM2 =				0x04,
+    DAC960_V1_OEM3 =				0x08,
+    DAC960_V1_Conner =				0x10,
+    DAC960_V1_SAFTE =				0x20
   } __attribute__ ((packed)) FaultManagementType;	/* Byte 114 */
   unsigned char :8;					/* Byte 115 */
   struct {
@@ -399,55 +528,64 @@
   unsigned int :32;					/* Bytes 120-123 */
   unsigned int :32;					/* Bytes 124-127 */
 }
-DAC960_Enquiry2_T;
+DAC960_V1_Enquiry2_T;
 
 
 /*
-  Define the Logical Drive State type.
+  Define the DAC960 V1 Firmware Logical Drive State type.
 */
 
 typedef enum
 {
-    DAC960_LogicalDrive_Online =		0x03,
-    DAC960_LogicalDrive_Critical =		0x04,
-    DAC960_LogicalDrive_Offline =		0xFF
+  DAC960_V1_LogicalDrive_Online =		0x03,
+  DAC960_V1_LogicalDrive_Critical =		0x04,
+  DAC960_V1_LogicalDrive_Offline =		0xFF
 }
 __attribute__ ((packed))
-DAC960_LogicalDriveState_T;
+DAC960_V1_LogicalDriveState_T;
 
 
 /*
-  Define the Get Logical Drive Information reply structure.
+  Define the DAC960 V1 Firmware Logical Drive Information structure.
 */
 
-typedef struct DAC960_LogicalDriveInformation
+typedef struct DAC960_V1_LogicalDriveInformation
 {
   unsigned int LogicalDriveSize;			/* Bytes 0-3 */
-  DAC960_LogicalDriveState_T LogicalDriveState;		/* Byte 4 */
+  DAC960_V1_LogicalDriveState_T LogicalDriveState;	/* Byte 4 */
   unsigned char RAIDLevel:7;				/* Byte 5 Bits 0-6 */
   boolean WriteBack:1;					/* Byte 5 Bit 7 */
-  unsigned int :16;					/* Bytes 6-7 */
+  unsigned short :16;					/* Bytes 6-7 */
 }
-DAC960_LogicalDriveInformation_T;
+DAC960_V1_LogicalDriveInformation_T;
+
+
+/*
+  Define the DAC960 V1 Firmware Get Logical Drive Information Command
+  reply structure.
+*/
+
+typedef DAC960_V1_LogicalDriveInformation_T
+	DAC960_V1_LogicalDriveInformationArray_T[DAC960_MaxLogicalDrives];
 
 
 /*
-  Define the Perform Event Log Operation Types.
+  Define the DAC960 V1 Firmware Perform Event Log Operation Types.
 */
 
 typedef enum
 {
-  DAC960_GetEventLogEntry =			0x00
+  DAC960_V1_GetEventLogEntry =			0x00
 }
 __attribute__ ((packed))
-DAC960_PerformEventLogOpType_T;
+DAC960_V1_PerformEventLogOpType_T;
 
 
 /*
-  Define the Get Event Log Entry reply structure.
+  Define the DAC960 V1 Firmware Get Event Log Entry Command reply structure.
 */
 
-typedef struct DAC960_EventLogEntry
+typedef struct DAC960_V1_EventLogEntry
 {
   unsigned char MessageType;				/* Byte 0 */
   unsigned char MessageLength;				/* Byte 1 */
@@ -459,7 +597,7 @@
   unsigned char ErrorCode:7;				/* Byte 6 Bits 0-6 */
   boolean Valid:1;					/* Byte 6 Bit 7 */
   unsigned char SegmentNumber;				/* Byte 7 */
-  unsigned char SenseKey:4;				/* Byte 8 Bits 0-3 */
+  DAC960_SCSI_RequestSenseKey_T SenseKey:4;		/* Byte 8 Bits 0-3 */
   unsigned char :1;					/* Byte 8 Bit 4 */
   boolean ILI:1;					/* Byte 8 Bit 5 */
   boolean EOM:1;					/* Byte 8 Bit 6 */
@@ -471,37 +609,37 @@
   unsigned char AdditionalSenseCodeQualifier;		/* Byte 19 */
   unsigned char Dummy[12];				/* Bytes 20-31 */
 }
-DAC960_EventLogEntry_T;
+DAC960_V1_EventLogEntry_T;
 
 
 /*
-  Define the Physical Device State type.
+  Define the DAC960 V1 Firmware Physical Device State type.
 */
 
 typedef enum
 {
-    DAC960_Device_Dead =			0x00,
-    DAC960_Device_WriteOnly =			0x02,
-    DAC960_Device_Online =			0x03,
-    DAC960_Device_Standby =			0x10
+    DAC960_V1_Device_Dead =			0x00,
+    DAC960_V1_Device_WriteOnly =		0x02,
+    DAC960_V1_Device_Online =			0x03,
+    DAC960_V1_Device_Standby =			0x10
 }
 __attribute__ ((packed))
-DAC960_PhysicalDeviceState_T;
+DAC960_V1_PhysicalDeviceState_T;
 
 
 /*
-  Define the Get Device State reply structure.
+  Define the DAC960 V1 Firmware Get Device State Command reply structure.
 */
 
-typedef struct DAC960_DeviceState
+typedef struct DAC960_V1_DeviceState
 {
   boolean Present:1;					/* Byte 0 Bit 0 */
   unsigned char :7;					/* Byte 0 Bits 1-7 */
   enum {
-    DAC960_OtherType =				0x00,
-    DAC960_DiskType =				0x01,
-    DAC960_SequentialType =			0x02,
-    DAC960_CDROM_or_WORM_Type =			0x03
+    DAC960_V1_OtherType =			0x0,
+    DAC960_V1_DiskType =			0x1,
+    DAC960_V1_SequentialType =			0x2,
+    DAC960_V1_CDROM_or_WORM_Type =		0x3
     } __attribute__ ((packed)) DeviceType:2;		/* Byte 1 Bits 0-1 */
   boolean :1;						/* Byte 1 Bit 2 */
   boolean Fast20:1;					/* Byte 1 Bit 3 */
@@ -509,60 +647,60 @@
   boolean Fast:1;					/* Byte 1 Bit 5 */
   boolean Wide:1;					/* Byte 1 Bit 6 */
   boolean TaggedQueuingSupported:1;			/* Byte 1 Bit 7 */
-  DAC960_PhysicalDeviceState_T DeviceState;		/* Byte 2 */
+  DAC960_V1_PhysicalDeviceState_T DeviceState;		/* Byte 2 */
   unsigned char :8;					/* Byte 3 */
   unsigned char SynchronousMultiplier;			/* Byte 4 */
   unsigned char SynchronousOffset:5;			/* Byte 5 Bits 0-4 */
   unsigned char :3;					/* Byte 5 Bits 5-7 */
   unsigned int DiskSize __attribute__ ((packed));	/* Bytes 6-9 */
 }
-DAC960_DeviceState_T;
+DAC960_V1_DeviceState_T;
 
 
 /*
-  Define the Get Rebuild Progress reply structure.
+  Define the DAC960 V1 Firmware Get Rebuild Progress Command reply structure.
 */
 
-typedef struct DAC960_RebuildProgress
+typedef struct DAC960_V1_RebuildProgress
 {
   unsigned int LogicalDriveNumber;			/* Bytes 0-3 */
   unsigned int LogicalDriveSize;			/* Bytes 4-7 */
   unsigned int RemainingBlocks;				/* Bytes 8-11 */
 }
-DAC960_RebuildProgress_T;
+DAC960_V1_RebuildProgress_T;
 
 
 /*
-  Define the Error Table Entry and Get Error Table reply structure.
+  Define the DAC960 V1 Firmware Error Table Entry structure.
 */
 
-typedef struct DAC960_ErrorTableEntry
+typedef struct DAC960_V1_ErrorTableEntry
 {
   unsigned char ParityErrorCount;			/* Byte 0 */
   unsigned char SoftErrorCount;				/* Byte 1 */
   unsigned char HardErrorCount;				/* Byte 2 */
   unsigned char MiscErrorCount;				/* Byte 3 */
 }
-DAC960_ErrorTableEntry_T;
+DAC960_V1_ErrorTableEntry_T;
 
 
 /*
-  Define the Get Error Table reply structure.
+  Define the DAC960 V1 Firmware Get Error Table Command reply structure.
 */
 
-typedef struct DAC960_ErrorTable
+typedef struct DAC960_V1_ErrorTable
 {
-  DAC960_ErrorTableEntry_T
-    ErrorTableEntries[DAC960_MaxChannels][DAC960_MaxTargets];
+  DAC960_V1_ErrorTableEntry_T
+    ErrorTableEntries[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
 }
-DAC960_ErrorTable_T;
+DAC960_V1_ErrorTable_T;
 
 
 /*
-  Define the Config2 reply structure.
+  Define the DAC960 V1 Firmware Read Config2 Command reply structure.
 */
 
-typedef struct DAC960_Config2
+typedef struct DAC960_V1_Config2
 {
   unsigned char :1;					/* Byte 0 Bit 0 */
   boolean ActiveNegationEnabled:1;			/* Byte 0 Bit 1 */
@@ -576,12 +714,12 @@
   boolean AEMI_OFM:1;					/* Byte 1 Bit 6 */
   unsigned char :1;					/* Byte 1 Bit 7 */
   enum {
-    DAC960_OEMID_Mylex =			0x00,
-    DAC960_OEMID_IBM =				0x08,
-    DAC960_OEMID_HP =				0x0A,
-    DAC960_OEMID_DEC =				0x0C,
-    DAC960_OEMID_Siemens =			0x10,
-    DAC960_OEMID_Intel =			0x12
+    DAC960_V1_OEMID_Mylex =			0x00,
+    DAC960_V1_OEMID_IBM =			0x08,
+    DAC960_V1_OEMID_HP =			0x0A,
+    DAC960_V1_OEMID_DEC =			0x0C,
+    DAC960_V1_OEMID_Siemens =			0x10,
+    DAC960_V1_OEMID_Intel =			0x12
   } __attribute__ ((packed)) OEMID;			/* Byte 2 */
   unsigned char OEMModelNumber;				/* Byte 3 */
   unsigned char PhysicalSector;				/* Byte 4 */
@@ -600,21 +738,21 @@
   unsigned char BlocksPerStripe;			/* Byte 11 */
   struct {
     enum {
-      DAC960_Async =				0x00,
-      DAC960_Sync_8MHz =			0x01,
-      DAC960_Sync_5MHz =			0x02,
-      DAC960_Sync_10or20MHz =			0x03	/* Bits 0-1 */
+      DAC960_V1_Async =				0x0,
+      DAC960_V1_Sync_8MHz =			0x1,
+      DAC960_V1_Sync_5MHz =			0x2,
+      DAC960_V1_Sync_10or20MHz =		0x3	/* Byte 11 Bits 0-1 */
     } __attribute__ ((packed)) Speed:2;
-    boolean Force8Bit:1;				/* Bit 2 */
-    boolean DisableFast20:1;				/* Bit 3 */
-    unsigned char :3;					/* Bits 4-6 */
-    boolean EnableTaggedQueuing:1;			/* Bit 7 */
+    boolean Force8Bit:1;				/* Byte 11 Bit 2 */
+    boolean DisableFast20:1;				/* Byte 11 Bit 3 */
+    unsigned char :3;					/* Byte 11 Bits 4-6 */
+    boolean EnableTaggedQueuing:1;			/* Byte 11 Bit 7 */
   } __attribute__ ((packed)) ChannelParameters[6];	/* Bytes 12-17 */
   unsigned char SCSIInitiatorID;			/* Byte 18 */
   unsigned char :8;					/* Byte 19 */
   enum {
-    DAC960_StartupMode_ControllerSpinUp =	0x00,
-    DAC960_StartupMode_PowerOnSpinUp =		0x01
+    DAC960_V1_StartupMode_ControllerSpinUp =	0x00,
+    DAC960_V1_StartupMode_PowerOnSpinUp =	0x01
   } __attribute__ ((packed)) StartupMode;		/* Byte 20 */
   unsigned char SimultaneousDeviceSpinUpCount;		/* Byte 21 */
   unsigned char SecondsDelayBetweenSpinUps;		/* Byte 22 */
@@ -623,44 +761,44 @@
   boolean CDROMBootEnabled:1;				/* Byte 52 Bit 1 */
   unsigned char :3;					/* Byte 52 Bits 2-4 */
   enum {
-    DAC960_Geometry_128_32 =			0x00,
-    DAC960_Geometry_255_63 =			0x01,
-    DAC960_Geometry_Reserved1 =			0x02,
-    DAC960_Geometry_Reserved2 =			0x03
+    DAC960_V1_Geometry_128_32 =			0x0,
+    DAC960_V1_Geometry_255_63 =			0x1,
+    DAC960_V1_Geometry_Reserved1 =		0x2,
+    DAC960_V1_Geometry_Reserved2 =		0x3
   } __attribute__ ((packed)) DriveGeometry:2;		/* Byte 52 Bits 5-6 */
   unsigned char :1;					/* Byte 52 Bit 7 */
   unsigned char Reserved2[9];				/* Bytes 53-61 */
   unsigned short Checksum;				/* Bytes 62-63 */
 }
-DAC960_Config2_T;
+DAC960_V1_Config2_T;
 
 
 /*
-  Define the DCDB request structure.
+  Define the DAC960 V1 Firmware DCDB request structure.
 */
 
-typedef struct DAC960_DCDB
+typedef struct DAC960_V1_DCDB
 {
   unsigned char TargetID:4;				 /* Byte 0 Bits 0-3 */
   unsigned char Channel:4;				 /* Byte 0 Bits 4-7 */
   enum {
-    DAC960_DCDB_NoDataTransfer = 0,
-    DAC960_DCDB_DataTransferDeviceToSystem = 1,
-    DAC960_DCDB_DataTransferSystemToDevice = 2,
-    DAC960_DCDB_IllegalDataTransfer = 3
+    DAC960_V1_DCDB_NoDataTransfer =		0,
+    DAC960_V1_DCDB_DataTransferDeviceToSystem = 1,
+    DAC960_V1_DCDB_DataTransferSystemToDevice = 2,
+    DAC960_V1_DCDB_IllegalDataTransfer =	3
   } __attribute__ ((packed)) Direction:2;		 /* Byte 1 Bits 0-1 */
   boolean EarlyStatus:1;				 /* Byte 1 Bit 2 */
   unsigned char :1;					 /* Byte 1 Bit 3 */
   enum {
-    DAC960_DCDB_Timeout_24_hours = 0,
-    DAC960_DCDB_Timeout_10_seconds = 1,
-    DAC960_DCDB_Timeout_60_seconds = 2,
-    DAC960_DCDB_Timeout_10_minutes = 3
+    DAC960_V1_DCDB_Timeout_24_hours =		0,
+    DAC960_V1_DCDB_Timeout_10_seconds =		1,
+    DAC960_V1_DCDB_Timeout_60_seconds =		2,
+    DAC960_V1_DCDB_Timeout_10_minutes =		3
   } __attribute__ ((packed)) Timeout:2;			 /* Byte 1 Bits 4-5 */
   boolean NoAutomaticRequestSense:1;			 /* Byte 1 Bit 6 */
   boolean DisconnectPermitted:1;			 /* Byte 1 Bit 7 */
   unsigned short TransferLength;			 /* Bytes 2-3 */
-  DAC960_BusAddress_T BusAddress;			 /* Bytes 4-7 */
+  DAC960_BusAddress32_T BusAddress;			 /* Bytes 4-7 */
   unsigned char CDBLength:4;				 /* Byte 8 Bits 0-3 */
   unsigned char TransferLengthHigh4:4;			 /* Byte 8 Bits 4-7 */
   unsigned char SenseLength;				 /* Byte 9 */
@@ -669,387 +807,1288 @@
   unsigned char Status;					 /* Byte 86 */
   unsigned char :8;					 /* Byte 87 */
 }
-DAC960_DCDB_T;
-
-
-/*
-  Define the SCSI INQUIRY Standard Data reply structure.
-*/
-
-typedef struct DAC960_SCSI_Inquiry
-{
-  unsigned char PeripheralDeviceType:5;			/* Byte 0 Bits 0-4 */
-  unsigned char PeripheralQualifier:3;			/* Byte 0 Bits 5-7 */
-  unsigned char DeviceTypeModifier:7;			/* Byte 1 Bits 0-6 */
-  boolean RMB:1;					/* Byte 1 Bit 7 */
-  unsigned char ANSI_ApprovedVersion:3;			/* Byte 2 Bits 0-2 */
-  unsigned char ECMA_Version:3;				/* Byte 2 Bits 3-5 */
-  unsigned char ISO_Version:2;				/* Byte 2 Bits 6-7 */
-  unsigned char ResponseDataFormat:4;			/* Byte 3 Bits 0-3 */
-  unsigned char :2;					/* Byte 3 Bits 4-5 */
-  boolean TrmIOP:1;					/* Byte 3 Bit 6 */
-  boolean AENC:1;					/* Byte 3 Bit 7 */
-  unsigned char AdditionalLength;			/* Byte 4 */
-  unsigned char :8;					/* Byte 5 */
-  unsigned char :8;					/* Byte 6 */
-  boolean SftRe:1;					/* Byte 7 Bit 0 */
-  boolean CmdQue:1;					/* Byte 7 Bit 1 */
-  boolean :1;						/* Byte 7 Bit 2 */
-  boolean Linked:1;					/* Byte 7 Bit 3 */
-  boolean Sync:1;					/* Byte 7 Bit 4 */
-  boolean WBus16:1;					/* Byte 7 Bit 5 */
-  boolean WBus32:1;					/* Byte 7 Bit 6 */
-  boolean RelAdr:1;					/* Byte 7 Bit 7 */
-  unsigned char VendorIdentification[8];		/* Bytes 8-15 */
-  unsigned char ProductIdentification[16];		/* Bytes 16-31 */
-  unsigned char ProductRevisionLevel[4];		/* Bytes 32-35 */
-}
-DAC960_SCSI_Inquiry_T;
-
-
-/*
-  Define the SCSI INQUIRY Unit Serial Number reply structure.
-*/
-
-typedef struct DAC960_SCSI_Inquiry_UnitSerialNumber
-{
-  unsigned char PeripheralDeviceType:5;			/* Byte 0 Bits 0-4 */
-  unsigned char PeripheralQualifier:3;			/* Byte 0 Bits 5-7 */
-  unsigned char PageCode;				/* Byte 1 */
-  unsigned char :8;					/* Byte 2 */
-  unsigned char PageLength;				/* Byte 3 */
-  unsigned char ProductSerialNumber[28];		/* Bytes 4 - 31 */
-}
-DAC960_SCSI_Inquiry_UnitSerialNumber_T;
+DAC960_V1_DCDB_T;
 
 
 /*
-  Define the Scatter/Gather List Type 1 32 Bit Address 32 Bit Byte Count
-  structure.
+  Define the DAC960 V1 Firmware Scatter/Gather List Type 1 32 Bit Address
+  32 Bit Byte Count structure.
 */
 
-typedef struct DAC960_ScatterGatherSegment
+typedef struct DAC960_V1_ScatterGatherSegment
 {
-  DAC960_BusAddress_T SegmentDataPointer;		/* Bytes 0-3 */
-  DAC960_ByteCount_T SegmentByteCount;			/* Bytes 4-7 */
+  DAC960_BusAddress32_T SegmentDataPointer;		/* Bytes 0-3 */
+  DAC960_ByteCount32_T SegmentByteCount;		/* Bytes 4-7 */
 }
-DAC960_ScatterGatherSegment_T;
+DAC960_V1_ScatterGatherSegment_T;
 
 
 /*
-  Define the 13 Byte DAC960 Command Mailbox structure.  Bytes 13-15 are
-  not used.  The Command Mailbox structure is padded to 16 bytes for
+  Define the 13 Byte DAC960 V1 Firmware Command Mailbox structure.  Bytes 13-15
+  are not used.  The Command Mailbox structure is padded to 16 bytes for
   efficient access.
 */
 
-typedef union DAC960_CommandMailbox
+typedef union DAC960_V1_CommandMailbox
 {
   unsigned int Words[4];				/* Words 0-3 */
   unsigned char Bytes[16];				/* Bytes 0-15 */
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned char Dummy[14];				/* Bytes 2-15 */
   } __attribute__ ((packed)) Common;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned char Dummy1[6];				/* Bytes 2-7 */
-    DAC960_BusAddress_T BusAddress;			/* Bytes 8-11 */
+    DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
     unsigned char Dummy2[4];				/* Bytes 12-15 */
   } __attribute__ ((packed)) Type3;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned char Dummy1[5];				/* Bytes 2-6 */
     unsigned char LogicalDriveNumber:6;			/* Byte 7 Bits 0-6 */
     boolean AutoRestore:1;				/* Byte 7 Bit 7 */
     unsigned char Dummy2[8];				/* Bytes 8-15 */
   } __attribute__ ((packed)) Type3C;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned char Channel;				/* Byte 2 */
     unsigned char TargetID;				/* Byte 3 */
-    DAC960_PhysicalDeviceState_T DeviceState:5;		/* Byte 4 Bits 0-4 */
+    DAC960_V1_PhysicalDeviceState_T DeviceState:5;	/* Byte 4 Bits 0-4 */
     unsigned char Modifier:3;				/* Byte 4 Bits 5-7 */
     unsigned char Dummy1[3];				/* Bytes 5-7 */
-    DAC960_BusAddress_T BusAddress;			/* Bytes 8-11 */
+    DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
     unsigned char Dummy2[4];				/* Bytes 12-15 */
   } __attribute__ ((packed)) Type3D;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
-    DAC960_PerformEventLogOpType_T OperationType;	/* Byte 2 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_PerformEventLogOpType_T OperationType;	/* Byte 2 */
     unsigned char OperationQualifier;			/* Byte 3 */
     unsigned short SequenceNumber;			/* Bytes 4-5 */
     unsigned char Dummy1[2];				/* Bytes 6-7 */
-    DAC960_BusAddress_T BusAddress;			/* Bytes 8-11 */
+    DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
     unsigned char Dummy2[4];				/* Bytes 12-15 */
   } __attribute__ ((packed)) Type3E;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned char Dummy1[2];				/* Bytes 2-3 */
     unsigned char RebuildRateConstant;			/* Byte 4 */
     unsigned char Dummy2[3];				/* Bytes 5-7 */
-    DAC960_BusAddress_T BusAddress;			/* Bytes 8-11 */
+    DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
     unsigned char Dummy3[4];				/* Bytes 12-15 */
   } __attribute__ ((packed)) Type3R;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned short TransferLength;			/* Bytes 2-3 */
     unsigned int LogicalBlockAddress;			/* Bytes 4-7 */
-    DAC960_BusAddress_T BusAddress;			/* Bytes 8-11 */
+    DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
     unsigned char LogicalDriveNumber;			/* Byte 12 */
     unsigned char Dummy[3];				/* Bytes 13-15 */
   } __attribute__ ((packed)) Type4;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     struct {
       unsigned short TransferLength:11;			/* Bytes 2-3 */
       unsigned char LogicalDriveNumber:5;		/* Byte 3 Bits 3-7 */
     } __attribute__ ((packed)) LD;
     unsigned int LogicalBlockAddress;			/* Bytes 4-7 */
-    DAC960_BusAddress_T BusAddress;			/* Bytes 8-11 */
+    DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
     unsigned char ScatterGatherCount:6;			/* Byte 12 Bits 0-5 */
     enum {
-      DAC960_ScatterGather_32BitAddress_32BitByteCount =	0x0,
-      DAC960_ScatterGather_32BitAddress_16BitByteCount =	0x1,
-      DAC960_ScatterGather_32BitByteCount_32BitAddress =	0x2,
-      DAC960_ScatterGather_16BitByteCount_32BitAddress =	0x3
+      DAC960_V1_ScatterGather_32BitAddress_32BitByteCount = 0x0,
+      DAC960_V1_ScatterGather_32BitAddress_16BitByteCount = 0x1,
+      DAC960_V1_ScatterGather_32BitByteCount_32BitAddress = 0x2,
+      DAC960_V1_ScatterGather_16BitByteCount_32BitAddress = 0x3
     } __attribute__ ((packed)) ScatterGatherType:2;	/* Byte 12 Bits 6-7 */
     unsigned char Dummy[3];				/* Bytes 13-15 */
   } __attribute__ ((packed)) Type5;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned char CommandOpcode2;			/* Byte 2 */
     unsigned char :8;					/* Byte 3 */
-    DAC960_BusAddress_T CommandMailboxesBusAddress;	/* Bytes 4-7 */
-    DAC960_BusAddress_T StatusMailboxesBusAddress;	/* Bytes 8-11 */
+    DAC960_BusAddress32_T CommandMailboxesBusAddress;	/* Bytes 4-7 */
+    DAC960_BusAddress32_T StatusMailboxesBusAddress;	/* Bytes 8-11 */
     unsigned char Dummy[4];				/* Bytes 12-15 */
   } __attribute__ ((packed)) TypeX;
 }
-DAC960_CommandMailbox_T;
+DAC960_V1_CommandMailbox_T;
 
 
 /*
-  Define the DAC960 Driver IOCTL requests.
+  Define the DAC960 V2 Firmware Command Opcodes.
 */
 
-#define DAC960_IOCTL_GET_CONTROLLER_COUNT	0xDAC001
-#define DAC960_IOCTL_GET_CONTROLLER_INFO	0xDAC002
-#define DAC960_IOCTL_EXECUTE_COMMAND		0xDAC003
+typedef enum
+{
+  DAC960_V2_MemCopy =				0x01,
+  DAC960_V2_SCSI_10_Passthru =			0x02,
+  DAC960_V2_SCSI_255_Passthru =			0x03,
+  DAC960_V2_SCSI_10 =				0x04,
+  DAC960_V2_SCSI_256 =				0x05,
+  DAC960_V2_IOCTL =				0x20
+}
+__attribute__ ((packed))
+DAC960_V2_CommandOpcode_T;
 
 
 /*
-  Define the DAC960_IOCTL_GET_CONTROLLER_INFO reply structure.
+  Define the DAC960 V2 Firmware IOCTL Opcodes.
 */
 
-typedef struct DAC960_ControllerInfo
+typedef enum
 {
-  unsigned char ControllerNumber;
-  unsigned char PCI_Bus;
-  unsigned char PCI_Device;
-  unsigned char PCI_Function;
-  unsigned char IRQ_Channel;
-  unsigned char Channels;
-  DAC960_PCI_Address_T PCI_Address;
-  unsigned char ModelName[16];
-  unsigned char FirmwareVersion[16];
+  DAC960_V2_GetControllerInfo =			0x01,
+  DAC960_V2_GetLogicalDeviceInfoValid =		0x03,
+  DAC960_V2_GetPhysicalDeviceInfoValid =	0x05,
+  DAC960_V2_GetHealthStatus =			0x11,
+  DAC960_V2_GetEvent =				0x15,
+  DAC960_V2_SetDeviceState =			0x82,
+  DAC960_V2_RebuildDeviceStart =		0x88,
+  DAC960_V2_RebuildDeviceStop =			0x89,
+  DAC960_V2_ConsistencyCheckStart =		0x8C,
+  DAC960_V2_ConsistencyCheckStop =		0x8D,
+  DAC960_V2_SetMemoryMailbox =			0x8E,
+  DAC960_V2_PauseDevice =			0x92,
+  DAC960_V2_TranslatePhysicalToLogicalDevice =	0xC5
 }
-DAC960_ControllerInfo_T;
+__attribute__ ((packed))
+DAC960_V2_IOCTL_Opcode_T;
 
 
 /*
-  Define the User Mode DAC960_IOCTL_EXECUTE_COMMAND request structure.
+  Define the DAC960 V2 Firmware Command Identifier type.
 */
 
-typedef struct DAC960_UserCommand
-{
-  unsigned char ControllerNumber;
-  DAC960_CommandMailbox_T CommandMailbox;
-  int DataTransferLength;
-  void *DataTransferBuffer;
-  DAC960_DCDB_T *DCDB;
-}
-DAC960_UserCommand_T;
+typedef unsigned short DAC960_V2_CommandIdentifier_T;
 
 
 /*
-  Define the Kernel Mode DAC960_IOCTL_EXECUTE_COMMAND request structure.
+  Define the DAC960 V2 Firmware Command Status Codes.
 */
 
-typedef struct DAC960_KernelCommand
-{
-  unsigned char ControllerNumber;
-  DAC960_CommandMailbox_T CommandMailbox;
-  int DataTransferLength;
-  void *DataTransferBuffer;
-  DAC960_DCDB_T *DCDB;
-  DAC960_CommandStatus_T CommandStatus;
-  void (*CompletionFunction)(struct DAC960_KernelCommand *);
-  void *CompletionData;
-}
-DAC960_KernelCommand_T;
+#define DAC960_V2_NormalCompletion		0x00
+#define DAC960_V2_AbormalCompletion		0x02
+#define DAC960_V2_DeviceNonresponsive		0x0E
+
+typedef unsigned char DAC960_V2_CommandStatus_T;
 
 
 /*
-  Import the Kernel Mode IOCTL interface.
+  Define the DAC960 V2 Firmware Memory Type structure.
 */
 
-extern int DAC960_KernelIOCTL(unsigned int Request, void *Argument);
+typedef struct DAC960_V2_MemoryType
+{
+  enum {
+    DAC960_V2_MemoryType_Reserved =		0x00,
+    DAC960_V2_MemoryType_DRAM =			0x01,
+    DAC960_V2_MemoryType_EDRAM =		0x02,
+    DAC960_V2_MemoryType_EDO =			0x03,
+    DAC960_V2_MemoryType_SDRAM =		0x04
+  } __attribute__ ((packed)) MemoryType:5;		/* Byte 0 Bits 0-4 */
+  boolean :1;						/* Byte 0 Bit 5 */
+  boolean MemoryParity:1;				/* Byte 0 Bit 6 */
+  boolean MemoryECC:1;					/* Byte 0 Bit 7 */
+}
+DAC960_V2_MemoryType_T;
 
 
 /*
-  Virtual_to_Bus maps from Kernel Virtual Addresses to PCI Bus Addresses.
+  Define the DAC960 V2 Firmware Processor Type structure.
 */
 
-static inline DAC960_BusAddress_T Virtual_to_Bus(void *VirtualAddress)
+typedef enum
 {
-  return (DAC960_BusAddress_T) virt_to_bus(VirtualAddress);
+  DAC960_V2_ProcessorType_i960CA =		0x01,
+  DAC960_V2_ProcessorType_i960RD =		0x02,
+  DAC960_V2_ProcessorType_i960RN =		0x03,
+  DAC960_V2_ProcessorType_i960RP =		0x04,
+  DAC960_V2_ProcessorType_NorthBay =		0x05,
+  DAC960_V2_ProcessorType_StrongArm =		0x06,
+  DAC960_V2_ProcessorType_i960RM =		0x07
 }
+__attribute__ ((packed))
+DAC960_V2_ProcessorType_T;
 
 
 /*
-  Bus_to_Virtual maps from PCI Bus Addresses to Kernel Virtual Addresses.
+  Define the DAC960 V2 Firmware Get Controller Info reply structure.
 */
 
-static inline void *Bus_to_Virtual(DAC960_BusAddress_T BusAddress)
+typedef struct DAC960_V2_ControllerInfo
 {
-  return (void *) bus_to_virt(BusAddress);
+  unsigned char :8;					/* Byte 0 */
+  enum {
+    DAC960_V2_SCSI_Bus =			0x00,
+    DAC960_V2_Fibre_Bus =			0x01,
+    DAC960_V2_PCI_Bus =				0x03
+  } __attribute__ ((packed)) BusInterfaceType;		/* Byte 1 */
+  enum {
+    DAC960_V2_DAC960E =				0x01,
+    DAC960_V2_DAC960M =				0x08,
+    DAC960_V2_DAC960PD =			0x10,
+    DAC960_V2_DAC960PL =			0x11,
+    DAC960_V2_DAC960PU =			0x12,
+    DAC960_V2_DAC960PE =			0x13,
+    DAC960_V2_DAC960PG =			0x14,
+    DAC960_V2_DAC960PJ =			0x15,
+    DAC960_V2_DAC960PTL0 =			0x16,
+    DAC960_V2_DAC960PR =			0x17,
+    DAC960_V2_DAC960PRL =			0x18,
+    DAC960_V2_DAC960PT =			0x19,
+    DAC960_V2_DAC1164P =			0x1A,
+    DAC960_V2_DAC960PTL1 =			0x1B,
+    DAC960_V2_EXR2000P =			0x1C,
+    DAC960_V2_EXR3000P =			0x1D,
+    DAC960_V2_AcceleRAID352 =			0x1E,
+    DAC960_V2_AcceleRAID351 =			0x1F,
+    DAC960_V2_DAC960S =				0x60,
+    DAC960_V2_DAC960SU =			0x61,
+    DAC960_V2_DAC960SX =			0x62,
+    DAC960_V2_DAC960SF =			0x63,
+    DAC960_V2_DAC960SS =			0x64,
+    DAC960_V2_DAC960FL =			0x65,
+    DAC960_V2_DAC960LL =			0x66,
+    DAC960_V2_DAC960FF =			0x67,
+    DAC960_V2_DAC960HP =			0x68,
+    DAC960_V2_RAIDBRICK =			0x69,
+    DAC960_V2_METEOR_FL =			0x6A,
+    DAC960_V2_METEOR_FF =			0x6B
+  } __attribute__ ((packed)) ControllerType;		/* Byte 2 */
+  unsigned char :8;					/* Byte 3 */
+  unsigned short BusInterfaceSpeedMHz;			/* Bytes 4-5 */
+  unsigned char BusWidthBits;				/* Byte 6 */
+  unsigned char Reserved1[9];				/* Bytes 7-15 */
+  unsigned char BusInterfaceName[16];			/* Bytes 16-31 */
+  unsigned char ControllerName[16];			/* Bytes 32-47 */
+  unsigned char Reserved2[16];				/* Bytes 48-63 */
+  /* Firmware Release Information */
+  unsigned char FirmwareMajorVersion;			/* Byte 64 */
+  unsigned char FirmwareMinorVersion;			/* Byte 65 */
+  unsigned char FirmwareTurnNumber;			/* Byte 66 */
+  unsigned char FirmwareBuildNumber;			/* Byte 67 */
+  unsigned char FirmwareReleaseDay;			/* Byte 68 */
+  unsigned char FirmwareReleaseMonth;			/* Byte 69 */
+  unsigned char FirmwareReleaseYearHigh2Digits;		/* Byte 70 */
+  unsigned char FirmwareReleaseYearLow2Digits;		/* Byte 71 */
+  /* Hardware Release Information */
+  unsigned char HardwareRevision;			/* Byte 72 */
+  unsigned int :24;					/* Bytes 73-75 */
+  unsigned char HardwareReleaseDay;			/* Byte 76 */
+  unsigned char HardwareReleaseMonth;			/* Byte 77 */
+  unsigned char HardwareReleaseYearHigh2Digits;		/* Byte 78 */
+  unsigned char HardwareReleaseYearLow2Digits;		/* Byte 79 */
+  /* Hardware Manufacturing Information */
+  unsigned char ManufacturingBatchNumber;		/* Byte 80 */
+  unsigned char :8;					/* Byte 81 */
+  unsigned char ManufacturingPlantNumber;		/* Byte 82 */
+  unsigned char :8;					/* Byte 83 */
+  unsigned char HardwareManufacturingDay;		/* Byte 84 */
+  unsigned char HardwareManufacturingMonth;		/* Byte 85 */
+  unsigned char HardwareManufacturingYearHigh2Digits;	/* Byte 86 */
+  unsigned char HardwareManufacturingYearLow2Digits;	/* Byte 87 */
+  unsigned char MaximumNumberOfPDDperXLDD;		/* Byte 88 */
+  unsigned char MaximumNumberOfILDDperXLDD;		/* Byte 89 */
+  unsigned short NonvolatileMemorySizeKB;		/* Bytes 90-91 */
+  unsigned char MaximumNumberOfXLDD;			/* Byte 92 */
+  unsigned int :24;					/* Bytes 93-95 */
+  /* Unique Information per Controller */
+  unsigned char ControllerSerialNumber[16];		/* Bytes 96-111 */
+  unsigned char Reserved3[16];				/* Bytes 112-127 */
+  /* Vendor Information */
+  unsigned int :24;					/* Bytes 128-130 */
+  unsigned char OEM_Information;			/* Byte 131 */
+  unsigned char VendorName[16];				/* Bytes 132-147 */
+  /* Other Physical/Controller/Operation Information */
+  boolean BBU_Present:1;				/* Byte 148 Bit 0 */
+  boolean ActiveActiveClusteringMode:1;			/* Byte 148 Bit 1 */
+  unsigned char :6;					/* Byte 148 Bits 2-7 */
+  unsigned char :8;					/* Byte 149 */
+  unsigned short :16;					/* Bytes 150-151 */
+  /* Physical Device Scan Information */
+  boolean PhysicalScanActive:1;				/* Byte 152 Bit 0 */
+  unsigned char :7;					/* Byte 152 Bits 1-7 */
+  unsigned char PhysicalDeviceChannelNumber;		/* Byte 153 */
+  unsigned char PhysicalDeviceTargetID;			/* Byte 154 */
+  unsigned char PhysicalDeviceLogicalUnit;		/* Byte 155 */
+  /* Maximum Command Data Transfer Sizes */
+  unsigned short MaximumDataTransferSizeInBlocks;	/* Bytes 156-157 */
+  unsigned short MaximumScatterGatherEntries;		/* Bytes 158-159 */
+  /* Logical/Physical Device Counts */
+  unsigned short LogicalDevicesPresent;			/* Bytes 160-161 */
+  unsigned short LogicalDevicesCritical;		/* Bytes 162-163 */
+  unsigned short LogicalDevicesOffline;			/* Bytes 164-165 */
+  unsigned short PhysicalDevicesPresent;		/* Bytes 166-167 */
+  unsigned short PhysicalDisksPresent;			/* Bytes 168-169 */
+  unsigned short PhysicalDisksCritical;			/* Bytes 170-171 */
+  unsigned short PhysicalDisksOffline;			/* Bytes 172-173 */
+  unsigned short MaximumParallelCommands;		/* Bytes 174-175 */
+  /* Channel and Target ID Information */
+  unsigned char NumberOfPhysicalChannelsPresent;	/* Byte 176 */
+  unsigned char NumberOfVirtualChannelsPresent;		/* Byte 177 */
+  unsigned char NumberOfPhysicalChannelsPossible;	/* Byte 178 */
+  unsigned char NumberOfVirtualChannelsPossible;	/* Byte 179 */
+  unsigned char MaximumTargetsPerChannel[16];		/* Bytes 180-195 */
+  unsigned char Reserved4[12];				/* Bytes 196-207 */
+  /* Memory/Cache Information */
+  unsigned short MemorySizeMB;				/* Bytes 208-209 */
+  unsigned short CacheSizeMB;				/* Bytes 210-211 */
+  unsigned int ValidCacheSizeInBytes;			/* Bytes 212-215 */
+  unsigned int DirtyCacheSizeInBytes;			/* Bytes 216-219 */
+  unsigned short MemorySpeedMHz;			/* Bytes 220-221 */
+  unsigned char MemoryDataWidthBits;			/* Byte 222 */
+  DAC960_V2_MemoryType_T MemoryType;			/* Byte 223 */
+  unsigned char CacheMemoryTypeName[16];		/* Bytes 224-239 */
+  /* Execution Memory Information */
+  unsigned short ExecutionMemorySizeMB;			/* Bytes 240-241 */
+  unsigned short ExecutionL2CacheSizeMB;		/* Bytes 242-243 */
+  unsigned char Reserved5[8];				/* Bytes 244-251 */
+  unsigned short ExecutionMemorySpeedMHz;		/* Bytes 252-253 */
+  unsigned char ExecutionMemoryDataWidthBits;		/* Byte 254 */
+  DAC960_V2_MemoryType_T ExecutionMemoryType;		/* Byte 255 */
+  unsigned char ExecutionMemoryTypeName[16];		/* Bytes 256-271 */
+  /* First CPU Type Information */
+  unsigned short FirstProcessorSpeedMHz;		/* Bytes 272-273 */
+  DAC960_V2_ProcessorType_T FirstProcessorType;		/* Byte 274 */
+  unsigned char FirstProcessorCount;			/* Byte 275 */
+  unsigned char Reserved6[12];				/* Bytes 276-287 */
+  unsigned char FirstProcessorName[16];			/* Bytes 288-303 */
+  /* Second CPU Type Information */
+  unsigned short SecondProcessorSpeedMHz;		/* Bytes 304-305 */
+  DAC960_V2_ProcessorType_T SecondProcessorType;	/* Byte 306 */
+  unsigned char SecondProcessorCount;			/* Byte 307 */
+  unsigned char Reserved7[12];				/* Bytes 308-319 */
+  unsigned char SecondProcessorName[16];		/* Bytes 320-335 */
+  /* Debugging/Profiling/Command Time Tracing Information */
+  unsigned short CurrentProfilingDataPageNumber;	/* Bytes 336-337 */
+  unsigned short ProgramsAwaitingProfilingData;		/* Bytes 338-339 */
+  unsigned short CurrentCommandTimeTraceDataPageNumber;	/* Bytes 340-341 */
+  unsigned short ProgramsAwaitingCommandTimeTraceData;	/* Bytes 342-343 */
+  unsigned char Reserved8[8];				/* Bytes 344-351 */
+  /* Error Counters on Physical Devices */
+  unsigned short PhysicalDeviceBusResets;		/* Bytes 352-353 */
+  unsigned short PhysicalDeviceParityErrors;		/* Bytes 355-355 */
+  unsigned short PhysicalDeviceSoftErrors;		/* Bytes 356-357 */
+  unsigned short PhysicalDeviceCommandsFailed;		/* Bytes 358-359 */
+  unsigned short PhysicalDeviceMiscellaneousErrors;	/* Bytes 360-361 */
+  unsigned short PhysicalDeviceCommandTimeouts;		/* Bytes 362-363 */
+  unsigned short PhysicalDeviceSelectionTimeouts;	/* Bytes 364-365 */
+  unsigned short PhysicalDeviceRetriesDone;		/* Bytes 366-367 */
+  unsigned short PhysicalDeviceAbortsDone;		/* Bytes 368-369 */
+  unsigned short PhysicalDeviceHostCommandAbortsDone;	/* Bytes 370-371 */
+  unsigned short PhysicalDevicePredictedFailuresDetected; /* Bytes 372-373 */
+  unsigned short PhysicalDeviceHostCommandsFailed;	/* Bytes 374-375 */
+  unsigned char Reserved9[8];				/* Bytes 376-383 */
+  /* Error Counters on Logical Devices */
+  unsigned short LogicalDeviceSoftErrors;		/* Bytes 384-385 */
+  unsigned short LogicalDeviceCommandsFailed;		/* Bytes 386-387 */
+  unsigned short LogicalDeviceHostCommandAbortsDone;	/* Bytes 388-389 */
+  unsigned short :16;					/* Bytes 390-391 */
+  unsigned short ControllerMemoryErrors;		/* Bytes 392-393 */
+  unsigned short ControllerHostCommandAbortsDone;	/* Bytes 394-395 */
+  unsigned int :32;					/* Bytes 396-399 */
+  /* Long Duration Activity Information */
+  unsigned short BackgroundInitializationsActive;	/* Bytes 400-401 */
+  unsigned short LogicalDeviceInitializationsActive;	/* Bytes 402-403 */
+  unsigned short PhysicalDeviceInitializationsActive;	/* Bytes 404-405 */
+  unsigned short ConsistencyChecksActive;		/* Bytes 406-407 */
+  unsigned short RebuildsActive;			/* Bytes 408-409 */
+  unsigned short OnlineExpansionsActive;		/* Bytes 410-411 */
+  unsigned short PatrolActivitiesActive;		/* Bytes 412-413 */
+  unsigned char LongOperationStatus;			/* Byte 414 */
+  unsigned char :8;					/* Byte 415 */
+  /* Flash ROM Information */
+  unsigned char FlashType;				/* Byte 416 */
+  unsigned char :8;					/* Byte 417 */
+  unsigned short FlashSizeMB;				/* Bytes 418-419 */
+  unsigned int FlashLimit;				/* Bytes 420-423 */
+  unsigned int FlashCount;				/* Bytes 424-427 */
+  unsigned int :32;					/* Bytes 428-431 */
+  unsigned char FlashTypeName[16];			/* Bytes 432-447 */
+  /* Firmware Run Time Information */
+  unsigned char RebuildRate;				/* Byte 448 */
+  unsigned char BackgroundInitializationRate;		/* Byte 449 */
+  unsigned char ForegroundInitializationRate;		/* Byte 450 */
+  unsigned char ConsistencyCheckRate;			/* Byte 451 */
+  unsigned int :32;					/* Bytes 452-455 */
+  unsigned int MaximumDP;				/* Bytes 456-459 */
+  unsigned int FreeDP;					/* Bytes 460-463 */
+  unsigned int MaximumIOP;				/* Bytes 464-467 */
+  unsigned int FreeIOP;					/* Bytes 468-471 */
+  unsigned short MaximumCombLengthInBlocks;		/* Bytes 472-473 */
+  unsigned short NumberOfConfigurationGroups;		/* Bytes 474-475 */
+  boolean InstallationAbortStatus:1;			/* Byte 476 Bit 0 */
+  boolean MaintenanceModeStatus:1;			/* Byte 476 Bit 1 */
+  unsigned int :6;					/* Byte 476 Bits 2-7 */
+  unsigned int :24;					/* Bytes 477-479 */
+  unsigned char Reserved10[32];				/* Bytes 480-511 */
+  unsigned char Reserved11[512];			/* Bytes 512-1023 */
 }
+DAC960_V2_ControllerInfo_T;
 
 
 /*
-  DAC960_DriverVersion protects the private portion of this file.
+  Define the DAC960 V2 Firmware Logical Device State type.
 */
 
-#ifdef DAC960_DriverVersion
+typedef enum
+{
+  DAC960_V2_LogicalDevice_Online =		0x01,
+  DAC960_V2_LogicalDevice_Offline =		0x08,
+  DAC960_V2_LogicalDevice_Critical =		0x09
+}
+__attribute__ ((packed))
+DAC960_V2_LogicalDeviceState_T;
 
 
 /*
-  Define the maximum Driver Queue Depth and Controller Queue Depth supported
-  by any DAC960 model.
+  Define the DAC960 V2 Firmware Get Logical Device Info reply structure.
 */
 
-#define DAC960_MaxDriverQueueDepth		127
-#define DAC960_MaxControllerQueueDepth		128
+typedef struct DAC960_V2_LogicalDeviceInfo
+{
+  unsigned char :8;					/* Byte 0 */
+  unsigned char Channel;				/* Byte 1 */
+  unsigned char TargetID;				/* Byte 2 */
+  unsigned char LogicalUnit;				/* Byte 3 */
+  DAC960_V2_LogicalDeviceState_T LogicalDeviceState;	/* Byte 4 */
+  unsigned char RAIDLevel;				/* Byte 5 */
+  unsigned char StripeSize;				/* Byte 6 */
+  unsigned char CacheLineSize;				/* Byte 7 */
+  struct {
+    enum {
+      DAC960_V2_ReadCacheDisabled =		0x0,
+      DAC960_V2_ReadCacheEnabled =		0x1,
+      DAC960_V2_ReadAheadEnabled =		0x2,
+      DAC960_V2_IntelligentReadAheadEnabled =	0x3
+    } __attribute__ ((packed)) ReadCache:3;		/* Byte 8 Bits 0-2 */
+    enum {
+      DAC960_V2_WriteCacheDisabled =		0x0,
+      DAC960_V2_LogicalDeviceReadOnly =		0x1,
+      DAC960_V2_WriteCacheEnabled =		0x2,
+      DAC960_V2_IntelligentWriteCacheEnabled =	0x3
+    } __attribute__ ((packed)) WriteCache:3;		/* Byte 8 Bits 3-5 */
+    boolean :1;						/* Byte 8 Bit 6 */
+    boolean LogicalDeviceInitialized:1;			/* Byte 8 Bit 7 */
+  } LogicalDeviceControl;				/* Byte 8 */
+  /* Logical Device Operations Status */
+  boolean ConsistencyCheckInProgress:1;			/* Byte 9 Bit 0 */
+  boolean RebuildInProgress:1;				/* Byte 9 Bit 1 */
+  boolean BackgroundInitializationInProgress:1;		/* Byte 9 Bit 2 */
+  boolean ForegroundInitializationInProgress:1;		/* Byte 9 Bit 3 */
+  boolean DataMigrationInProgress:1;			/* Byte 9 Bit 4 */
+  boolean PatrolOperationInProgress:1;			/* Byte 9 Bit 5 */
+  unsigned char :2;					/* Byte 9 Bits 6-7 */
+  unsigned char RAID5WriteUpdate;			/* Byte 10 */
+  unsigned char RAID5Algorithm;				/* Byte 11 */
+  unsigned short LogicalDeviceNumber;			/* Bytes 12-13 */
+  /* BIOS Info */
+  boolean BIOSDisabled:1;				/* Byte 14 Bit 0 */
+  boolean CDROMBootEnabled:1;				/* Byte 14 Bit 1 */
+  boolean DriveCoercionEnabled:1;			/* Byte 14 Bit 2 */
+  boolean WriteSameDisabled:1;				/* Byte 14 Bit 3 */
+  boolean HBA_ModeEnabled:1;				/* Byte 14 Bit 4 */
+  enum {
+    DAC960_V2_Geometry_128_32 =			0x0,
+    DAC960_V2_Geometry_255_63 =			0x1,
+    DAC960_V2_Geometry_Reserved1 =		0x2,
+    DAC960_V2_Geometry_Reserved2 =		0x3
+  } __attribute__ ((packed)) DriveGeometry:2;		/* Byte 14 Bits 5-6 */
+  unsigned char :1;					/* Byte 14 Bit 7 */
+  unsigned char :8;					/* Byte 15 */
+  /* Error Counters */
+  unsigned short SoftErrors;				/* Bytes 16-17 */
+  unsigned short CommandsFailed;			/* Bytes 18-19 */
+  unsigned short HostCommandAbortsDone;			/* Bytes 20-21 */
+  unsigned short DeferredWriteErrors;			/* Bytes 22-23 */
+  unsigned int :32;					/* Bytes 24-27 */
+  unsigned int :32;					/* Bytes 28-31 */
+  /* Device Size Information */
+  unsigned short :16;					/* Bytes 32-33 */
+  unsigned short DeviceBlockSizeInBytes;		/* Bytes 34-35 */
+  unsigned int OriginalDeviceSizeIn512ByteBlocksOrMB;	/* Bytes 36-39 */
+  unsigned int ConfigurableDeviceSizeIn512ByteBlocksOrMB; /* Bytes 40-43 */
+  unsigned int :32;					/* Bytes 44-47 */
+  unsigned char LogicalDeviceName[32];			/* Bytes 48-79 */
+  unsigned char SCSI_InquiryData[36];			/* Bytes 80-115 */
+  unsigned char Reserved1[12];				/* Bytes 116-127 */
+  DAC960_ByteCount64_T LastReadBlockNumber;		/* Bytes 128-135 */
+  DAC960_ByteCount64_T LastWrittenBlockNumber;		/* Bytes 136-143 */
+  DAC960_ByteCount64_T ConsistencyCheckBlockNumber;	/* Bytes 144-151 */
+  DAC960_ByteCount64_T RebuildBlockNumber;		/* Bytes 152-159 */
+  DAC960_ByteCount64_T BackgroundInitializationBlockNumber; /* Bytes 160-167 */
+  DAC960_ByteCount64_T ForegroundInitializationBlockNumber; /* Bytes 168-175 */
+  DAC960_ByteCount64_T DataMigrationBlockNumber;	/* Bytes 176-183 */
+  DAC960_ByteCount64_T PatrolOperationBlockNumber;	/* Bytes 184-191 */
+  unsigned char Reserved2[64];				/* Bytes 192-255 */
+}
+DAC960_V2_LogicalDeviceInfo_T;
 
 
 /*
-  Define the maximum number of Scatter/Gather Segments supported by any
-  DAC960 model.
+  Define the DAC960 V2 Firmware Physical Device State type.
 */
 
-#define DAC960_MaxScatterGatherSegments		33
+typedef enum
+{
+    DAC960_V2_Device_Unconfigured =		0x00,
+    DAC960_V2_Device_Online =			0x01,
+    DAC960_V2_Device_WriteOnly =		0x03,
+    DAC960_V2_Device_Dead =			0x08,
+    DAC960_V2_Device_Standby =			0x21,
+    DAC960_V2_Device_InvalidState =		0xFF
+}
+__attribute__ ((packed))
+DAC960_V2_PhysicalDeviceState_T;
 
 
 /*
-  Define the number of Command Mailboxes and Status Mailboxes used by the
-  Memory Mailbox Interface.
+  Define the DAC960 V2 Firmware Get Physical Device Info reply structure.
 */
 
-#define DAC960_CommandMailboxCount		256
-#define DAC960_StatusMailboxCount		1024
+typedef struct DAC960_V2_PhysicalDeviceInfo
+{
+  unsigned char :8;					/* Byte 0 */
+  unsigned char Channel;				/* Byte 1 */
+  unsigned char TargetID;				/* Byte 2 */
+  unsigned char LogicalUnit;				/* Byte 3 */
+  /* Configuration Status Bits */
+  boolean PhysicalDeviceFaultTolerant:1;		/* Byte 4 Bit 0 */
+  boolean :1;						/* Byte 4 Bit 1 */
+  boolean PhysicalDeviceLocalToController:1;		/* Byte 4 Bit 2 */
+  unsigned char :5;					/* Byte 4 Bits 3-7 */
+  /* Multiple Host/Controller Status Bits */
+  boolean RemoteHostSystemDead:1;			/* Byte 5 Bit 0 */
+  boolean RemoteControllerDead:1;			/* Byte 5 Bit 1 */
+  unsigned char :6;					/* Byte 5 Bits 2-7 */
+  DAC960_V2_PhysicalDeviceState_T PhysicalDeviceState;	/* Byte 6 */
+  unsigned char NegotiatedDataWidthBits;		/* Byte 7 */
+  unsigned short NegotiatedSynchronousMegaTransfers;	/* Bytes 8-9 */
+  /* Multiported Physical Device Information */
+  unsigned char NumberOfPortConnections;		/* Byte 10 */
+  unsigned char DriveAccessibilityBitmap;		/* Byte 11 */
+  unsigned int :32;					/* Bytes 12-15 */
+  unsigned char NetworkAddress[16];			/* Bytes 16-31 */
+  unsigned short MaximumTags;				/* Bytes 32-33 */
+  /* Physical Device Operations Status */
+  boolean ConsistencyCheckInProgress:1;			/* Byte 34 Bit 0 */
+  boolean RebuildInProgress:1;				/* Byte 34 Bit 1 */
+  boolean MakingDataConsistentInProgress:1;		/* Byte 34 Bit 2 */
+  boolean PhysicalDeviceInitializationInProgress:1;	/* Byte 34 Bit 3 */
+  boolean DataMigrationInProgress:1;			/* Byte 34 Bit 4 */
+  boolean PatrolOperationInProgress:1;			/* Byte 34 Bit 5 */
+  unsigned char :2;					/* Byte 34 Bits 6-7 */
+  unsigned char LongOperationStatus;			/* Byte 35 */
+  unsigned char ParityErrors;				/* Byte 36 */
+  unsigned char SoftErrors;				/* Byte 37 */
+  unsigned char HardErrors;				/* Byte 38 */
+  unsigned char MiscellaneousErrors;			/* Byte 39 */
+  unsigned char CommandTimeouts;			/* Byte 40 */
+  unsigned char Retries;				/* Byte 41 */
+  unsigned char Aborts;					/* Byte 42 */
+  unsigned char PredictedFailuresDetected;		/* Byte 43 */
+  unsigned int :32;					/* Bytes 44-47 */
+  unsigned short :16;					/* Bytes 48-49 */
+  unsigned short DeviceBlockSizeInBytes;		/* Bytes 50-51 */
+  unsigned int OriginalDeviceSizeIn512ByteBlocksOrMB;	/* Bytes 52-55 */
+  unsigned int ConfigurableDeviceSizeIn512ByteBlocksOrMB; /* Bytes 56-59 */
+  unsigned int :32;					/* Bytes 60-63 */
+  unsigned char PhysicalDeviceName[16];			/* Bytes 64-79 */
+  unsigned char Reserved1[16];				/* Bytes 80-95 */
+  unsigned char Reserved2[32];				/* Bytes 96-127 */
+  unsigned char SCSI_InquiryData[36];			/* Bytes 128-163 */
+  unsigned char Reserved3[12];				/* Bytes 164-175 */
+  unsigned char Reserved4[16];				/* Bytes 176-191 */
+  DAC960_ByteCount64_T LastReadBlockNumber;		/* Bytes 192-199 */
+  DAC960_ByteCount64_T LastWrittenBlockNumber;		/* Bytes 200-207 */
+  DAC960_ByteCount64_T ConsistencyCheckBlockNumber;	/* Bytes 208-215 */
+  DAC960_ByteCount64_T RebuildBlockNumber;		/* Bytes 216-223 */
+  DAC960_ByteCount64_T MakingDataConsistentBlockNumber;	/* Bytes 224-231 */
+  DAC960_ByteCount64_T DeviceInitializationBlockNumber; /* Bytes 232-239 */
+  DAC960_ByteCount64_T DataMigrationBlockNumber;	/* Bytes 240-247 */
+  DAC960_ByteCount64_T PatrolOperationBlockNumber;	/* Bytes 248-255 */
+  unsigned char Reserved5[256];				/* Bytes 256-511 */
+}
+DAC960_V2_PhysicalDeviceInfo_T;
+
+
+/*
+  Define the DAC960 V2 Firmware Health Status Buffer structure.
+*/
+
+typedef struct DAC960_V2_HealthStatusBuffer
+{
+  unsigned int MicrosecondsFromControllerStartTime;	/* Bytes 0-3 */
+  unsigned int MillisecondsFromControllerStartTime;	/* Bytes 4-7 */
+  unsigned int SecondsFrom1January1970;			/* Bytes 8-11 */
+  unsigned int :32;					/* Bytes 12-15 */
+  unsigned int StatusChangeCounter;			/* Bytes 16-19 */
+  unsigned int :32;					/* Bytes 20-23 */
+  unsigned int DebugOutputMessageBufferIndex;		/* Bytes 24-27 */
+  unsigned int CodedMessageBufferIndex;			/* Bytes 28-31 */
+  unsigned int CurrentTimeTracePageNumber;		/* Bytes 32-35 */
+  unsigned int CurrentProfilerPageNumber;		/* Bytes 36-39 */
+  unsigned int NextEventSequenceNumber;			/* Bytes 40-43 */
+  unsigned int :32;					/* Bytes 44-47 */
+  unsigned char Reserved1[16];				/* Bytes 48-63 */
+  unsigned char Reserved2[64];				/* Bytes 64-127 */
+}
+DAC960_V2_HealthStatusBuffer_T;
 
 
 /*
-  Define the DAC960 Controller Monitoring Timer Interval.
+  Define the DAC960 V2 Firmware Get Event reply structure.
 */
 
-#define DAC960_MonitoringTimerInterval		(10 * HZ)
+typedef struct DAC960_V2_Event
+{
+  unsigned int EventSequenceNumber;			/* Bytes 0-3 */
+  unsigned int EventTime;				/* Bytes 4-7 */
+  unsigned int EventCode;				/* Bytes 8-11 */
+  unsigned char :8;					/* Byte 12 */
+  unsigned char Channel;				/* Byte 13 */
+  unsigned char TargetID;				/* Byte 14 */
+  unsigned char LogicalUnit;				/* Byte 15 */
+  unsigned int :32;					/* Bytes 16-19 */
+  unsigned int EventSpecificParameter;			/* Bytes 20-23 */
+  unsigned char RequestSenseData[40];			/* Bytes 24-63 */
+}
+DAC960_V2_Event_T;
 
 
 /*
-  Define the DAC960 Controller Secondary Monitoring Interval.
+  Define the DAC960 V2 Firmware Command Control Bits structure.
 */
 
-#define DAC960_SecondaryMonitoringInterval	(60 * HZ)
+typedef struct DAC960_V2_CommandControlBits
+{
+  boolean ForceUnitAccess:1;				/* Byte 0 Bit 0 */
+  boolean DisablePageOut:1;				/* Byte 0 Bit 1 */
+  boolean :1;						/* Byte 0 Bit 2 */
+  boolean AdditionalScatterGatherListMemory:1;		/* Byte 0 Bit 3 */
+  boolean DataTransferControllerToHost:1;		/* Byte 0 Bit 4 */
+  boolean :1;						/* Byte 0 Bit 5 */
+  boolean NoAutoRequestSense:1;				/* Byte 0 Bit 6 */
+  boolean DisconnectProhibited:1;			/* Byte 0 Bit 7 */
+}
+DAC960_V2_CommandControlBits_T;
 
 
 /*
-  Define the DAC960 Controller Progress Reporting Interval.
+  Define the DAC960 V2 Firmware Command Timeout structure.
 */
 
-#define DAC960_ProgressReportingInterval	(60 * HZ)
+typedef struct DAC960_V2_CommandTimeout
+{
+  unsigned char TimeoutValue:6;				/* Byte 0 Bits 0-5 */
+  enum {
+    DAC960_V2_TimeoutScale_Seconds =		0,
+    DAC960_V2_TimeoutScale_Minutes =		1,
+    DAC960_V2_TimeoutScale_Hours =		2,
+    DAC960_V2_TimeoutScale_Reserved =		3
+  } __attribute__ ((packed)) TimeoutScale:2;		/* Byte 0 Bits 6-7 */
+}
+DAC960_V2_CommandTimeout_T;
 
 
 /*
-  Define the maximum number of Partitions allowed for each Logical Drive.
+  Define the DAC960 V2 Firmware Physical Device structure.
 */
 
-#define DAC960_MaxPartitions			8
-#define DAC960_MaxPartitionsBits		3
+typedef struct DAC960_V2_PhysicalDevice
+{
+  unsigned char LogicalUnit;				/* Byte 0 */
+  unsigned char TargetID;				/* Byte 1 */
+  unsigned char Channel:3;				/* Byte 2 Bits 0-2 */
+  unsigned char Controller:5;				/* Byte 2 Bits 3-7 */
+}
+__attribute__ ((packed))
+DAC960_V2_PhysicalDevice_T;
 
 
 /*
-  Define macros to extract the Controller Number, Logical Drive Number, and
-  Partition Number from a Kernel Device, and to construct a Major Number, Minor
-  Number, and Kernel Device from the Controller Number, Logical Drive Number,
-  and Partition Number.  There is one Major Number assigned to each Controller.
-  The associated Minor Number is divided into the Logical Drive Number and
-  Partition Number.
+  Define the DAC960 V2 Firmware Logical Device structure.
 */
 
-#define DAC960_ControllerNumber(Device) \
-  (MAJOR(Device) - DAC960_MAJOR)
+typedef struct DAC960_V2_LogicalDevice
+{
+  unsigned short LogicalDeviceNumber;			/* Bytes 0-1 */
+  unsigned char :3;					/* Byte 2 Bits 0-2 */
+  unsigned char Controller:5;				/* Byte 2 Bits 3-7 */
+}
+__attribute__ ((packed))
+DAC960_V2_LogicalDevice_T;
 
-#define DAC960_LogicalDriveNumber(Device) \
-  (MINOR(Device) >> DAC960_MaxPartitionsBits)
 
-#define DAC960_PartitionNumber(Device) \
-  (MINOR(Device) & (DAC960_MaxPartitions - 1))
+/*
+  Define the DAC960 V2 Firmware Operation Device type.
+*/
 
-#define DAC960_MajorNumber(ControllerNumber) \
-  (DAC960_MAJOR + (ControllerNumber))
+typedef enum
+{
+  DAC960_V2_Physical_Device =			0x00,
+  DAC960_V2_RAID_Device =			0x01,
+  DAC960_V2_Physical_Channel =			0x02,
+  DAC960_V2_RAID_Channel =			0x03,
+  DAC960_V2_Physical_Controller =		0x04,
+  DAC960_V2_RAID_Controller =			0x05,
+  DAC960_V2_Configuration_Group =		0x10
+}
+__attribute__ ((packed))
+DAC960_V2_OperationDevice_T;
 
-#define DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber) \
-   (((LogicalDriveNumber) << DAC960_MaxPartitionsBits) | (PartitionNumber))
 
-#define DAC960_MinorCount			(DAC960_MaxLogicalDrives \
-						 * DAC960_MaxPartitions)
+/*
+  Define the DAC960 V2 Firmware Translate Physical To Logical Device structure.
+*/
+
+typedef struct DAC960_V2_PhysicalToLogicalDevice
+{
+  unsigned short LogicalDeviceNumber;			/* Bytes 0-1 */
+  unsigned short :16;					/* Bytes 2-3 */
+  unsigned char PreviousBootController;			/* Byte 4 */
+  unsigned char PreviousBootChannel;			/* Byte 5 */
+  unsigned char PreviousBootTargetID;			/* Byte 6 */
+  unsigned char PreviousBootLogicalUnit;		/* Byte 7 */
+}
+DAC960_V2_PhysicalToLogicalDevice_T;
 
-#define DAC960_KernelDevice(ControllerNumber,				       \
-			    LogicalDriveNumber,				       \
-			    PartitionNumber)				       \
-   MKDEV(DAC960_MajorNumber(ControllerNumber),				       \
-	 DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber))
 
 
 /*
-  Define the DAC960 Controller fixed Block Size and Block Size Bits.
+  Define the DAC960 V2 Firmware Scatter/Gather List Entry structure.
 */
 
-#define DAC960_BlockSize			512
+typedef struct DAC960_V2_ScatterGatherSegment
+{
+  DAC960_BusAddress64_T SegmentDataPointer;		/* Bytes 0-7 */
+  DAC960_ByteCount64_T SegmentByteCount;		/* Bytes 8-15 */
+}
+DAC960_V2_ScatterGatherSegment_T;
+
+
+/*
+  Define the DAC960 V2 Firmware Data Transfer Memory Address structure.
+*/
+
+typedef union DAC960_V2_DataTransferMemoryAddress
+{
+  DAC960_V2_ScatterGatherSegment_T ScatterGatherSegments[2]; /* Bytes 0-31 */
+  struct {
+    unsigned short ScatterGatherList0Length;		/* Bytes 0-1 */
+    unsigned short ScatterGatherList1Length;		/* Bytes 2-3 */
+    unsigned short ScatterGatherList2Length;		/* Bytes 4-5 */
+    unsigned short :16;					/* Bytes 6-7 */
+    DAC960_BusAddress64_T ScatterGatherList0Address;	/* Bytes 8-15 */
+    DAC960_BusAddress64_T ScatterGatherList1Address;	/* Bytes 16-23 */
+    DAC960_BusAddress64_T ScatterGatherList2Address;	/* Bytes 24-31 */
+  } ExtendedScatterGather;
+}
+DAC960_V2_DataTransferMemoryAddress_T;
+
+
+/*
+  Define the 64 Byte DAC960 V2 Firmware Command Mailbox structure.
+*/
+
+typedef union DAC960_V2_CommandMailbox
+{
+  unsigned int Words[16];				/* Words 0-15 */
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    unsigned int :24;					/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    unsigned char Reserved[10];				/* Bytes 22-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } Common;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_PhysicalDevice_T PhysicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char CDBLength;				/* Byte 21 */
+    unsigned char SCSI_CDB[10];				/* Bytes 22-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } SCSI_10;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_PhysicalDevice_T PhysicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char CDBLength;				/* Byte 21 */
+    unsigned short :16;					/* Bytes 22-23 */
+    DAC960_BusAddress64_T SCSI_CDB_BusAddress;		/* Bytes 24-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } SCSI_255;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    unsigned short :16;					/* Bytes 16-17 */
+    unsigned char ControllerNumber;			/* Byte 18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    unsigned char Reserved[10];				/* Bytes 22-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } ControllerInfo;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_LogicalDevice_T LogicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    unsigned char Reserved[10];				/* Bytes 22-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } LogicalDeviceInfo;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_PhysicalDevice_T PhysicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    unsigned char Reserved[10];				/* Bytes 22-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } PhysicalDeviceInfo;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    unsigned short EventSequenceNumberHigh16;		/* Bytes 16-17 */
+    unsigned char ControllerNumber;			/* Byte 18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    unsigned short EventSequenceNumberLow16;		/* Bytes 22-23 */
+    unsigned char Reserved[8];				/* Bytes 24-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } GetEvent;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_LogicalDevice_T LogicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    union {
+      DAC960_V2_LogicalDeviceState_T LogicalDeviceState;
+      DAC960_V2_PhysicalDeviceState_T PhysicalDeviceState;
+    } DeviceState;					/* Byte 22 */
+    unsigned char Reserved[9];				/* Bytes 23-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } SetDeviceState;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_LogicalDevice_T LogicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    boolean RestoreConsistency:1;			/* Byte 22 Bit 0 */
+    boolean InitializedAreaOnly:1;			/* Byte 22 Bit 1 */
+    unsigned char :6;					/* Byte 22 Bits 2-7 */
+    unsigned char Reserved[9];				/* Bytes 23-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } ConsistencyCheck;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    unsigned char FirstCommandMailboxSizeKB;		/* Byte 4 */
+    unsigned char FirstStatusMailboxSizeKB;		/* Byte 5 */
+    unsigned char SecondCommandMailboxSizeKB;		/* Byte 6 */
+    unsigned char SecondStatusMailboxSizeKB;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    unsigned int :24;					/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    unsigned char HealthStatusBufferSizeKB;		/* Byte 22 */
+    unsigned char :8;					/* Byte 23 */
+    DAC960_BusAddress64_T HealthStatusBufferBusAddress; /* Bytes 24-31 */
+    DAC960_BusAddress64_T FirstCommandMailboxBusAddress; /* Bytes 32-39 */
+    DAC960_BusAddress64_T FirstStatusMailboxBusAddress; /* Bytes 40-47 */
+    DAC960_BusAddress64_T SecondCommandMailboxBusAddress; /* Bytes 48-55 */
+    DAC960_BusAddress64_T SecondStatusMailboxBusAddress; /* Bytes 56-63 */
+  } SetMemoryMailbox;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_PhysicalDevice_T PhysicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    DAC960_V2_OperationDevice_T OperationDevice;	/* Byte 22 */
+    unsigned char Reserved[9];				/* Bytes 23-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } DeviceOperation;
+}
+__attribute__ ((packed))
+DAC960_V2_CommandMailbox_T;
+
+
+/*
+  Define the DAC960 Driver IOCTL requests.
+*/
+
+#define DAC960_IOCTL_GET_CONTROLLER_COUNT	0xDAC001
+#define DAC960_IOCTL_GET_CONTROLLER_INFO	0xDAC002
+#define DAC960_IOCTL_V1_EXECUTE_COMMAND		0xDAC003
+#define DAC960_IOCTL_V2_EXECUTE_COMMAND		0xDAC004
+#define DAC960_IOCTL_V2_GET_HEALTH_STATUS	0xDAC005
+
+
+/*
+  Define the DAC960_IOCTL_GET_CONTROLLER_INFO reply structure.
+*/
+
+typedef struct DAC960_ControllerInfo
+{
+  unsigned char ControllerNumber;
+  unsigned char FirmwareType;
+  unsigned char Channels;
+  unsigned char Targets;
+  unsigned char PCI_Bus;
+  unsigned char PCI_Device;
+  unsigned char PCI_Function;
+  unsigned char IRQ_Channel;
+  DAC960_PCI_Address_T PCI_Address;
+  unsigned char ModelName[20];
+  unsigned char FirmwareVersion[12];
+}
+DAC960_ControllerInfo_T;
+
+
+/*
+  Define the User Mode DAC960_IOCTL_V1_EXECUTE_COMMAND request structure.
+*/
+
+typedef struct DAC960_V1_UserCommand
+{
+  unsigned char ControllerNumber;
+  DAC960_V1_CommandMailbox_T CommandMailbox;
+  int DataTransferLength;
+  void *DataTransferBuffer;
+  DAC960_V1_DCDB_T *DCDB;
+}
+DAC960_V1_UserCommand_T;
+
+
+/*
+  Define the Kernel Mode DAC960_IOCTL_V1_EXECUTE_COMMAND request structure.
+*/
+
+typedef struct DAC960_V1_KernelCommand
+{
+  unsigned char ControllerNumber;
+  DAC960_V1_CommandMailbox_T CommandMailbox;
+  int DataTransferLength;
+  void *DataTransferBuffer;
+  DAC960_V1_DCDB_T *DCDB;
+  DAC960_V1_CommandStatus_T CommandStatus;
+  void (*CompletionFunction)(struct DAC960_V1_KernelCommand *);
+  void *CompletionData;
+}
+DAC960_V1_KernelCommand_T;
+
+
+/*
+  Define the User Mode DAC960_IOCTL_V2_EXECUTE_COMMAND request structure.
+*/
+
+typedef struct DAC960_V2_UserCommand
+{
+  unsigned char ControllerNumber;
+  DAC960_V2_CommandMailbox_T CommandMailbox;
+  int DataTransferLength;
+  int RequestSenseLength;
+  void *DataTransferBuffer;
+  void *RequestSenseBuffer;
+}
+DAC960_V2_UserCommand_T;
+
+
+/*
+  Define the Kernel Mode DAC960_IOCTL_V2_EXECUTE_COMMAND request structure.
+*/
+
+typedef struct DAC960_V2_KernelCommand
+{
+  unsigned char ControllerNumber;
+  DAC960_V2_CommandMailbox_T CommandMailbox;
+  int DataTransferLength;
+  int RequestSenseLength;
+  void *DataTransferBuffer;
+  void *RequestSenseBuffer;
+  DAC960_V2_CommandStatus_T CommandStatus;
+  void (*CompletionFunction)(struct DAC960_V2_KernelCommand *);
+  void *CompletionData;
+}
+DAC960_V2_KernelCommand_T;
+
+
+/*
+  Define the User Mode DAC960_IOCTL_V2_GET_HEALTH_STATUS request structure.
+*/
+
+typedef struct DAC960_V2_GetHealthStatus
+{
+  unsigned char ControllerNumber;
+  DAC960_V2_HealthStatusBuffer_T *HealthStatusBuffer;
+}
+DAC960_V2_GetHealthStatus_T;
+
+
+/*
+  Import the Kernel Mode IOCTL interface.
+*/
+
+extern int DAC960_KernelIOCTL(unsigned int Request, void *Argument);
+
+
+/*
+  Virtual_to_Bus maps from Kernel Virtual Addresses to PCI Bus Addresses.
+*/
+
+static inline DAC960_BusAddress32_T Virtual_to_Bus(void *VirtualAddress)
+{
+  return (DAC960_BusAddress32_T) virt_to_bus(VirtualAddress);
+}
+
+
+/*
+  Bus_to_Virtual maps from PCI Bus Addresses to Kernel Virtual Addresses.
+*/
+
+static inline void *Bus_to_Virtual(DAC960_BusAddress32_T BusAddress)
+{
+  return (void *) bus_to_virt(BusAddress);
+}
+
+
+/*
+  DAC960_DriverVersion protects the private portion of this file.
+*/
+
+#ifdef DAC960_DriverVersion
+
+
+/*
+  Define the maximum Driver Queue Depth and Controller Queue Depth supported
+  by DAC960 V1 and V2 Firmware Controllers.
+*/
+
+#define DAC960_MaxDriverQueueDepth		511
+#define DAC960_MaxControllerQueueDepth		512
+
+
+/*
+  Define the maximum number of Scatter/Gather Segments supported for any
+  DAC960 V1 and V2 Firmware controller.
+*/
+
+#define DAC960_V1_ScatterGatherLimit		33
+#define DAC960_V2_ScatterGatherLimit		128
+
+
+/*
+  Define the number of Command Mailboxes and Status Mailboxes used by the
+  DAC960 V1 and V2 Firmware Memory Mailbox Interface.
+*/
+
+#define DAC960_V1_CommandMailboxCount		256
+#define DAC960_V1_StatusMailboxCount		1024
+#define DAC960_V2_CommandMailboxCount		512
+#define DAC960_V2_StatusMailboxCount		512
+
+
+/*
+  Define the DAC960 Controller Monitoring Timer Interval.
+*/
+
+#define DAC960_MonitoringTimerInterval		(10 * HZ)
+
+
+/*
+  Define the DAC960 Controller Secondary Monitoring Interval.
+*/
+
+#define DAC960_SecondaryMonitoringInterval	(60 * HZ)
+
+
+/*
+  Define the DAC960 Controller Health Status Monitoring Interval.
+*/
+
+#define DAC960_HealthStatusMonitoringInterval	(1 * HZ)
+
+
+/*
+  Define the DAC960 Controller Progress Reporting Interval.
+*/
+
+#define DAC960_ProgressReportingInterval	(60 * HZ)
+
+
+/*
+  Define the maximum number of Partitions allowed for each Logical Drive.
+*/
+
+#define DAC960_MaxPartitions			8
+#define DAC960_MaxPartitionsBits		3
+
+
+/*
+  Define macros to extract the Controller Number, Logical Drive Number, and
+  Partition Number from a Kernel Device, and to construct a Major Number, Minor
+  Number, and Kernel Device from the Controller Number, Logical Drive Number,
+  and Partition Number.  There is one Major Number assigned to each Controller.
+  The associated Minor Number is divided into the Logical Drive Number and
+  Partition Number.
+*/
+
+#define DAC960_ControllerNumber(Device) \
+  (MAJOR(Device) - DAC960_MAJOR)
+
+#define DAC960_LogicalDriveNumber(Device) \
+  (MINOR(Device) >> DAC960_MaxPartitionsBits)
+
+#define DAC960_PartitionNumber(Device) \
+  (MINOR(Device) & (DAC960_MaxPartitions - 1))
+
+#define DAC960_MajorNumber(ControllerNumber) \
+  (DAC960_MAJOR + (ControllerNumber))
+
+#define DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber) \
+   (((LogicalDriveNumber) << DAC960_MaxPartitionsBits) | (PartitionNumber))
+
+#define DAC960_MinorCount			(DAC960_MaxLogicalDrives \
+						 * DAC960_MaxPartitions)
+
+#define DAC960_KernelDevice(ControllerNumber,				       \
+			    LogicalDriveNumber,				       \
+			    PartitionNumber)				       \
+   MKDEV(DAC960_MajorNumber(ControllerNumber),				       \
+	 DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber))
+
+
+/*
+  Define the DAC960 Controller fixed Block Size and Block Size Bits.
+*/
+
+#define DAC960_BlockSize			512
 #define DAC960_BlockSizeBits			9
 
 
 /*
-  Define the Controller Line Buffer, Status Buffer, Rebuild Progress,
-  and User Message Sizes.
+  Define the number of Command structures that should be allocated as a
+  group to optimize kernel memory allocation.
+*/
+
+#define DAC960_V1_CommandAllocationGroupSize	11
+#define DAC960_V2_CommandAllocationGroupSize	29
+
+
+/*
+  Define the Controller Line Buffer, Progress Buffer, User Message, and
+  Initial Status Buffer sizes.
 */
 
 #define DAC960_LineBufferSize			100
-#define DAC960_StatusBufferSize			16384
-#define DAC960_RebuildProgressSize		200
+#define DAC960_ProgressBufferSize		200
 #define DAC960_UserMessageSize			200
+#define DAC960_InitialStatusBufferSize		(8192-32)
+
+
+/*
+  Define the DAC960 Controller Firmware Types.
+*/
+
+typedef enum
+{
+  DAC960_V1_Controller =			1,
+  DAC960_V2_Controller =			2
+}
+DAC960_FirmwareType_T;
 
 
 /*
-  Define the types of DAC960 Controllers that are supported.
+  Define the DAC960 Controller Hardware Types.
 */
 
 typedef enum
 {
-  DAC960_V5_Controller =			1,	/* DAC1164P */
-  DAC960_V4_Controller =			2,	/* DAC960PTL/PJ/PG */
-  DAC960_V3_Controller =			3	/* DAC960PU/PD/PL */
+  DAC960_BA_Controller =			1,	/* eXtremeRAID 2000 */
+  DAC960_LP_Controller =			2,	/* AcceleRAID 352 */
+  DAC960_LA_Controller =			3,	/* DAC1164P */
+  DAC960_PG_Controller =			4,	/* DAC960PTL/PJ/PG */
+  DAC960_PD_Controller =			5	/* DAC960PU/PD/PL */
 }
-DAC960_ControllerType_T;
+DAC960_HardwareType_T;
 
 
 /*
@@ -1131,285 +2170,999 @@
 
 
 /*
-  Define the DAC960 Controller Status Mailbox structure.
+  Define the DAC960 V1 Firmware Controller Status Mailbox structure.
+*/
+
+typedef union DAC960_V1_StatusMailbox
+{
+  unsigned int Word;					/* Word 0 */
+  struct {
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 0 */
+    unsigned char :7;					/* Byte 1 Bits 0-6 */
+    boolean Valid:1;					/* Byte 1 Bit 7 */
+    DAC960_V1_CommandStatus_T CommandStatus;		/* Bytes 2-3 */
+  } Fields;
+}
+DAC960_V1_StatusMailbox_T;
+
+
+/*
+  Define the DAC960 V2 Firmware Controller Status Mailbox structure.
+*/
+
+typedef union DAC960_V2_StatusMailbox
+{
+  unsigned int Words[2];				/* Words 0-1 */
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandStatus_T CommandStatus;		/* Byte 2 */
+    unsigned char RequestSenseLength;			/* Byte 3 */
+    int DataTransferResidue;				/* Bytes 4-7 */
+  } Fields;
+}
+DAC960_V2_StatusMailbox_T;
+
+
+/*
+  Define the DAC960 Driver Command Types.
+*/
+
+typedef enum
+{
+  DAC960_ReadCommand =				1,
+  DAC960_WriteCommand =				2,
+  DAC960_ReadRetryCommand =			3,
+  DAC960_WriteRetryCommand =			4,
+  DAC960_MonitoringCommand =			5,
+  DAC960_ImmediateCommand =			6,
+  DAC960_QueuedCommand =			7
+}
+DAC960_CommandType_T;
+
+
+/*
+  Define the DAC960 Driver Command structure.
+*/
+
+typedef struct DAC960_Command
+{
+  int CommandIdentifier;
+  DAC960_CommandType_T CommandType;
+  struct DAC960_Controller *Controller;
+  struct DAC960_Command *Next;
+  Semaphore_T *Semaphore;
+  unsigned int LogicalDriveNumber;
+  unsigned int BlockNumber;
+  unsigned int BlockCount;
+  unsigned int SegmentCount;
+  BufferHeader_T *BufferHeader;
+  void *RequestBuffer;
+  union {
+    struct {
+      DAC960_V1_CommandMailbox_T CommandMailbox;
+      DAC960_V1_KernelCommand_T *KernelCommand;
+      DAC960_V1_CommandStatus_T CommandStatus;
+      DAC960_V1_ScatterGatherSegment_T
+	ScatterGatherList[DAC960_V1_ScatterGatherLimit]
+	__attribute__ ((aligned (sizeof(DAC960_V1_ScatterGatherSegment_T))));
+      unsigned int EndMarker[0];
+    } V1;
+    struct {
+      DAC960_V2_CommandMailbox_T CommandMailbox;
+      DAC960_V2_KernelCommand_T *KernelCommand;
+      DAC960_V2_CommandStatus_T CommandStatus;
+      unsigned char RequestSenseLength;
+      int DataTransferResidue;
+      DAC960_V2_ScatterGatherSegment_T
+	ScatterGatherList[DAC960_V2_ScatterGatherLimit]
+	__attribute__ ((aligned (sizeof(DAC960_V2_ScatterGatherSegment_T))));
+      DAC960_SCSI_RequestSense_T RequestSense
+	__attribute__ ((aligned (sizeof(int))));
+      unsigned int EndMarker[0];
+    } V2;
+  } FW;
+}
+DAC960_Command_T;
+
+
+/*
+  Define the DAC960 Driver Controller structure.
+*/
+
+typedef struct DAC960_Controller
+{
+  void *BaseAddress;
+  void *MemoryMappedAddress;
+  DAC960_FirmwareType_T FirmwareType;
+  DAC960_HardwareType_T HardwareType;
+  DAC960_IO_Address_T IO_Address;
+  DAC960_PCI_Address_T PCI_Address;
+  unsigned char ControllerNumber;
+  unsigned char ControllerName[4];
+  unsigned char ModelName[20];
+  unsigned char FullModelName[28];
+  unsigned char FirmwareVersion[12];
+  unsigned char Bus;
+  unsigned char Device;
+  unsigned char Function;
+  unsigned char IRQ_Channel;
+  unsigned char Channels;
+  unsigned char Targets;
+  unsigned char MemorySize;
+  unsigned char LogicalDriveCount;
+  unsigned short CommandAllocationGroupSize;
+  unsigned short ControllerQueueDepth;
+  unsigned short DriverQueueDepth;
+  unsigned short MaxBlocksPerCommand;
+  unsigned short ControllerScatterGatherLimit;
+  unsigned short DriverScatterGatherLimit;
+  unsigned int ControllerUsageCount;
+  unsigned int CombinedStatusBufferLength;
+  unsigned int InitialStatusLength;
+  unsigned int CurrentStatusLength;
+  unsigned int ProgressBufferLength;
+  unsigned int UserStatusLength;
+  unsigned long MemoryMailboxPagesAddress;
+  unsigned long MemoryMailboxPagesOrder;
+  unsigned long MonitoringTimerCount;
+  unsigned long PrimaryMonitoringTime;
+  unsigned long SecondaryMonitoringTime;
+  unsigned long LastProgressReportTime;
+  unsigned long LastCurrentStatusTime;
+  boolean ControllerDetectionSuccessful;
+  boolean ControllerInitialized;
+  boolean MonitoringCommandDeferred;
+  boolean EphemeralProgressMessage;
+  boolean DriveSpinUpMessageDisplayed;
+  boolean MonitoringAlertMode;
+  Timer_T MonitoringTimer;
+  GenericDiskInfo_T GenericDiskInfo;
+  DAC960_Command_T *FreeCommands;
+  unsigned char *CombinedStatusBuffer;
+  unsigned char *CurrentStatusBuffer;
+  PROC_DirectoryEntry_T ControllerProcEntry;
+  PROC_DirectoryEntry_T InitialStatusProcEntry;
+  PROC_DirectoryEntry_T CurrentStatusProcEntry;
+  PROC_DirectoryEntry_T UserCommandProcEntry;
+  WaitQueue_T *CommandWaitQueue;
+  WaitQueue_T *HealthStatusWaitQueue;
+  DAC960_Command_T InitialCommand;
+  DAC960_Command_T *Commands[DAC960_MaxDriverQueueDepth];
+  unsigned int LogicalDriveUsageCount[DAC960_MaxLogicalDrives];
+  boolean LogicalDriveInitiallyAccessible[DAC960_MaxLogicalDrives];
+  void (*QueueCommand)(DAC960_Command_T *Command);
+  boolean (*ReadControllerConfiguration)(struct DAC960_Controller *);
+  boolean (*ReadDeviceConfiguration)(struct DAC960_Controller *);
+  boolean (*ReportDeviceConfiguration)(struct DAC960_Controller *);
+  void (*QueueReadWriteCommand)(DAC960_Command_T *Command);
+  union {
+    struct {
+      unsigned char GeometryTranslationHeads;
+      unsigned char GeometryTranslationSectors;
+      unsigned char PendingRebuildFlag;
+      unsigned short StripeSize;
+      unsigned short SegmentSize;
+      unsigned short NewEventLogSequenceNumber;
+      unsigned short OldEventLogSequenceNumber;
+      unsigned short DeviceStateChannel;
+      unsigned short DeviceStateTargetID;
+      boolean DualModeMemoryMailboxInterface;
+      boolean SAFTE_EnclosureManagementEnabled;
+      boolean NeedLogicalDriveInformation;
+      boolean NeedErrorTableInformation;
+      boolean NeedDeviceStateInformation;
+      boolean NeedDeviceInquiryInformation;
+      boolean NeedDeviceSerialNumberInformation;
+      boolean NeedRebuildProgress;
+      boolean NeedConsistencyCheckProgress;
+      boolean RebuildProgressFirst;
+      boolean RebuildFlagPending;
+      boolean RebuildStatusPending;
+      DAC960_V1_CommandMailbox_T *FirstCommandMailbox;
+      DAC960_V1_CommandMailbox_T *LastCommandMailbox;
+      DAC960_V1_CommandMailbox_T *NextCommandMailbox;
+      DAC960_V1_CommandMailbox_T *PreviousCommandMailbox1;
+      DAC960_V1_CommandMailbox_T *PreviousCommandMailbox2;
+      DAC960_V1_StatusMailbox_T *FirstStatusMailbox;
+      DAC960_V1_StatusMailbox_T *LastStatusMailbox;
+      DAC960_V1_StatusMailbox_T *NextStatusMailbox;
+      DAC960_V1_DCDB_T MonitoringDCDB;
+      DAC960_V1_Enquiry_T Enquiry;
+      DAC960_V1_Enquiry_T NewEnquiry;
+      DAC960_V1_ErrorTable_T ErrorTable;
+      DAC960_V1_ErrorTable_T NewErrorTable;
+      DAC960_V1_EventLogEntry_T EventLogEntry;
+      DAC960_V1_RebuildProgress_T RebuildProgress;
+      DAC960_V1_CommandStatus_T LastRebuildStatus;
+      DAC960_V1_CommandStatus_T PendingRebuildStatus;
+      DAC960_V1_LogicalDriveInformationArray_T LogicalDriveInformation;
+      DAC960_V1_LogicalDriveInformationArray_T NewLogicalDriveInformation;
+      DAC960_V1_DeviceState_T
+	DeviceState[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
+      DAC960_V1_DeviceState_T NewDeviceState;
+      DAC960_SCSI_Inquiry_T
+	InquiryStandardData[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
+      DAC960_SCSI_Inquiry_UnitSerialNumber_T
+	InquiryUnitSerialNumber[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
+      int DeviceResetCount[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
+      boolean DirectCommandActive[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
+    } V1;
+    struct {
+      unsigned int StatusChangeCounter;
+      unsigned int NextEventSequenceNumber;
+      unsigned int PhysicalDeviceIndex;
+      boolean NeedLogicalDeviceInformation;
+      boolean NeedPhysicalDeviceInformation;
+      boolean NeedDeviceSerialNumberInformation;
+      DAC960_V2_CommandMailbox_T *FirstCommandMailbox;
+      DAC960_V2_CommandMailbox_T *LastCommandMailbox;
+      DAC960_V2_CommandMailbox_T *NextCommandMailbox;
+      DAC960_V2_CommandMailbox_T *PreviousCommandMailbox1;
+      DAC960_V2_CommandMailbox_T *PreviousCommandMailbox2;
+      DAC960_V2_StatusMailbox_T *FirstStatusMailbox;
+      DAC960_V2_StatusMailbox_T *LastStatusMailbox;
+      DAC960_V2_StatusMailbox_T *NextStatusMailbox;
+      DAC960_V2_HealthStatusBuffer_T *HealthStatusBuffer;
+      DAC960_V2_ControllerInfo_T ControllerInformation;
+      DAC960_V2_ControllerInfo_T NewControllerInformation;
+      DAC960_V2_LogicalDeviceInfo_T
+	*LogicalDeviceInformation[DAC960_MaxLogicalDrives];
+      DAC960_V2_LogicalDeviceInfo_T NewLogicalDeviceInformation;
+      DAC960_V2_PhysicalDeviceInfo_T
+	*PhysicalDeviceInformation[DAC960_V2_MaxPhysicalDevices];
+      DAC960_V2_PhysicalDeviceInfo_T NewPhysicalDeviceInformation;
+      DAC960_SCSI_Inquiry_UnitSerialNumber_T
+	*InquiryUnitSerialNumber[DAC960_V2_MaxPhysicalDevices];
+      DAC960_V2_PhysicalDevice_T
+	LogicalDriveToVirtualDevice[DAC960_MaxLogicalDrives];
+      DAC960_V2_Event_T Event;
+    } V2;
+  } FW;
+  DiskPartition_T DiskPartitions[DAC960_MinorCount];
+  int PartitionSizes[DAC960_MinorCount];
+  int BlockSizes[DAC960_MinorCount];
+  int MaxSectorsPerRequest[DAC960_MinorCount];
+  int MaxSegmentsPerRequest[DAC960_MinorCount];
+  unsigned char ProgressBuffer[DAC960_ProgressBufferSize];
+  unsigned char UserStatusBuffer[DAC960_UserMessageSize];
+}
+DAC960_Controller_T;
+
+
+/*
+  Simplify access to Firmware Version Dependent Data Structure Components
+  and Functions.
+*/
+
+#define V1				FW.V1
+#define V2				FW.V2
+#define DAC960_QueueCommand(Command) \
+  (Controller->QueueCommand)(Command)
+#define DAC960_ReadControllerConfiguration(Controller) \
+  (Controller->ReadControllerConfiguration)(Controller)
+#define DAC960_ReadDeviceConfiguration(Controller) \
+  (Controller->ReadDeviceConfiguration)(Controller)
+#define DAC960_ReportDeviceConfiguration(Controller) \
+  (Controller->ReportDeviceConfiguration)(Controller)
+#define DAC960_QueueReadWriteCommand(Command) \
+  (Controller->QueueReadWriteCommand)(Command)
+
+
+/*
+  DAC960_AcquireControllerLock acquires exclusive access to Controller.
+*/
+
+static inline
+void DAC960_AcquireControllerLock(DAC960_Controller_T *Controller,
+				  ProcessorFlags_T *ProcessorFlags)
+{
+  spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
+}
+
+
+/*
+  DAC960_ReleaseControllerLock releases exclusive access to Controller.
+*/
+
+static inline
+void DAC960_ReleaseControllerLock(DAC960_Controller_T *Controller,
+				  ProcessorFlags_T *ProcessorFlags)
+{
+  spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
+}
+
+
+/*
+  DAC960_AcquireControllerLockRF acquires exclusive access to Controller,
+  but is only called from the request function with the io_request_lock held.
+*/
+
+static inline
+void DAC960_AcquireControllerLockRF(DAC960_Controller_T *Controller,
+				    ProcessorFlags_T *ProcessorFlags)
+{
+}
+
+
+/*
+  DAC960_ReleaseControllerLockRF releases exclusive access to Controller,
+  but is only called from the request function with the io_request_lock held.
+*/
+
+static inline
+void DAC960_ReleaseControllerLockRF(DAC960_Controller_T *Controller,
+				    ProcessorFlags_T *ProcessorFlags)
+{
+}
+
+
+/*
+  DAC960_AcquireControllerLockIH acquires exclusive access to Controller,
+  but is only called from the interrupt handler.
+*/
+
+static inline
+void DAC960_AcquireControllerLockIH(DAC960_Controller_T *Controller,
+				    ProcessorFlags_T *ProcessorFlags)
+{
+  spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
+}
+
+
+/*
+  DAC960_ReleaseControllerLockIH releases exclusive access to Controller,
+  but is only called from the interrupt handler.
+*/
+
+static inline
+void DAC960_ReleaseControllerLockIH(DAC960_Controller_T *Controller,
+				    ProcessorFlags_T *ProcessorFlags)
+{
+  spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
+}
+
+
+/*
+  Define the DAC960 BA Series Controller Interface Register Offsets.
+*/
+
+#define DAC960_BA_RegisterWindowSize		0x80
+
+typedef enum
+{
+  DAC960_BA_InboundDoorBellRegisterOffset =	0x60,
+  DAC960_BA_OutboundDoorBellRegisterOffset =	0x61,
+  DAC960_BA_InterruptStatusRegisterOffset =	0x30,
+  DAC960_BA_InterruptMaskRegisterOffset =	0x34,
+  DAC960_BA_CommandMailboxBusAddressOffset =	0x50,
+  DAC960_BA_CommandStatusOffset =		0x58,
+  DAC960_BA_ErrorStatusRegisterOffset =		0x63
+}
+DAC960_BA_RegisterOffsets_T;
+
+
+/*
+  Define the structure of the DAC960 BA Series Inbound Door Bell Register.
+*/
+
+typedef union DAC960_BA_InboundDoorBellRegister
+{
+  unsigned char All;
+  struct {
+    boolean HardwareMailboxNewCommand:1;		/* Bit 0 */
+    boolean AcknowledgeHardwareMailboxStatus:1;		/* Bit 1 */
+    boolean GenerateInterrupt:1;			/* Bit 2 */
+    boolean ControllerReset:1;				/* Bit 3 */
+    boolean MemoryMailboxNewCommand:1;			/* Bit 4 */
+    unsigned char :3;					/* Bits 5-7 */
+  } Write;
+  struct {
+    boolean HardwareMailboxEmpty:1;			/* Bit 0 */
+    boolean InitializationNotInProgress:1;		/* Bit 1 */
+    unsigned char :6;					/* Bits 2-7 */
+  } Read;
+}
+DAC960_BA_InboundDoorBellRegister_T;
+
+
+/*
+  Define the structure of the DAC960 BA Series Outbound Door Bell Register.
+*/
+
+typedef union DAC960_BA_OutboundDoorBellRegister
+{
+  unsigned char All;
+  struct {
+    boolean AcknowledgeHardwareMailboxInterrupt:1;	/* Bit 0 */
+    boolean AcknowledgeMemoryMailboxInterrupt:1;	/* Bit 1 */
+    unsigned char :6;					/* Bits 2-7 */
+  } Write;
+  struct {
+    boolean HardwareMailboxStatusAvailable:1;		/* Bit 0 */
+    boolean MemoryMailboxStatusAvailable:1;		/* Bit 1 */
+    unsigned char :6;					/* Bits 2-7 */
+  } Read;
+}
+DAC960_BA_OutboundDoorBellRegister_T;
+
+
+/*
+  Define the structure of the DAC960 BA Series Interrupt Mask Register.
+*/
+
+typedef union DAC960_BA_InterruptMaskRegister
+{
+  unsigned char All;
+  struct {
+    unsigned int :2;					/* Bits 0-1 */
+    boolean DisableInterrupts:1;			/* Bit 2 */
+    boolean DisableInterruptsI2O:1;			/* Bit 3 */
+    unsigned int :4;					/* Bits 4-7 */
+  } Bits;
+}
+DAC960_BA_InterruptMaskRegister_T;
+
+
+/*
+  Define the structure of the DAC960 BA Series Error Status Register.
+*/
+
+typedef union DAC960_BA_ErrorStatusRegister
+{
+  unsigned char All;
+  struct {
+    unsigned int :2;					/* Bits 0-1 */
+    boolean ErrorStatusPending:1;			/* Bit 2 */
+    unsigned int :5;					/* Bits 3-7 */
+  } Bits;
+}
+DAC960_BA_ErrorStatusRegister_T;
+
+
+/*
+  Define inline functions to provide an abstraction for reading and writing the
+  DAC960 BA Series Controller Interface Registers.
+*/
+
+static inline
+void DAC960_BA_HardwareMailboxNewCommand(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+}
+
+static inline
+void DAC960_BA_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+}
+
+static inline
+void DAC960_BA_GenerateInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.GenerateInterrupt = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+}
+
+static inline
+void DAC960_BA_ControllerReset(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.ControllerReset = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+}
+
+static inline
+void DAC960_BA_MemoryMailboxNewCommand(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+}
+
+static inline
+boolean DAC960_BA_HardwareMailboxFullP(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+  return !InboundDoorBellRegister.Read.HardwareMailboxEmpty;
+}
+
+static inline
+boolean DAC960_BA_InitializationInProgressP(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+  return !InboundDoorBellRegister.Read.InitializationNotInProgress;
+}
+
+static inline
+void DAC960_BA_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
+  writeb(OutboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
+}
+
+static inline
+void DAC960_BA_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
+  writeb(OutboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
+}
+
+static inline
+void DAC960_BA_AcknowledgeInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
+  OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
+  writeb(OutboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
+}
+
+static inline
+boolean DAC960_BA_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
+{
+  DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
+  return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
+}
+
+static inline
+boolean DAC960_BA_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
+{
+  DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
+  return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
+}
+
+static inline
+void DAC960_BA_EnableInterrupts(void *ControllerBaseAddress)
+{
+  DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All = 0xFF;
+  InterruptMaskRegister.Bits.DisableInterrupts = false;
+  InterruptMaskRegister.Bits.DisableInterruptsI2O = true;
+  writeb(InterruptMaskRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset);
+}
+
+static inline
+void DAC960_BA_DisableInterrupts(void *ControllerBaseAddress)
+{
+  DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All = 0xFF;
+  InterruptMaskRegister.Bits.DisableInterrupts = true;
+  InterruptMaskRegister.Bits.DisableInterruptsI2O = true;
+  writeb(InterruptMaskRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset);
+}
+
+static inline
+boolean DAC960_BA_InterruptsEnabledP(void *ControllerBaseAddress)
+{
+  DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All =
+    readb(ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset);
+  return !InterruptMaskRegister.Bits.DisableInterrupts;
+}
+
+static inline
+void DAC960_BA_WriteCommandMailbox(DAC960_V2_CommandMailbox_T
+				     *MemoryCommandMailbox,
+				   DAC960_V2_CommandMailbox_T
+				     *CommandMailbox)
+{
+  memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1],
+	 sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int));
+  wmb();
+  MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
+  mb();
+}
+
+static inline
+void DAC960_BA_WriteHardwareMailbox(void *ControllerBaseAddress,
+				    DAC960_V2_CommandMailbox_T *CommandMailbox)
+{
+  writel(Virtual_to_Bus(CommandMailbox),
+	 ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset);
+}
+
+static inline DAC960_V2_CommandIdentifier_T
+DAC960_BA_ReadCommandIdentifier(void *ControllerBaseAddress)
+{
+  return readw(ControllerBaseAddress + DAC960_BA_CommandStatusOffset);
+}
+
+static inline DAC960_V2_CommandStatus_T
+DAC960_BA_ReadCommandStatus(void *ControllerBaseAddress)
+{
+  return readw(ControllerBaseAddress + DAC960_BA_CommandStatusOffset + 2);
+}
+
+static inline boolean
+DAC960_BA_ReadErrorStatus(void *ControllerBaseAddress,
+			  unsigned char *ErrorStatus,
+			  unsigned char *Parameter0,
+			  unsigned char *Parameter1)
+{
+  DAC960_BA_ErrorStatusRegister_T ErrorStatusRegister;
+  ErrorStatusRegister.All =
+    readb(ControllerBaseAddress + DAC960_BA_ErrorStatusRegisterOffset);
+  if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
+  ErrorStatusRegister.Bits.ErrorStatusPending = false;
+  *ErrorStatus = ErrorStatusRegister.All;
+  *Parameter0 =
+    readb(ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset + 0);
+  *Parameter1 =
+    readb(ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset + 1);
+  writeb(0xFF, ControllerBaseAddress + DAC960_BA_ErrorStatusRegisterOffset);
+  return true;
+}
+
+
+/*
+  Define the DAC960 LP Series Controller Interface Register Offsets.
+*/
+
+#define DAC960_LP_RegisterWindowSize		0x80
+
+typedef enum
+{
+  DAC960_LP_InboundDoorBellRegisterOffset =	0x20,
+  DAC960_LP_OutboundDoorBellRegisterOffset =	0x2C,
+  DAC960_LP_InterruptStatusRegisterOffset =	0x30,
+  DAC960_LP_InterruptMaskRegisterOffset =	0x34,
+  DAC960_LP_CommandMailboxBusAddressOffset =	0x10,
+  DAC960_LP_CommandStatusOffset =		0x18,
+  DAC960_LP_ErrorStatusRegisterOffset =		0x2E
+}
+DAC960_LP_RegisterOffsets_T;
+
+
+/*
+  Define the structure of the DAC960 LP Series Inbound Door Bell Register.
 */
 
-typedef union DAC960_StatusMailbox
+typedef union DAC960_LP_InboundDoorBellRegister
 {
-  unsigned int Word;					/* Bytes 0-3 */
+  unsigned char All;
   struct {
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 0 */
-    unsigned char :7;					/* Byte 1 Bits 0-6 */
-    boolean Valid:1;					/* Byte 1 Bit 7 */
-    DAC960_CommandStatus_T CommandStatus;		/* Bytes 2-3 */
-  } Fields;
+    boolean HardwareMailboxNewCommand:1;		/* Bit 0 */
+    boolean AcknowledgeHardwareMailboxStatus:1;		/* Bit 1 */
+    boolean GenerateInterrupt:1;			/* Bit 2 */
+    boolean ControllerReset:1;				/* Bit 3 */
+    boolean MemoryMailboxNewCommand:1;			/* Bit 4 */
+    unsigned char :3;					/* Bits 5-7 */
+  } Write;
+  struct {
+    boolean HardwareMailboxFull:1;			/* Bit 0 */
+    boolean InitializationInProgress:1;			/* Bit 1 */
+    unsigned char :6;					/* Bits 2-7 */
+  } Read;
 }
-DAC960_StatusMailbox_T;
+DAC960_LP_InboundDoorBellRegister_T;
 
 
 /*
-  Define the DAC960 Driver Command Types.
+  Define the structure of the DAC960 LP Series Outbound Door Bell Register.
 */
 
-typedef enum
+typedef union DAC960_LP_OutboundDoorBellRegister
 {
-  DAC960_ReadCommand =				1,
-  DAC960_WriteCommand =				2,
-  DAC960_ReadRetryCommand =			3,
-  DAC960_WriteRetryCommand =			4,
-  DAC960_MonitoringCommand =			5,
-  DAC960_ImmediateCommand =			6,
-  DAC960_QueuedCommand =			7
+  unsigned char All;
+  struct {
+    boolean AcknowledgeHardwareMailboxInterrupt:1;	/* Bit 0 */
+    boolean AcknowledgeMemoryMailboxInterrupt:1;	/* Bit 1 */
+    unsigned char :6;					/* Bits 2-7 */
+  } Write;
+  struct {
+    boolean HardwareMailboxStatusAvailable:1;		/* Bit 0 */
+    boolean MemoryMailboxStatusAvailable:1;		/* Bit 1 */
+    unsigned char :6;					/* Bits 2-7 */
+  } Read;
 }
-DAC960_CommandType_T;
+DAC960_LP_OutboundDoorBellRegister_T;
 
 
 /*
-  Define the DAC960 Driver Command structure.
+  Define the structure of the DAC960 LP Series Interrupt Mask Register.
 */
 
-typedef struct DAC960_Command
+typedef union DAC960_LP_InterruptMaskRegister
 {
-  DAC960_CommandType_T CommandType;
-  DAC960_CommandMailbox_T CommandMailbox;
-  DAC960_CommandStatus_T CommandStatus;
-  struct DAC960_Controller *Controller;
-  struct DAC960_Command *Next;
-  Semaphore_T *Semaphore;
-  unsigned int LogicalDriveNumber;
-  unsigned int BlockNumber;
-  unsigned int BlockCount;
-  unsigned int SegmentCount;
-  BufferHeader_T *BufferHeader;
-  DAC960_KernelCommand_T *KernelCommand;
-  DAC960_ScatterGatherSegment_T
-    ScatterGatherList[DAC960_MaxScatterGatherSegments];
+  unsigned char All;
+  struct {
+    unsigned int :2;					/* Bits 0-1 */
+    boolean DisableInterrupts:1;			/* Bit 2 */
+    unsigned int :5;					/* Bits 3-7 */
+  } Bits;
 }
-DAC960_Command_T;
+DAC960_LP_InterruptMaskRegister_T;
 
 
 /*
-  Define the DAC960 Driver Controller structure.
+  Define the structure of the DAC960 LP Series Error Status Register.
 */
 
-typedef struct DAC960_Controller
+typedef union DAC960_LP_ErrorStatusRegister
 {
-  void *BaseAddress;
-  void *MemoryMappedAddress;
-  DAC960_ControllerType_T ControllerType;
-  DAC960_IO_Address_T IO_Address;
-  DAC960_PCI_Address_T PCI_Address;
-  unsigned char ControllerNumber;
-  unsigned char ControllerName[4];
-  unsigned char ModelName[12];
-  unsigned char FullModelName[18];
-  unsigned char FirmwareVersion[14];
-  unsigned char Bus;
-  unsigned char Device;
-  unsigned char Function;
-  unsigned char IRQ_Channel;
-  unsigned char Channels;
-  unsigned char MemorySize;
-  unsigned char LogicalDriveCount;
-  unsigned char GeometryTranslationHeads;
-  unsigned char GeometryTranslationSectors;
-  unsigned char PendingRebuildFlag;
-  unsigned short ControllerQueueDepth;
-  unsigned short DriverQueueDepth;
-  unsigned short MaxBlocksPerCommand;
-  unsigned short MaxScatterGatherSegments;
-  unsigned short StripeSize;
-  unsigned short SegmentSize;
-  unsigned short NewEventLogSequenceNumber;
-  unsigned short OldEventLogSequenceNumber;
-  unsigned short InitialStatusLength;
-  unsigned short CurrentStatusLength;
-  unsigned short UserStatusLength;
-  unsigned short RebuildProgressLength;
-  unsigned int ControllerUsageCount;
-  unsigned int EnquiryIndex;
-  unsigned int LogicalDriveInformationIndex;
-  unsigned int ErrorTableIndex;
-  unsigned int DeviceStateIndex;
-  unsigned int DeviceStateChannel;
-  unsigned int DeviceStateTargetID;
-  unsigned long MonitoringTimerCount;
-  unsigned long SecondaryMonitoringTime;
-  unsigned long LastProgressReportTime;
-  unsigned long LastCurrentStatusTime;
-  boolean DualModeMemoryMailboxInterface;
-  boolean SAFTE_EnclosureManagementEnabled;
-  boolean ControllerInitialized;
-  boolean MonitoringCommandDeferred;
-  boolean NeedLogicalDriveInformation;
-  boolean NeedErrorTableInformation;
-  boolean NeedDeviceStateInformation;
-  boolean NeedDeviceInquiryInformation;
-  boolean NeedDeviceSerialNumberInformation;
-  boolean NeedRebuildProgress;
-  boolean NeedConsistencyCheckProgress;
-  boolean EphemeralProgressMessage;
-  boolean RebuildFlagPending;
-  boolean RebuildStatusPending;
-  boolean DriveSpinUpMessageDisplayed;
-  Timer_T MonitoringTimer;
-  GenericDiskInfo_T GenericDiskInfo;
-  DAC960_Command_T *FreeCommands;
-  DAC960_CommandMailbox_T *FirstCommandMailbox;
-  DAC960_CommandMailbox_T *LastCommandMailbox;
-  DAC960_CommandMailbox_T *NextCommandMailbox;
-  DAC960_CommandMailbox_T *PreviousCommandMailbox1;
-  DAC960_CommandMailbox_T *PreviousCommandMailbox2;
-  DAC960_StatusMailbox_T *FirstStatusMailbox;
-  DAC960_StatusMailbox_T *LastStatusMailbox;
-  DAC960_StatusMailbox_T *NextStatusMailbox;
-  PROC_DirectoryEntry_T ControllerProcEntry;
-  PROC_DirectoryEntry_T InitialStatusProcEntry;
-  PROC_DirectoryEntry_T CurrentStatusProcEntry;
-  PROC_DirectoryEntry_T UserCommandProcEntry;
-  WaitQueue_T *CommandWaitQueue;
-  DAC960_DCDB_T MonitoringDCDB;
-  DAC960_Enquiry_T Enquiry[2];
-  DAC960_ErrorTable_T ErrorTable[2];
-  DAC960_EventLogEntry_T EventLogEntry;
-  DAC960_RebuildProgress_T RebuildProgress;
-  DAC960_CommandStatus_T LastRebuildStatus;
-  DAC960_CommandStatus_T PendingRebuildStatus;
-  DAC960_LogicalDriveInformation_T
-    LogicalDriveInformation[2][DAC960_MaxLogicalDrives];
-  DAC960_LogicalDriveState_T LogicalDriveInitialState[DAC960_MaxLogicalDrives];
-  DAC960_DeviceState_T DeviceState[2][DAC960_MaxChannels][DAC960_MaxTargets];
-  DAC960_Command_T Commands[DAC960_MaxDriverQueueDepth];
-  DAC960_SCSI_Inquiry_T
-    InquiryStandardData[DAC960_MaxChannels][DAC960_MaxTargets];
-  DAC960_SCSI_Inquiry_UnitSerialNumber_T
-    InquiryUnitSerialNumber[DAC960_MaxChannels][DAC960_MaxTargets];
-  DiskPartition_T DiskPartitions[DAC960_MinorCount];
-  int LogicalDriveUsageCount[DAC960_MaxLogicalDrives];
-  int PartitionSizes[DAC960_MinorCount];
-  int BlockSizes[DAC960_MinorCount];
-  int MaxSectorsPerRequest[DAC960_MinorCount];
-  int MaxSegmentsPerRequest[DAC960_MinorCount];
-  int DeviceResetCount[DAC960_MaxChannels][DAC960_MaxTargets];
-  boolean DirectCommandActive[DAC960_MaxChannels][DAC960_MaxTargets];
-  char InitialStatusBuffer[DAC960_StatusBufferSize];
-  char CurrentStatusBuffer[DAC960_StatusBufferSize];
-  char UserStatusBuffer[DAC960_UserMessageSize];
-  char RebuildProgressBuffer[DAC960_RebuildProgressSize];
+  unsigned char All;
+  struct {
+    unsigned int :2;					/* Bits 0-1 */
+    boolean ErrorStatusPending:1;			/* Bit 2 */
+    unsigned int :5;					/* Bits 3-7 */
+  } Bits;
 }
-DAC960_Controller_T;
+DAC960_LP_ErrorStatusRegister_T;
 
 
 /*
-  DAC960_AcquireControllerLock acquires exclusive access to Controller.
+  Define inline functions to provide an abstraction for reading and writing the
+  DAC960 LP Series Controller Interface Registers.
 */
 
 static inline
-void DAC960_AcquireControllerLock(DAC960_Controller_T *Controller,
-				  ProcessorFlags_T *ProcessorFlags)
+void DAC960_LP_HardwareMailboxNewCommand(void *ControllerBaseAddress)
 {
-  spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
 }
 
+static inline
+void DAC960_LP_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
+{
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
+}
 
-/*
-  DAC960_ReleaseControllerLock releases exclusive access to Controller.
-*/
+static inline
+void DAC960_LP_GenerateInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.GenerateInterrupt = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
+}
 
 static inline
-void DAC960_ReleaseControllerLock(DAC960_Controller_T *Controller,
-				  ProcessorFlags_T *ProcessorFlags)
+void DAC960_LP_ControllerReset(void *ControllerBaseAddress)
 {
-  spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.ControllerReset = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
 }
 
+static inline
+void DAC960_LP_MemoryMailboxNewCommand(void *ControllerBaseAddress)
+{
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
+}
 
-/*
-  DAC960_AcquireControllerLockRF acquires exclusive access to Controller,
-  but is only called from the request function with the io_request_lock held.
-*/
+static inline
+boolean DAC960_LP_HardwareMailboxFullP(void *ControllerBaseAddress)
+{
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
+  return InboundDoorBellRegister.Read.HardwareMailboxFull;
+}
 
 static inline
-void DAC960_AcquireControllerLockRF(DAC960_Controller_T *Controller,
-				    ProcessorFlags_T *ProcessorFlags)
+boolean DAC960_LP_InitializationInProgressP(void *ControllerBaseAddress)
 {
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
+  return InboundDoorBellRegister.Read.InitializationInProgress;
 }
 
+static inline
+void DAC960_LP_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
+  writeb(OutboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
+}
 
-/*
-  DAC960_ReleaseControllerLockRF releases exclusive access to Controller,
-  but is only called from the request function with the io_request_lock held.
-*/
+static inline
+void DAC960_LP_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
+  writeb(OutboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
+}
 
 static inline
-void DAC960_ReleaseControllerLockRF(DAC960_Controller_T *Controller,
-				    ProcessorFlags_T *ProcessorFlags)
+void DAC960_LP_AcknowledgeInterrupt(void *ControllerBaseAddress)
 {
+  DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
+  OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
+  writeb(OutboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
 }
 
+static inline
+boolean DAC960_LP_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
+{
+  DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
+  return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
+}
 
-/*
-  DAC960_AcquireControllerLockIH acquires exclusive access to Controller,
-  but is only called from the interrupt handler.
-*/
+static inline
+boolean DAC960_LP_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
+{
+  DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
+  return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
+}
 
 static inline
-void DAC960_AcquireControllerLockIH(DAC960_Controller_T *Controller,
-				    ProcessorFlags_T *ProcessorFlags)
+void DAC960_LP_EnableInterrupts(void *ControllerBaseAddress)
 {
-  spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
+  DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All = 0xFF;
+  InterruptMaskRegister.Bits.DisableInterrupts = false;
+  writeb(InterruptMaskRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset);
 }
 
+static inline
+void DAC960_LP_DisableInterrupts(void *ControllerBaseAddress)
+{
+  DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All = 0xFF;
+  InterruptMaskRegister.Bits.DisableInterrupts = true;
+  writeb(InterruptMaskRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset);
+}
 
-/*
-  DAC960_ReleaseControllerLockIH releases exclusive access to Controller,
-  but is only called from the interrupt handler.
-*/
+static inline
+boolean DAC960_LP_InterruptsEnabledP(void *ControllerBaseAddress)
+{
+  DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All =
+    readb(ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset);
+  return !InterruptMaskRegister.Bits.DisableInterrupts;
+}
 
 static inline
-void DAC960_ReleaseControllerLockIH(DAC960_Controller_T *Controller,
-				    ProcessorFlags_T *ProcessorFlags)
+void DAC960_LP_WriteCommandMailbox(DAC960_V2_CommandMailbox_T
+				     *MemoryCommandMailbox,
+				   DAC960_V2_CommandMailbox_T
+				     *CommandMailbox)
 {
-  spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
+  memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1],
+	 sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int));
+  wmb();
+  MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
+  mb();
+}
+
+static inline
+void DAC960_LP_WriteHardwareMailbox(void *ControllerBaseAddress,
+				    DAC960_V2_CommandMailbox_T *CommandMailbox)
+{
+  writel(Virtual_to_Bus(CommandMailbox),
+	 ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset);
+}
+
+static inline DAC960_V2_CommandIdentifier_T
+DAC960_LP_ReadCommandIdentifier(void *ControllerBaseAddress)
+{
+  return readw(ControllerBaseAddress + DAC960_LP_CommandStatusOffset);
+}
+
+static inline DAC960_V2_CommandStatus_T
+DAC960_LP_ReadCommandStatus(void *ControllerBaseAddress)
+{
+  return readw(ControllerBaseAddress + DAC960_LP_CommandStatusOffset + 2);
+}
+
+static inline boolean
+DAC960_LP_ReadErrorStatus(void *ControllerBaseAddress,
+			  unsigned char *ErrorStatus,
+			  unsigned char *Parameter0,
+			  unsigned char *Parameter1)
+{
+  DAC960_LP_ErrorStatusRegister_T ErrorStatusRegister;
+  ErrorStatusRegister.All =
+    readb(ControllerBaseAddress + DAC960_LP_ErrorStatusRegisterOffset);
+  if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
+  ErrorStatusRegister.Bits.ErrorStatusPending = false;
+  *ErrorStatus = ErrorStatusRegister.All;
+  *Parameter0 =
+    readb(ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset + 0);
+  *Parameter1 =
+    readb(ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset + 1);
+  writeb(0xFF, ControllerBaseAddress + DAC960_LP_ErrorStatusRegisterOffset);
+  return true;
 }
 
 
 /*
-  Define the DAC960 V5 Controller Interface Register Offsets.
+  Define the DAC960 LA Series Controller Interface Register Offsets.
 */
 
-#define DAC960_V5_RegisterWindowSize		0x80
+#define DAC960_LA_RegisterWindowSize		0x80
 
 typedef enum
 {
-  DAC960_V5_InboundDoorBellRegisterOffset =	0x60,
-  DAC960_V5_OutboundDoorBellRegisterOffset =	0x61,
-  DAC960_V5_InterruptMaskRegisterOffset =	0x34,
-  DAC960_V5_CommandOpcodeRegisterOffset =	0x50,
-  DAC960_V5_CommandIdentifierRegisterOffset =	0x51,
-  DAC960_V5_MailboxRegister2Offset =		0x52,
-  DAC960_V5_MailboxRegister3Offset =		0x53,
-  DAC960_V5_MailboxRegister4Offset =		0x54,
-  DAC960_V5_MailboxRegister5Offset =		0x55,
-  DAC960_V5_MailboxRegister6Offset =		0x56,
-  DAC960_V5_MailboxRegister7Offset =		0x57,
-  DAC960_V5_MailboxRegister8Offset =		0x58,
-  DAC960_V5_MailboxRegister9Offset =		0x59,
-  DAC960_V5_MailboxRegister10Offset =		0x5A,
-  DAC960_V5_MailboxRegister11Offset =		0x5B,
-  DAC960_V5_MailboxRegister12Offset =		0x5C,
-  DAC960_V5_StatusCommandIdentifierRegOffset =	0x5D,
-  DAC960_V5_StatusRegisterOffset =		0x5E,
-  DAC960_V5_ErrorStatusRegisterOffset =		0x63
+  DAC960_LA_InboundDoorBellRegisterOffset =	0x60,
+  DAC960_LA_OutboundDoorBellRegisterOffset =	0x61,
+  DAC960_LA_InterruptMaskRegisterOffset =	0x34,
+  DAC960_LA_CommandOpcodeRegisterOffset =	0x50,
+  DAC960_LA_CommandIdentifierRegisterOffset =	0x51,
+  DAC960_LA_MailboxRegister2Offset =		0x52,
+  DAC960_LA_MailboxRegister3Offset =		0x53,
+  DAC960_LA_MailboxRegister4Offset =		0x54,
+  DAC960_LA_MailboxRegister5Offset =		0x55,
+  DAC960_LA_MailboxRegister6Offset =		0x56,
+  DAC960_LA_MailboxRegister7Offset =		0x57,
+  DAC960_LA_MailboxRegister8Offset =		0x58,
+  DAC960_LA_MailboxRegister9Offset =		0x59,
+  DAC960_LA_MailboxRegister10Offset =		0x5A,
+  DAC960_LA_MailboxRegister11Offset =		0x5B,
+  DAC960_LA_MailboxRegister12Offset =		0x5C,
+  DAC960_LA_StatusCommandIdentifierRegOffset =	0x5D,
+  DAC960_LA_StatusRegisterOffset =		0x5E,
+  DAC960_LA_ErrorStatusRegisterOffset =		0x63
 }
-DAC960_V5_RegisterOffsets_T;
+DAC960_LA_RegisterOffsets_T;
 
 
 /*
-  Define the structure of the DAC960 V5 Inbound Door Bell Register.
+  Define the structure of the DAC960 LA Series Inbound Door Bell Register.
 */
 
-typedef union DAC960_V5_InboundDoorBellRegister
+typedef union DAC960_LA_InboundDoorBellRegister
 {
   unsigned char All;
   struct {
@@ -1426,14 +3179,14 @@
     unsigned char :6;					/* Bits 2-7 */
   } Read;
 }
-DAC960_V5_InboundDoorBellRegister_T;
+DAC960_LA_InboundDoorBellRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V5 Outbound Door Bell Register.
+  Define the structure of the DAC960 LA Series Outbound Door Bell Register.
 */
 
-typedef union DAC960_V5_OutboundDoorBellRegister
+typedef union DAC960_LA_OutboundDoorBellRegister
 {
   unsigned char All;
   struct {
@@ -1447,14 +3200,14 @@
     unsigned char :6;					/* Bits 2-7 */
   } Read;
 }
-DAC960_V5_OutboundDoorBellRegister_T;
+DAC960_LA_OutboundDoorBellRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V5 Interrupt Mask Register.
+  Define the structure of the DAC960 LA Series Interrupt Mask Register.
 */
 
-typedef union DAC960_V5_InterruptMaskRegister
+typedef union DAC960_LA_InterruptMaskRegister
 {
   unsigned char All;
   struct {
@@ -1463,14 +3216,14 @@
     unsigned char :5;					/* Bits 3-7 */
   } Bits;
 }
-DAC960_V5_InterruptMaskRegister_T;
+DAC960_LA_InterruptMaskRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V5 Error Status Register.
+  Define the structure of the DAC960 LA Series Error Status Register.
 */
 
-typedef union DAC960_V5_ErrorStatusRegister
+typedef union DAC960_LA_ErrorStatusRegister
 {
   unsigned char All;
   struct {
@@ -1479,288 +3232,294 @@
     unsigned int :5;					/* Bits 3-7 */
   } Bits;
 }
-DAC960_V5_ErrorStatusRegister_T;
+DAC960_LA_ErrorStatusRegister_T;
 
 
 /*
   Define inline functions to provide an abstraction for reading and writing the
-  DAC960 V5 Controller Interface Registers.
+  DAC960 LA Series Controller Interface Registers.
 */
 
 static inline
-void DAC960_V5_HardwareMailboxNewCommand(void *ControllerBaseAddress)
+void DAC960_LA_HardwareMailboxNewCommand(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V5_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
+void DAC960_LA_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V5_GenerateInterrupt(void *ControllerBaseAddress)
+void DAC960_LA_GenerateInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.GenerateInterrupt = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V5_ControllerReset(void *ControllerBaseAddress)
+void DAC960_LA_ControllerReset(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.ControllerReset = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V5_MemoryMailboxNewCommand(void *ControllerBaseAddress)
+void DAC960_LA_MemoryMailboxNewCommand(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
 }
 
 static inline
-boolean DAC960_V5_HardwareMailboxFullP(void *ControllerBaseAddress)
+boolean DAC960_LA_HardwareMailboxFullP(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
   return !InboundDoorBellRegister.Read.HardwareMailboxEmpty;
 }
 
 static inline
-boolean DAC960_V5_InitializationInProgressP(void *ControllerBaseAddress)
+boolean DAC960_LA_InitializationInProgressP(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
   return !InboundDoorBellRegister.Read.InitializationNotInProgress;
 }
 
 static inline
-void DAC960_V5_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
+void DAC960_LA_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
   writeb(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V5_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
+void DAC960_LA_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
   writeb(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V5_AcknowledgeInterrupt(void *ControllerBaseAddress)
+void DAC960_LA_AcknowledgeInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
   writeb(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-boolean DAC960_V5_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
+boolean DAC960_LA_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
 {
-  DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
   return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
 }
 
 static inline
-boolean DAC960_V5_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
+boolean DAC960_LA_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
 {
-  DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
   return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
 }
 
 static inline
-void DAC960_V5_EnableInterrupts(void *ControllerBaseAddress)
+void DAC960_LA_EnableInterrupts(void *ControllerBaseAddress)
 {
-  DAC960_V5_InterruptMaskRegister_T InterruptMaskRegister;
+  DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister;
   InterruptMaskRegister.All = 0xFF;
   InterruptMaskRegister.Bits.DisableInterrupts = false;
   writeb(InterruptMaskRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InterruptMaskRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset);
 }
 
 static inline
-void DAC960_V5_DisableInterrupts(void *ControllerBaseAddress)
+void DAC960_LA_DisableInterrupts(void *ControllerBaseAddress)
 {
-  DAC960_V5_InterruptMaskRegister_T InterruptMaskRegister;
+  DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister;
   InterruptMaskRegister.All = 0xFF;
   InterruptMaskRegister.Bits.DisableInterrupts = true;
   writeb(InterruptMaskRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InterruptMaskRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset);
 }
 
 static inline
-boolean DAC960_V5_InterruptsEnabledP(void *ControllerBaseAddress)
+boolean DAC960_LA_InterruptsEnabledP(void *ControllerBaseAddress)
 {
-  DAC960_V5_InterruptMaskRegister_T InterruptMaskRegister;
+  DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister;
   InterruptMaskRegister.All =
-    readb(ControllerBaseAddress + DAC960_V5_InterruptMaskRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset);
   return !InterruptMaskRegister.Bits.DisableInterrupts;
 }
 
 static inline
-void DAC960_V5_WriteCommandMailbox(DAC960_CommandMailbox_T *NextCommandMailbox,
-				   DAC960_CommandMailbox_T *CommandMailbox)
-{
-  NextCommandMailbox->Words[1] = CommandMailbox->Words[1];
-  NextCommandMailbox->Words[2] = CommandMailbox->Words[2];
-  NextCommandMailbox->Words[3] = CommandMailbox->Words[3];
+void DAC960_LA_WriteCommandMailbox(DAC960_V1_CommandMailbox_T
+				     *MemoryCommandMailbox,
+				   DAC960_V1_CommandMailbox_T
+				     *CommandMailbox)
+{
+  MemoryCommandMailbox->Words[1] = CommandMailbox->Words[1];
+  MemoryCommandMailbox->Words[2] = CommandMailbox->Words[2];
+  MemoryCommandMailbox->Words[3] = CommandMailbox->Words[3];
   wmb();
-  NextCommandMailbox->Words[0] = CommandMailbox->Words[0];
+  MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
   mb();
 }
 
 static inline
-void DAC960_V5_WriteHardwareMailbox(void *ControllerBaseAddress,
-				    DAC960_CommandMailbox_T *CommandMailbox)
+void DAC960_LA_WriteHardwareMailbox(void *ControllerBaseAddress,
+				    DAC960_V1_CommandMailbox_T *CommandMailbox)
 {
   writel(CommandMailbox->Words[0],
-	 ControllerBaseAddress + DAC960_V5_CommandOpcodeRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset);
   writel(CommandMailbox->Words[1],
-	 ControllerBaseAddress + DAC960_V5_MailboxRegister4Offset);
+	 ControllerBaseAddress + DAC960_LA_MailboxRegister4Offset);
   writel(CommandMailbox->Words[2],
-	 ControllerBaseAddress + DAC960_V5_MailboxRegister8Offset);
+	 ControllerBaseAddress + DAC960_LA_MailboxRegister8Offset);
   writeb(CommandMailbox->Bytes[12],
-	 ControllerBaseAddress + DAC960_V5_MailboxRegister12Offset);
+	 ControllerBaseAddress + DAC960_LA_MailboxRegister12Offset);
 }
 
-static inline DAC960_CommandIdentifier_T
-DAC960_V5_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
+static inline DAC960_V1_CommandIdentifier_T
+DAC960_LA_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
 {
   return readb(ControllerBaseAddress
-	       + DAC960_V5_StatusCommandIdentifierRegOffset);
+	       + DAC960_LA_StatusCommandIdentifierRegOffset);
 }
 
-static inline DAC960_CommandStatus_T
-DAC960_V5_ReadStatusRegister(void *ControllerBaseAddress)
+static inline DAC960_V1_CommandStatus_T
+DAC960_LA_ReadStatusRegister(void *ControllerBaseAddress)
 {
-  return readw(ControllerBaseAddress + DAC960_V5_StatusRegisterOffset);
+  return readw(ControllerBaseAddress + DAC960_LA_StatusRegisterOffset);
 }
 
 static inline boolean
-DAC960_V5_ReadErrorStatus(void *ControllerBaseAddress,
+DAC960_LA_ReadErrorStatus(void *ControllerBaseAddress,
 			  unsigned char *ErrorStatus,
 			  unsigned char *Parameter0,
 			  unsigned char *Parameter1)
 {
-  DAC960_V5_ErrorStatusRegister_T ErrorStatusRegister;
+  DAC960_LA_ErrorStatusRegister_T ErrorStatusRegister;
   ErrorStatusRegister.All =
-    readb(ControllerBaseAddress + DAC960_V5_ErrorStatusRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_ErrorStatusRegisterOffset);
   if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
   ErrorStatusRegister.Bits.ErrorStatusPending = false;
   *ErrorStatus = ErrorStatusRegister.All;
   *Parameter0 =
-    readb(ControllerBaseAddress + DAC960_V5_CommandOpcodeRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset);
   *Parameter1 =
-    readb(ControllerBaseAddress + DAC960_V5_CommandIdentifierRegisterOffset);
-  writeb(0xFF, ControllerBaseAddress + DAC960_V5_ErrorStatusRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_CommandIdentifierRegisterOffset);
+  writeb(0xFF, ControllerBaseAddress + DAC960_LA_ErrorStatusRegisterOffset);
   return true;
 }
 
 static inline
-void DAC960_V5_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
+void DAC960_LA_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
 {
+#ifdef __i386__
   void *ControllerBaseAddress = Controller->BaseAddress;
   writel(0x743C485E,
-	 ControllerBaseAddress + DAC960_V5_CommandOpcodeRegisterOffset);
-  writel((unsigned long) Controller->FirstCommandMailbox,
-	 ControllerBaseAddress + DAC960_V5_MailboxRegister4Offset);
-  writew(Controller->NextCommandMailbox - Controller->FirstCommandMailbox,
-	 ControllerBaseAddress + DAC960_V5_MailboxRegister8Offset);
-  writew(Controller->NextStatusMailbox - Controller->FirstStatusMailbox,
-	 ControllerBaseAddress + DAC960_V5_MailboxRegister10Offset);
+	 ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset);
+  writel((unsigned long) Controller->V1.FirstCommandMailbox,
+	 ControllerBaseAddress + DAC960_LA_MailboxRegister4Offset);
+  writew(Controller->V1.NextCommandMailbox - Controller->V1.FirstCommandMailbox,
+	 ControllerBaseAddress + DAC960_LA_MailboxRegister8Offset);
+  writew(Controller->V1.NextStatusMailbox - Controller->V1.FirstStatusMailbox,
+	 ControllerBaseAddress + DAC960_LA_MailboxRegister10Offset);
+#endif
 }
 
 static inline
-void DAC960_V5_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
+void DAC960_LA_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
 					void **MemoryMailboxAddress,
 					short *NextCommandMailboxIndex,
 					short *NextStatusMailboxIndex)
 {
+#ifdef __i386__
   void *ControllerBaseAddress = Controller->BaseAddress;
   if (readl(ControllerBaseAddress
-	    + DAC960_V5_CommandOpcodeRegisterOffset) != 0x743C485E)
+	    + DAC960_LA_CommandOpcodeRegisterOffset) != 0x743C485E)
     return;
   *MemoryMailboxAddress =
-    (void *) readl(ControllerBaseAddress + DAC960_V5_MailboxRegister4Offset);
+    (void *) readl(ControllerBaseAddress + DAC960_LA_MailboxRegister4Offset);
   *NextCommandMailboxIndex =
-    readw(ControllerBaseAddress + DAC960_V5_MailboxRegister8Offset);
+    readw(ControllerBaseAddress + DAC960_LA_MailboxRegister8Offset);
   *NextStatusMailboxIndex =
-    readw(ControllerBaseAddress + DAC960_V5_MailboxRegister10Offset);
+    readw(ControllerBaseAddress + DAC960_LA_MailboxRegister10Offset);
+#endif
 }
 
 
 /*
-  Define the DAC960 V4 Controller Interface Register Offsets.
+  Define the DAC960 PG Series Controller Interface Register Offsets.
 */
 
-#define DAC960_V4_RegisterWindowSize		0x2000
+#define DAC960_PG_RegisterWindowSize		0x2000
 
 typedef enum
 {
-  DAC960_V4_InboundDoorBellRegisterOffset =	0x0020,
-  DAC960_V4_OutboundDoorBellRegisterOffset =	0x002C,
-  DAC960_V4_InterruptMaskRegisterOffset =	0x0034,
-  DAC960_V4_CommandOpcodeRegisterOffset =	0x1000,
-  DAC960_V4_CommandIdentifierRegisterOffset =	0x1001,
-  DAC960_V4_MailboxRegister2Offset =		0x1002,
-  DAC960_V4_MailboxRegister3Offset =		0x1003,
-  DAC960_V4_MailboxRegister4Offset =		0x1004,
-  DAC960_V4_MailboxRegister5Offset =		0x1005,
-  DAC960_V4_MailboxRegister6Offset =		0x1006,
-  DAC960_V4_MailboxRegister7Offset =		0x1007,
-  DAC960_V4_MailboxRegister8Offset =		0x1008,
-  DAC960_V4_MailboxRegister9Offset =		0x1009,
-  DAC960_V4_MailboxRegister10Offset =		0x100A,
-  DAC960_V4_MailboxRegister11Offset =		0x100B,
-  DAC960_V4_MailboxRegister12Offset =		0x100C,
-  DAC960_V4_StatusCommandIdentifierRegOffset =	0x1018,
-  DAC960_V4_StatusRegisterOffset =		0x101A,
-  DAC960_V4_ErrorStatusRegisterOffset =		0x103F
+  DAC960_PG_InboundDoorBellRegisterOffset =	0x0020,
+  DAC960_PG_OutboundDoorBellRegisterOffset =	0x002C,
+  DAC960_PG_InterruptMaskRegisterOffset =	0x0034,
+  DAC960_PG_CommandOpcodeRegisterOffset =	0x1000,
+  DAC960_PG_CommandIdentifierRegisterOffset =	0x1001,
+  DAC960_PG_MailboxRegister2Offset =		0x1002,
+  DAC960_PG_MailboxRegister3Offset =		0x1003,
+  DAC960_PG_MailboxRegister4Offset =		0x1004,
+  DAC960_PG_MailboxRegister5Offset =		0x1005,
+  DAC960_PG_MailboxRegister6Offset =		0x1006,
+  DAC960_PG_MailboxRegister7Offset =		0x1007,
+  DAC960_PG_MailboxRegister8Offset =		0x1008,
+  DAC960_PG_MailboxRegister9Offset =		0x1009,
+  DAC960_PG_MailboxRegister10Offset =		0x100A,
+  DAC960_PG_MailboxRegister11Offset =		0x100B,
+  DAC960_PG_MailboxRegister12Offset =		0x100C,
+  DAC960_PG_StatusCommandIdentifierRegOffset =	0x1018,
+  DAC960_PG_StatusRegisterOffset =		0x101A,
+  DAC960_PG_ErrorStatusRegisterOffset =		0x103F
 }
-DAC960_V4_RegisterOffsets_T;
+DAC960_PG_RegisterOffsets_T;
 
 
 /*
-  Define the structure of the DAC960 V4 Inbound Door Bell Register.
+  Define the structure of the DAC960 PG Series Inbound Door Bell Register.
 */
 
-typedef union DAC960_V4_InboundDoorBellRegister
+typedef union DAC960_PG_InboundDoorBellRegister
 {
   unsigned int All;
   struct {
@@ -1777,14 +3536,14 @@
     unsigned int :30;					/* Bits 2-31 */
   } Read;
 }
-DAC960_V4_InboundDoorBellRegister_T;
+DAC960_PG_InboundDoorBellRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V4 Outbound Door Bell Register.
+  Define the structure of the DAC960 PG Series Outbound Door Bell Register.
 */
 
-typedef union DAC960_V4_OutboundDoorBellRegister
+typedef union DAC960_PG_OutboundDoorBellRegister
 {
   unsigned int All;
   struct {
@@ -1798,14 +3557,14 @@
     unsigned int :30;					/* Bits 2-31 */
   } Read;
 }
-DAC960_V4_OutboundDoorBellRegister_T;
+DAC960_PG_OutboundDoorBellRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V4 Interrupt Mask Register.
+  Define the structure of the DAC960 PG Series Interrupt Mask Register.
 */
 
-typedef union DAC960_V4_InterruptMaskRegister
+typedef union DAC960_PG_InterruptMaskRegister
 {
   unsigned int All;
   struct {
@@ -1815,14 +3574,14 @@
     unsigned int Reserved0:24;				/* Bits 8-31 */
   } Bits;
 }
-DAC960_V4_InterruptMaskRegister_T;
+DAC960_PG_InterruptMaskRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V4 Error Status Register.
+  Define the structure of the DAC960 PG Series Error Status Register.
 */
 
-typedef union DAC960_V4_ErrorStatusRegister
+typedef union DAC960_PG_ErrorStatusRegister
 {
   unsigned char All;
   struct {
@@ -1831,292 +3590,298 @@
     unsigned int :5;					/* Bits 3-7 */
   } Bits;
 }
-DAC960_V4_ErrorStatusRegister_T;
+DAC960_PG_ErrorStatusRegister_T;
 
 
 /*
   Define inline functions to provide an abstraction for reading and writing the
-  DAC960 V4 Controller Interface Registers.
+  DAC960 PG Series Controller Interface Registers.
 */
 
 static inline
-void DAC960_V4_HardwareMailboxNewCommand(void *ControllerBaseAddress)
+void DAC960_PG_HardwareMailboxNewCommand(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
   writel(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V4_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
+void DAC960_PG_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
   writel(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V4_GenerateInterrupt(void *ControllerBaseAddress)
+void DAC960_PG_GenerateInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.GenerateInterrupt = true;
   writel(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V4_ControllerReset(void *ControllerBaseAddress)
+void DAC960_PG_ControllerReset(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.ControllerReset = true;
   writel(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V4_MemoryMailboxNewCommand(void *ControllerBaseAddress)
+void DAC960_PG_MemoryMailboxNewCommand(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
   writel(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
 }
 
 static inline
-boolean DAC960_V4_HardwareMailboxFullP(void *ControllerBaseAddress)
+boolean DAC960_PG_HardwareMailboxFullP(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All =
-    readl(ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+    readl(ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
   return InboundDoorBellRegister.Read.HardwareMailboxFull;
 }
 
 static inline
-boolean DAC960_V4_InitializationInProgressP(void *ControllerBaseAddress)
+boolean DAC960_PG_InitializationInProgressP(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All =
-    readl(ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+    readl(ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
   return InboundDoorBellRegister.Read.InitializationInProgress;
 }
 
 static inline
-void DAC960_V4_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
+void DAC960_PG_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
   writel(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V4_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
+void DAC960_PG_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
   writel(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V4_AcknowledgeInterrupt(void *ControllerBaseAddress)
+void DAC960_PG_AcknowledgeInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
   writel(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-boolean DAC960_V4_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
+boolean DAC960_PG_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
 {
-  DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All =
-    readl(ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
+    readl(ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
   return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
 }
 
 static inline
-boolean DAC960_V4_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
+boolean DAC960_PG_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
 {
-  DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All =
-    readl(ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
+    readl(ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
   return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
 }
 
 static inline
-void DAC960_V4_EnableInterrupts(void *ControllerBaseAddress)
+void DAC960_PG_EnableInterrupts(void *ControllerBaseAddress)
 {
-  DAC960_V4_InterruptMaskRegister_T InterruptMaskRegister;
+  DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister;
   InterruptMaskRegister.All = 0;
   InterruptMaskRegister.Bits.MessageUnitInterruptMask1 = 0x3;
   InterruptMaskRegister.Bits.DisableInterrupts = false;
   InterruptMaskRegister.Bits.MessageUnitInterruptMask2 = 0x1F;
   writel(InterruptMaskRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InterruptMaskRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset);
 }
 
 static inline
-void DAC960_V4_DisableInterrupts(void *ControllerBaseAddress)
+void DAC960_PG_DisableInterrupts(void *ControllerBaseAddress)
 {
-  DAC960_V4_InterruptMaskRegister_T InterruptMaskRegister;
+  DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister;
   InterruptMaskRegister.All = 0;
   InterruptMaskRegister.Bits.MessageUnitInterruptMask1 = 0x3;
   InterruptMaskRegister.Bits.DisableInterrupts = true;
   InterruptMaskRegister.Bits.MessageUnitInterruptMask2 = 0x1F;
   writel(InterruptMaskRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InterruptMaskRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset);
 }
 
 static inline
-boolean DAC960_V4_InterruptsEnabledP(void *ControllerBaseAddress)
+boolean DAC960_PG_InterruptsEnabledP(void *ControllerBaseAddress)
 {
-  DAC960_V4_InterruptMaskRegister_T InterruptMaskRegister;
+  DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister;
   InterruptMaskRegister.All =
-    readl(ControllerBaseAddress + DAC960_V4_InterruptMaskRegisterOffset);
+    readl(ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset);
   return !InterruptMaskRegister.Bits.DisableInterrupts;
 }
 
 static inline
-void DAC960_V4_WriteCommandMailbox(DAC960_CommandMailbox_T *NextCommandMailbox,
-				   DAC960_CommandMailbox_T *CommandMailbox)
-{
-  NextCommandMailbox->Words[1] = CommandMailbox->Words[1];
-  NextCommandMailbox->Words[2] = CommandMailbox->Words[2];
-  NextCommandMailbox->Words[3] = CommandMailbox->Words[3];
+void DAC960_PG_WriteCommandMailbox(DAC960_V1_CommandMailbox_T
+				     *MemoryCommandMailbox,
+				   DAC960_V1_CommandMailbox_T
+				     *CommandMailbox)
+{
+  MemoryCommandMailbox->Words[1] = CommandMailbox->Words[1];
+  MemoryCommandMailbox->Words[2] = CommandMailbox->Words[2];
+  MemoryCommandMailbox->Words[3] = CommandMailbox->Words[3];
   wmb();
-  NextCommandMailbox->Words[0] = CommandMailbox->Words[0];
+  MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
   mb();
 }
 
 static inline
-void DAC960_V4_WriteHardwareMailbox(void *ControllerBaseAddress,
-				    DAC960_CommandMailbox_T *CommandMailbox)
+void DAC960_PG_WriteHardwareMailbox(void *ControllerBaseAddress,
+				    DAC960_V1_CommandMailbox_T *CommandMailbox)
 {
   writel(CommandMailbox->Words[0],
-	 ControllerBaseAddress + DAC960_V4_CommandOpcodeRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset);
   writel(CommandMailbox->Words[1],
-	 ControllerBaseAddress + DAC960_V4_MailboxRegister4Offset);
+	 ControllerBaseAddress + DAC960_PG_MailboxRegister4Offset);
   writel(CommandMailbox->Words[2],
-	 ControllerBaseAddress + DAC960_V4_MailboxRegister8Offset);
+	 ControllerBaseAddress + DAC960_PG_MailboxRegister8Offset);
   writeb(CommandMailbox->Bytes[12],
-	 ControllerBaseAddress + DAC960_V4_MailboxRegister12Offset);
+	 ControllerBaseAddress + DAC960_PG_MailboxRegister12Offset);
 }
 
-static inline DAC960_CommandIdentifier_T
-DAC960_V4_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
+static inline DAC960_V1_CommandIdentifier_T
+DAC960_PG_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
 {
   return readb(ControllerBaseAddress
-	       + DAC960_V4_StatusCommandIdentifierRegOffset);
+	       + DAC960_PG_StatusCommandIdentifierRegOffset);
 }
 
-static inline DAC960_CommandStatus_T
-DAC960_V4_ReadStatusRegister(void *ControllerBaseAddress)
+static inline DAC960_V1_CommandStatus_T
+DAC960_PG_ReadStatusRegister(void *ControllerBaseAddress)
 {
-  return readw(ControllerBaseAddress + DAC960_V4_StatusRegisterOffset);
+  return readw(ControllerBaseAddress + DAC960_PG_StatusRegisterOffset);
 }
 
 static inline boolean
-DAC960_V4_ReadErrorStatus(void *ControllerBaseAddress,
+DAC960_PG_ReadErrorStatus(void *ControllerBaseAddress,
 			  unsigned char *ErrorStatus,
 			  unsigned char *Parameter0,
 			  unsigned char *Parameter1)
 {
-  DAC960_V4_ErrorStatusRegister_T ErrorStatusRegister;
+  DAC960_PG_ErrorStatusRegister_T ErrorStatusRegister;
   ErrorStatusRegister.All =
-    readb(ControllerBaseAddress + DAC960_V4_ErrorStatusRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PG_ErrorStatusRegisterOffset);
   if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
   ErrorStatusRegister.Bits.ErrorStatusPending = false;
   *ErrorStatus = ErrorStatusRegister.All;
   *Parameter0 =
-    readb(ControllerBaseAddress + DAC960_V4_CommandOpcodeRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset);
   *Parameter1 =
-    readb(ControllerBaseAddress + DAC960_V4_CommandIdentifierRegisterOffset);
-  writeb(0, ControllerBaseAddress + DAC960_V4_ErrorStatusRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PG_CommandIdentifierRegisterOffset);
+  writeb(0, ControllerBaseAddress + DAC960_PG_ErrorStatusRegisterOffset);
   return true;
 }
 
 static inline
-void DAC960_V4_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
+void DAC960_PG_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
 {
+#ifdef __i386__
   void *ControllerBaseAddress = Controller->BaseAddress;
   writel(0x743C485E,
-	 ControllerBaseAddress + DAC960_V4_CommandOpcodeRegisterOffset);
-  writel((unsigned long) Controller->FirstCommandMailbox,
-	 ControllerBaseAddress + DAC960_V4_MailboxRegister4Offset);
-  writew(Controller->NextCommandMailbox - Controller->FirstCommandMailbox,
-	 ControllerBaseAddress + DAC960_V4_MailboxRegister8Offset);
-  writew(Controller->NextStatusMailbox - Controller->FirstStatusMailbox,
-	 ControllerBaseAddress + DAC960_V4_MailboxRegister10Offset);
+	 ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset);
+  writel((unsigned long) Controller->V1.FirstCommandMailbox,
+	 ControllerBaseAddress + DAC960_PG_MailboxRegister4Offset);
+  writew(Controller->V1.NextCommandMailbox - Controller->V1.FirstCommandMailbox,
+	 ControllerBaseAddress + DAC960_PG_MailboxRegister8Offset);
+  writew(Controller->V1.NextStatusMailbox - Controller->V1.FirstStatusMailbox,
+	 ControllerBaseAddress + DAC960_PG_MailboxRegister10Offset);
+#endif
 }
 
 static inline
-void DAC960_V4_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
+void DAC960_PG_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
 					void **MemoryMailboxAddress,
 					short *NextCommandMailboxIndex,
 					short *NextStatusMailboxIndex)
 {
+#ifdef __i386__
   void *ControllerBaseAddress = Controller->BaseAddress;
   if (readl(ControllerBaseAddress
-	    + DAC960_V4_CommandOpcodeRegisterOffset) != 0x743C485E)
+	    + DAC960_PG_CommandOpcodeRegisterOffset) != 0x743C485E)
     return;
   *MemoryMailboxAddress =
-    (void *) readl(ControllerBaseAddress + DAC960_V4_MailboxRegister4Offset);
+    (void *) readl(ControllerBaseAddress + DAC960_PG_MailboxRegister4Offset);
   *NextCommandMailboxIndex =
-    readw(ControllerBaseAddress + DAC960_V4_MailboxRegister8Offset);
+    readw(ControllerBaseAddress + DAC960_PG_MailboxRegister8Offset);
   *NextStatusMailboxIndex =
-    readw(ControllerBaseAddress + DAC960_V4_MailboxRegister10Offset);
+    readw(ControllerBaseAddress + DAC960_PG_MailboxRegister10Offset);
+#endif
 }
 
 
 /*
-  Define the DAC960 V3 Controller Interface Register Offsets.
+  Define the DAC960 PD Series Controller Interface Register Offsets.
 */
 
-#define DAC960_V3_RegisterWindowSize		0x80
+#define DAC960_PD_RegisterWindowSize		0x80
 
 typedef enum
 {
-  DAC960_V3_CommandOpcodeRegisterOffset =	0x00,
-  DAC960_V3_CommandIdentifierRegisterOffset =	0x01,
-  DAC960_V3_MailboxRegister2Offset =		0x02,
-  DAC960_V3_MailboxRegister3Offset =		0x03,
-  DAC960_V3_MailboxRegister4Offset =		0x04,
-  DAC960_V3_MailboxRegister5Offset =		0x05,
-  DAC960_V3_MailboxRegister6Offset =		0x06,
-  DAC960_V3_MailboxRegister7Offset =		0x07,
-  DAC960_V3_MailboxRegister8Offset =		0x08,
-  DAC960_V3_MailboxRegister9Offset =		0x09,
-  DAC960_V3_MailboxRegister10Offset =		0x0A,
-  DAC960_V3_MailboxRegister11Offset =		0x0B,
-  DAC960_V3_MailboxRegister12Offset =		0x0C,
-  DAC960_V3_StatusCommandIdentifierRegOffset =	0x0D,
-  DAC960_V3_StatusRegisterOffset =		0x0E,
-  DAC960_V3_ErrorStatusRegisterOffset =		0x3F,
-  DAC960_V3_InboundDoorBellRegisterOffset =	0x40,
-  DAC960_V3_OutboundDoorBellRegisterOffset =	0x41,
-  DAC960_V3_InterruptEnableRegisterOffset =	0x43
+  DAC960_PD_CommandOpcodeRegisterOffset =	0x00,
+  DAC960_PD_CommandIdentifierRegisterOffset =	0x01,
+  DAC960_PD_MailboxRegister2Offset =		0x02,
+  DAC960_PD_MailboxRegister3Offset =		0x03,
+  DAC960_PD_MailboxRegister4Offset =		0x04,
+  DAC960_PD_MailboxRegister5Offset =		0x05,
+  DAC960_PD_MailboxRegister6Offset =		0x06,
+  DAC960_PD_MailboxRegister7Offset =		0x07,
+  DAC960_PD_MailboxRegister8Offset =		0x08,
+  DAC960_PD_MailboxRegister9Offset =		0x09,
+  DAC960_PD_MailboxRegister10Offset =		0x0A,
+  DAC960_PD_MailboxRegister11Offset =		0x0B,
+  DAC960_PD_MailboxRegister12Offset =		0x0C,
+  DAC960_PD_StatusCommandIdentifierRegOffset =	0x0D,
+  DAC960_PD_StatusRegisterOffset =		0x0E,
+  DAC960_PD_ErrorStatusRegisterOffset =		0x3F,
+  DAC960_PD_InboundDoorBellRegisterOffset =	0x40,
+  DAC960_PD_OutboundDoorBellRegisterOffset =	0x41,
+  DAC960_PD_InterruptEnableRegisterOffset =	0x43
 }
-DAC960_V3_RegisterOffsets_T;
+DAC960_PD_RegisterOffsets_T;
 
 
 /*
-  Define the structure of the DAC960 V3 Inbound Door Bell Register.
+  Define the structure of the DAC960 PD Series Inbound Door Bell Register.
 */
 
-typedef union DAC960_V3_InboundDoorBellRegister
+typedef union DAC960_PD_InboundDoorBellRegister
 {
   unsigned char All;
   struct {
@@ -2132,14 +3897,14 @@
     unsigned char :6;					/* Bits 2-7 */
   } Read;
 }
-DAC960_V3_InboundDoorBellRegister_T;
+DAC960_PD_InboundDoorBellRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V3 Outbound Door Bell Register.
+  Define the structure of the DAC960 PD Series Outbound Door Bell Register.
 */
 
-typedef union DAC960_V3_OutboundDoorBellRegister
+typedef union DAC960_PD_OutboundDoorBellRegister
 {
   unsigned char All;
   struct {
@@ -2151,14 +3916,14 @@
     unsigned char :7;					/* Bits 1-7 */
   } Read;
 }
-DAC960_V3_OutboundDoorBellRegister_T;
+DAC960_PD_OutboundDoorBellRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V3 Interrupt Enable Register.
+  Define the structure of the DAC960 PD Series Interrupt Enable Register.
 */
 
-typedef union DAC960_V3_InterruptEnableRegister
+typedef union DAC960_PD_InterruptEnableRegister
 {
   unsigned char All;
   struct {
@@ -2166,14 +3931,14 @@
     unsigned char :7;					/* Bits 1-7 */
   } Bits;
 }
-DAC960_V3_InterruptEnableRegister_T;
+DAC960_PD_InterruptEnableRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V3 Error Status Register.
+  Define the structure of the DAC960 PD Series Error Status Register.
 */
 
-typedef union DAC960_V3_ErrorStatusRegister
+typedef union DAC960_PD_ErrorStatusRegister
 {
   unsigned char All;
   struct {
@@ -2182,187 +3947,176 @@
     unsigned int :5;					/* Bits 3-7 */
   } Bits;
 }
-DAC960_V3_ErrorStatusRegister_T;
+DAC960_PD_ErrorStatusRegister_T;
 
 
 /*
   Define inline functions to provide an abstraction for reading and writing the
-  DAC960 V3 Controller Interface Registers.
+  DAC960 PD Series Controller Interface Registers.
 */
 
 static inline
-void DAC960_V3_NewCommand(void *ControllerBaseAddress)
+void DAC960_PD_NewCommand(void *ControllerBaseAddress)
 {
-  DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.NewCommand = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V3_AcknowledgeStatus(void *ControllerBaseAddress)
+void DAC960_PD_AcknowledgeStatus(void *ControllerBaseAddress)
 {
-  DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.AcknowledgeStatus = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V3_GenerateInterrupt(void *ControllerBaseAddress)
+void DAC960_PD_GenerateInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.GenerateInterrupt = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V3_ControllerReset(void *ControllerBaseAddress)
+void DAC960_PD_ControllerReset(void *ControllerBaseAddress)
 {
-  DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.ControllerReset = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
 }
 
 static inline
-boolean DAC960_V3_MailboxFullP(void *ControllerBaseAddress)
+boolean DAC960_PD_MailboxFullP(void *ControllerBaseAddress)
 {
-  DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
   return InboundDoorBellRegister.Read.MailboxFull;
 }
 
 static inline
-boolean DAC960_V3_InitializationInProgressP(void *ControllerBaseAddress)
+boolean DAC960_PD_InitializationInProgressP(void *ControllerBaseAddress)
 {
-  DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
   return InboundDoorBellRegister.Read.InitializationInProgress;
 }
 
 static inline
-void DAC960_V3_AcknowledgeInterrupt(void *ControllerBaseAddress)
+void DAC960_PD_AcknowledgeInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V3_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PD_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeInterrupt = true;
   writeb(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V3_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-boolean DAC960_V3_StatusAvailableP(void *ControllerBaseAddress)
+boolean DAC960_PD_StatusAvailableP(void *ControllerBaseAddress)
 {
-  DAC960_V3_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PD_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V3_OutboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_OutboundDoorBellRegisterOffset);
   return OutboundDoorBellRegister.Read.StatusAvailable;
 }
 
 static inline
-void DAC960_V3_EnableInterrupts(void *ControllerBaseAddress)
+void DAC960_PD_EnableInterrupts(void *ControllerBaseAddress)
 {
-  DAC960_V3_InterruptEnableRegister_T InterruptEnableRegister;
+  DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister;
   InterruptEnableRegister.All = 0;
   InterruptEnableRegister.Bits.EnableInterrupts = true;
   writeb(InterruptEnableRegister.All,
-	 ControllerBaseAddress + DAC960_V3_InterruptEnableRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset);
 }
 
 static inline
-void DAC960_V3_DisableInterrupts(void *ControllerBaseAddress)
+void DAC960_PD_DisableInterrupts(void *ControllerBaseAddress)
 {
-  DAC960_V3_InterruptEnableRegister_T InterruptEnableRegister;
+  DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister;
   InterruptEnableRegister.All = 0;
   InterruptEnableRegister.Bits.EnableInterrupts = false;
   writeb(InterruptEnableRegister.All,
-	 ControllerBaseAddress + DAC960_V3_InterruptEnableRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset);
 }
 
 static inline
-boolean DAC960_V3_InterruptsEnabledP(void *ControllerBaseAddress)
+boolean DAC960_PD_InterruptsEnabledP(void *ControllerBaseAddress)
 {
-  DAC960_V3_InterruptEnableRegister_T InterruptEnableRegister;
+  DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister;
   InterruptEnableRegister.All =
-    readb(ControllerBaseAddress + DAC960_V3_InterruptEnableRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset);
   return InterruptEnableRegister.Bits.EnableInterrupts;
 }
 
 static inline
-void DAC960_V3_WriteCommandMailbox(void *ControllerBaseAddress,
-				   DAC960_CommandMailbox_T *CommandMailbox)
+void DAC960_PD_WriteCommandMailbox(void *ControllerBaseAddress,
+				   DAC960_V1_CommandMailbox_T *CommandMailbox)
 {
   writel(CommandMailbox->Words[0],
-	 ControllerBaseAddress + DAC960_V3_CommandOpcodeRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_CommandOpcodeRegisterOffset);
   writel(CommandMailbox->Words[1],
-	 ControllerBaseAddress + DAC960_V3_MailboxRegister4Offset);
+	 ControllerBaseAddress + DAC960_PD_MailboxRegister4Offset);
   writel(CommandMailbox->Words[2],
-	 ControllerBaseAddress + DAC960_V3_MailboxRegister8Offset);
+	 ControllerBaseAddress + DAC960_PD_MailboxRegister8Offset);
   writeb(CommandMailbox->Bytes[12],
-	 ControllerBaseAddress + DAC960_V3_MailboxRegister12Offset);
+	 ControllerBaseAddress + DAC960_PD_MailboxRegister12Offset);
 }
 
-static inline DAC960_CommandIdentifier_T
-DAC960_V3_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
+static inline DAC960_V1_CommandIdentifier_T
+DAC960_PD_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
 {
   return readb(ControllerBaseAddress
-	       + DAC960_V3_StatusCommandIdentifierRegOffset);
+	       + DAC960_PD_StatusCommandIdentifierRegOffset);
 }
 
-static inline DAC960_CommandStatus_T
-DAC960_V3_ReadStatusRegister(void *ControllerBaseAddress)
+static inline DAC960_V1_CommandStatus_T
+DAC960_PD_ReadStatusRegister(void *ControllerBaseAddress)
 {
-  return readw(ControllerBaseAddress + DAC960_V3_StatusRegisterOffset);
+  return readw(ControllerBaseAddress + DAC960_PD_StatusRegisterOffset);
 }
 
 static inline boolean
-DAC960_V3_ReadErrorStatus(void *ControllerBaseAddress,
+DAC960_PD_ReadErrorStatus(void *ControllerBaseAddress,
 			  unsigned char *ErrorStatus,
 			  unsigned char *Parameter0,
 			  unsigned char *Parameter1)
 {
-  DAC960_V3_ErrorStatusRegister_T ErrorStatusRegister;
+  DAC960_PD_ErrorStatusRegister_T ErrorStatusRegister;
   ErrorStatusRegister.All =
-    readb(ControllerBaseAddress + DAC960_V3_ErrorStatusRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_ErrorStatusRegisterOffset);
   if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
   ErrorStatusRegister.Bits.ErrorStatusPending = false;
   *ErrorStatus = ErrorStatusRegister.All;
   *Parameter0 =
-    readb(ControllerBaseAddress + DAC960_V3_CommandOpcodeRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_CommandOpcodeRegisterOffset);
   *Parameter1 =
-    readb(ControllerBaseAddress + DAC960_V3_CommandIdentifierRegisterOffset);
-  writeb(0, ControllerBaseAddress + DAC960_V3_ErrorStatusRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_CommandIdentifierRegisterOffset);
+  writeb(0, ControllerBaseAddress + DAC960_PD_ErrorStatusRegisterOffset);
   return true;
 }
 
 
 /*
-  Define compatibility macros between Linux 2.0 and Linux 2.1.
-*/
-
-#if LINUX_VERSION_CODE < 0x20100
-
-#define MODULE_PARM(Variable, Type)
-#define ioremap_nocache(Offset, Size)	vremap(Offset, Size)
-#define iounmap(Address)		vfree(Address)
-
-#endif
-
-
-/*
   Define prototypes for the forward referenced DAC960 Driver Internal Functions.
 */
 
 static void DAC960_FinalizeController(DAC960_Controller_T *);
 static int DAC960_Finalize(NotifierBlock_T *, unsigned long, void *);
+static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *);
+static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *);
 static void DAC960_RequestFunction0(void);
 static void DAC960_RequestFunction1(void);
 static void DAC960_RequestFunction2(void);
@@ -2371,15 +4125,20 @@
 static void DAC960_RequestFunction5(void);
 static void DAC960_RequestFunction6(void);
 static void DAC960_RequestFunction7(void);
-static void DAC960_InterruptHandler(int, void *, Registers_T *);
-static void DAC960_QueueMonitoringCommand(DAC960_Command_T *);
+static void DAC960_BA_InterruptHandler(int, void *, Registers_T *);
+static void DAC960_LP_InterruptHandler(int, void *, Registers_T *);
+static void DAC960_LA_InterruptHandler(int, void *, Registers_T *);
+static void DAC960_PG_InterruptHandler(int, void *, Registers_T *);
+static void DAC960_PD_InterruptHandler(int, void *, Registers_T *);
+static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *);
+static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *);
 static void DAC960_MonitoringTimerFunction(unsigned long);
 static int DAC960_Open(Inode_T *, File_T *);
 static int DAC960_Release(Inode_T *, File_T *);
 static int DAC960_IOCTL(Inode_T *, File_T *, unsigned int, unsigned long);
 static int DAC960_UserIOCTL(Inode_T *, File_T *, unsigned int, unsigned long);
 static void DAC960_InitializeGenericDiskInfo(GenericDiskInfo_T *);
-static void DAC960_Message(DAC960_MessageLevel_T, char *,
+static void DAC960_Message(DAC960_MessageLevel_T, unsigned char *,
 			   DAC960_Controller_T *, ...);
 static void DAC960_CreateProcEntries(void);
 static void DAC960_DestroyProcEntries(void);
diff -urN linux-2.2.17-pre15/drivers/char/rio/linux_compat.h linux/drivers/char/rio/linux_compat.h
--- linux-2.2.17-pre15/drivers/char/rio/linux_compat.h	Mon Dec  3 22:10:44 2001
+++ linux/drivers/char/rio/linux_compat.h	Mon Dec  3 22:10:50 2001
@@ -72,8 +72,6 @@
 
 extern int rio_debug;
 
-#define rio_dprint(f, p) do {if (rio_debug & f) printk p;} while (0)
-
 #define RIO_DEBUG_INIT         0x000001
 #define RIO_DEBUG_BOOT         0x000002
 #define RIO_DEBUG_CMD          0x000004
@@ -92,7 +90,7 @@
 #define RIO_DEBUG_REC          0x008000
 #define RIO_DEBUG_SPINLOCK     0x010000
 #define RIO_DEBUG_DELAY        0x020000
-
+#define RIO_DEBUG_MOD_COUNT    0x040000
 
 /* Copied over from riowinif.h . This is ugly. The winif file declares
 also much other stuff which is incompatible with the headers from
diff -urN linux-2.2.17-pre15/drivers/char/rio/rio_linux.c linux/drivers/char/rio/rio_linux.c
--- linux-2.2.17-pre15/drivers/char/rio/rio_linux.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/char/rio/rio_linux.c	Mon Dec  3 22:10:50 2001
@@ -251,6 +251,8 @@
 
 #ifndef TWO_ZERO
 #ifdef MODULE
+MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.n>");
+MODULE_DESCRIPTION("RIO driver");
 MODULE_PARM(rio_poll, "i");
 MODULE_PARM(rio_debug, "i");
 MODULE_PARM(rio_irqmask, "i");
@@ -397,26 +399,37 @@
 
 void rio_inc_mod_count (void)
 {
+#ifdef MODULE
   func_enter ();
+  rio_dprintk (RIO_DEBUG_MOD_COUNT, "rio_inc_mod_count\n");
   MOD_INC_USE_COUNT; 
   func_exit ();
+#endif
 }
 
 
 void rio_dec_mod_count (void)
 {
+#ifdef MODULE
   func_enter ();
+  rio_dprintk (RIO_DEBUG_MOD_COUNT, "rio_dec_mod_count\n");
   MOD_DEC_USE_COUNT; 
   func_exit ();
+#endif
 }
 
 
 static int rio_set_real_termios (void *ptr)
 {
-  int rv;
+  int rv, modem;
+  struct tty_struct *tty;
   func_enter();
 
-  rv = RIOParam( (struct Port *) ptr, CONFIG, 0, 1);
+  tty = ((struct Port *)ptr)->gs.tty;
+
+  modem = (MAJOR(tty->device) == RIO_NORMAL_MAJOR0) || (MAJOR(tty->device) == RIO_NORMAL_MAJOR1);
+
+  rv = RIOParam( (struct Port *) ptr, CONFIG, modem, 1);
 
   func_exit ();
 
@@ -669,7 +682,7 @@
 static void rio_hungup (void *ptr)
 {
   func_enter ();
-  /* rio_dec_mod_count (); */
+  rio_dec_mod_count (); 
   func_exit ();
 }
 
@@ -680,9 +693,22 @@
  */
 static void rio_close (void *ptr)
 {
+  struct Port *PortP;
+
   func_enter ();
+
+  PortP = (struct Port *)ptr;
+
   riotclose (ptr);
+
+  if(PortP->gs.count) {
+    printk (KERN_ERR "WARNING port count:%d\n", PortP->gs.count);
+    PortP->gs.count = 0; 
+  }                
+
+
   rio_dec_mod_count ();
+
   func_exit ();
 }
 
@@ -1002,7 +1028,7 @@
     port->gs.close_delay = HZ/2;
     port->gs.closing_wait = 30 * HZ;
     port->gs.rd = &rio_real_driver;
-
+    port->portSem = SPIN_LOCK_UNLOCKED;
   }
 #else
   /* We could postpone initializing them to when they are configured. */
@@ -1179,6 +1205,7 @@
       hp->Type  = RIO_PCI;
       hp->Copy  = rio_pcicopy; 
       hp->Mode  = RIO_PCI_BOOT_FROM_RAM;
+      hp->HostLock = SPIN_LOCK_UNLOCKED;
       rio_reset_interrupt (hp);
       rio_start_card_running (hp);
 
diff -urN linux-2.2.17-pre15/drivers/char/rio/rio_linux.h linux/drivers/char/rio/rio_linux.h
--- linux-2.2.17-pre15/drivers/char/rio/rio_linux.h	Mon Dec  3 22:10:44 2001
+++ linux/drivers/char/rio/rio_linux.h	Mon Dec  3 22:10:50 2001
@@ -29,6 +29,8 @@
 #define RIO_PORTSPERBOARD 128
 #define RIO_NPORTS        (RIO_NBOARDS * RIO_PORTSPERBOARD)
 
+#define MODEM_SUPPORT
+
 #ifdef __KERNEL__
 
 #define RIO_MAGIC 0x12345678
@@ -85,31 +87,34 @@
 #endif
 
 
+void rio_dec_mod_count (void);
+void rio_inc_mod_count (void);
+
 /* Allow us to debug "in the field" without requiring clients to
    recompile.... */
 #if 1
 #define rio_spin_lock_irqsave(sem, flags) do { \
-	rio_dprint(RIO_DEBUG_SPINLOCK, ("spinlockirqsave: %p %s:%d\n", \
-					sem, __FILE__, __LINE__));\
+	rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlockirqsave: %p %s:%d\n", \
+					sem, __FILE__, __LINE__);\
         spin_lock_irqsave(sem, flags);\
         } while (0)
 
 #define rio_spin_unlock_irqrestore(sem, flags) do { \
-	rio_dprint(RIO_DEBUG_SPINLOCK, ("spinunlockirqrestore: %p %s:%d\n",\
-					sem, __FILE__, __LINE__));\
+	rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlockirqrestore: %p %s:%d\n",\
+					sem, __FILE__, __LINE__);\
         spin_unlock_irqrestore(sem, flags);\
         } while (0)
 
 
 #define rio_spin_lock(sem) do { \
-	rio_dprint(RIO_DEBUG_SPINLOCK, ("spinlock: %p %s:%d\n",\
-					sem, __FILE__, __LINE__));\
+	rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlock: %p %s:%d\n",\
+					sem, __FILE__, __LINE__);\
         spin_lock(sem);\
         } while (0)
 
 #define rio_spin_unlock(sem) do { \
-	rio_dprint(RIO_DEBUG_SPINLOCK, ("spinunlock: %p %s:%d\n",\
-					sem, __FILE__, __LINE__));\
+	rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlock: %p %s:%d\n",\
+					sem, __FILE__, __LINE__);\
         spin_unlock(sem);\
         } while (0)
 #else
@@ -173,7 +178,7 @@
 */
 
 #ifdef DEBUG
-#define rio_dprintk(f, str...) if (rio_debug & f) printk (str)
+#define rio_dprintk(f, str...) do { if (rio_debug & f) printk (str);} while (0)
 #define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ "\n")
 #define func_exit()  rio_dprintk (RIO_DEBUG_FLOW, "rio: exit  " __FUNCTION__ "\n")
 #define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ \
diff -urN linux-2.2.17-pre15/drivers/char/rio/rioboot.c linux/drivers/char/rio/rioboot.c
--- linux-2.2.17-pre15/drivers/char/rio/rioboot.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/char/rio/rioboot.c	Mon Dec  3 22:10:50 2001
@@ -118,13 +118,13 @@
 	   "copyin". (Crash when a pagefault occurs). */
 	/* disable(oldspl); */
 	
-	rio_dprint(RIO_DEBUG_BOOT, ("Data at user address 0x%x\n",(int)rbp->DataP));
+	rio_dprintk (RIO_DEBUG_BOOT, "Data at user address 0x%x\n",(int)rbp->DataP);
 
 	/*
 	** Check that we have set asside enough memory for this
 	*/
 	if ( rbp->Count > SIXTY_FOUR_K ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code Too Large!\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot Code Too Large!\n");
 		p->RIOError.Error = HOST_FILE_TOO_LARGE;
 		/* restore(oldspl); */
 		func_exit ();
@@ -132,7 +132,7 @@
 	}
 
 	if ( p->RIOBooting ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code : BUSY BUSY BUSY!\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot Code : BUSY BUSY BUSY!\n");
 		p->RIOError.Error = BOOT_IN_PROGRESS;
 		/* restore(oldspl); */
 		func_exit ();
@@ -160,7 +160,7 @@
 
 	if ( copyin((int)rbp->DataP,((caddr_t)(p->RIOBootPackets))+offset,
 				rbp->Count) ==COPYFAIL ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("Bad data copy from user space\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Bad data copy from user space\n");
 		p->RIOError.Error = COPYIN_FAILED;
 		/* restore(oldspl); */
 		func_exit ();
@@ -185,7 +185,7 @@
 
 	switch ( HostP->Type ) {
 	case RIO_AT:
-		rio_dprint(RIO_DEBUG_BOOT, ("Start ISA card running\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Start ISA card running\n");
 		WBYTE(HostP->Control, 
 		      BOOT_FROM_RAM | EXTERNAL_BUS_ON
 		      | HostP->Mode
@@ -198,7 +198,7 @@
 				** MCA handles IRQ vectors differently, so we don't write 
 				** them to this register.
 				*/
-		rio_dprint(RIO_DEBUG_BOOT, ("Start MCA card running\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Start MCA card running\n");
 		WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode);
 		break;
 
@@ -206,7 +206,7 @@
 				/*
 				** EISA is totally different and expects OUTBZs to turn it on.
 				*/
-		rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_DAEMON,"Start EISA card running\n");
+		rio_dprintk (RIO_DEBUG_BOOT, "Start EISA card running\n");
 		OUTBZ( HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM );
 		break;
 #endif
@@ -217,11 +217,11 @@
 				** mapped, so we are writing to memory registers instead of io
 				** ports.
 				*/
-		rio_dprint(RIO_DEBUG_BOOT, ("Start PCI card running\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Start PCI card running\n");
 		WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode);
 		break;
 	default:
-		rio_dprint(RIO_DEBUG_BOOT, ("Unknown host type %d\n",HostP->Type));
+		rio_dprintk (RIO_DEBUG_BOOT, "Unknown host type %d\n", HostP->Type);
 		break;
 	}
 /* 
@@ -260,15 +260,15 @@
 
 	HostP = NULL; /* Assure the compiler we've initialized it */
 	for ( host=0; host<p->RIONumHosts; host++ ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("Attempt to boot host %d\n",host));
+		rio_dprintk (RIO_DEBUG_BOOT, "Attempt to boot host %d\n",host);
 		HostP = &p->RIOHosts[host];
 		
-		rio_dprint(RIO_DEBUG_BOOT,  ("Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
-		    HostP->Type, HostP->Mode, HostP->Ivec ) );
+		rio_dprintk (RIO_DEBUG_BOOT,  "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
+		    HostP->Type, HostP->Mode, HostP->Ivec);
 
 
 		if ( (HostP->Flags & RUN_STATE) != RC_WAITING ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("%s %d already running\n","Host",host));
+			rio_dprintk (RIO_DEBUG_BOOT, "%s %d already running\n","Host",host);
 			continue;
 		}
 
@@ -285,13 +285,13 @@
 		*/
 		StartP = (caddr_t)&Cad[p->RIOConf.HostLoadBase-rbp->Count];
 
-		rio_dprint(RIO_DEBUG_BOOT,  ("kernel virtual address for host is 0x%x\n", (int)Cad ) );
-		rio_dprint(RIO_DEBUG_BOOT,  ("kernel virtual address for download is 0x%x\n", (int)StartP ) );
-		rio_dprint(RIO_DEBUG_BOOT, ("host loadbase is 0x%x\n",p->RIOConf.HostLoadBase));
-		rio_dprint(RIO_DEBUG_BOOT,  ("size of download is 0x%x\n", rbp->Count ) );
+		rio_dprintk (RIO_DEBUG_BOOT, "kernel virtual address for host is 0x%x\n", (int)Cad );
+		rio_dprintk (RIO_DEBUG_BOOT, "kernel virtual address for download is 0x%x\n", (int)StartP);
+		rio_dprintk (RIO_DEBUG_BOOT, "host loadbase is 0x%x\n",p->RIOConf.HostLoadBase);
+		rio_dprintk (RIO_DEBUG_BOOT, "size of download is 0x%x\n", rbp->Count);
 
 		if ( p->RIOConf.HostLoadBase < rbp->Count ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("Bin too large\n"));
+			rio_dprintk (RIO_DEBUG_BOOT, "Bin too large\n");
 			p->RIOError.Error = HOST_FILE_TOO_LARGE;
 			func_exit ();
 			return EFBIG;
@@ -307,7 +307,7 @@
 		** This ain't going to be none too clever if the download
 		** code is bigger than this segment.
 		*/
-		rio_dprint(RIO_DEBUG_BOOT, ("Copy in code\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Copy in code\n");
 
 		/*
 		** PCI hostcard can't cope with 32 bit accesses and so need to copy 
@@ -318,7 +318,7 @@
 
 			DownCode = sysbrk(rbp->Count);
 			if ( !DownCode ) {
-				rio_dprint(RIO_DEBUG_BOOT, ("No system memory available\n"));
+				rio_dprintk (RIO_DEBUG_BOOT, "No system memory available\n");
 				p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY;
 				func_exit ();
 				return ENOMEM;
@@ -326,7 +326,7 @@
 			bzero(DownCode, rbp->Count);
 
 			if ( copyin((int)rbp->DataP,DownCode,rbp->Count)==COPYFAIL ) {
-				rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n"));
+				rio_dprintk (RIO_DEBUG_BOOT, "Bad copyin of host data\n");
 				p->RIOError.Error = COPYIN_FAILED;
 				func_exit ();
 				return EFAULT;
@@ -337,13 +337,13 @@
 			sysfree( DownCode, rbp->Count );
 		}
 		else if ( copyin((int)rbp->DataP,StartP,rbp->Count)==COPYFAIL ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n"));
+			rio_dprintk (RIO_DEBUG_BOOT, "Bad copyin of host data\n");
 			p->RIOError.Error = COPYIN_FAILED;
 			func_exit ();
 			return EFAULT;
 		}
 
-		rio_dprint(RIO_DEBUG_BOOT, ("Copy completed\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Copy completed\n");
 
 		/*
 		**			S T O P !
@@ -444,8 +444,8 @@
 		WBYTE( DestP[6] , NFIX(0) );
 		WBYTE( DestP[7] , JUMP(8) );
 
-		rio_dprint(RIO_DEBUG_BOOT, ("host loadbase is 0x%x\n",p->RIOConf.HostLoadBase));
-		rio_dprint(RIO_DEBUG_BOOT, ("startup offset is 0x%x\n",offset));
+		rio_dprintk (RIO_DEBUG_BOOT, "host loadbase is 0x%x\n",p->RIOConf.HostLoadBase);
+		rio_dprintk (RIO_DEBUG_BOOT, "startup offset is 0x%x\n",offset);
 
 		/*
 		** Flag what is going on
@@ -459,19 +459,19 @@
 		*/
 		OldParmMap = RWORD(HostP->__ParmMapR);
 
-		rio_dprint(RIO_DEBUG_BOOT, ("Original parmmap is 0x%x\n",OldParmMap));
+		rio_dprintk (RIO_DEBUG_BOOT, "Original parmmap is 0x%x\n",OldParmMap);
 
 		/*
 		** And start it running (I hope).
 		** As there is nothing dodgy or obscure about the
 		** above code, this is guaranteed to work every time.
 		*/
-		rio_dprint(RIO_DEBUG_BOOT,  ("Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
-		    HostP->Type, HostP->Mode, HostP->Ivec ) );
+		rio_dprintk (RIO_DEBUG_BOOT,  "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
+		    HostP->Type, HostP->Mode, HostP->Ivec);
 
 		rio_start_card_running(HostP);
 
-		rio_dprint(RIO_DEBUG_BOOT, ("Set control port\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Set control port\n");
 
 		/*
 		** Now, wait for upto five seconds for the Tp to setup the parmmap
@@ -479,7 +479,7 @@
 		*/
 		for ( wait_count=0; (wait_count<p->RIOConf.StartupTime)&&
 			(RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR)));
+			rio_dprintk (RIO_DEBUG_BOOT, "Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR));
 			delay(HostP, HUNDRED_MS);
 
 		}
@@ -489,8 +489,8 @@
 		** has crashed & burned in a really spectacular way
 		*/
 		if ( RWORD(HostP->__ParmMapR) == OldParmMap ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("parmmap 0x%x\n", RWORD(HostP->__ParmMapR)));
-			rio_dprint(RIO_DEBUG_BOOT, ("RIO Mesg Run Fail\n"));
+			rio_dprintk (RIO_DEBUG_BOOT, "parmmap 0x%x\n", RWORD(HostP->__ParmMapR));
+			rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n");
 
 #define	HOST_DISABLE \
 		HostP->Flags &= ~RUN_STATE; \
@@ -501,7 +501,7 @@
 			HOST_DISABLE;
 		}
 
-		rio_dprint(RIO_DEBUG_BOOT, ("Running 0x%x\n",RWORD(HostP->__ParmMapR)));
+		rio_dprintk (RIO_DEBUG_BOOT, "Running 0x%x\n", RWORD(HostP->__ParmMapR));
 
 		/*
 		** Well, the board thought it was OK, and setup its parmmap
@@ -513,10 +513,10 @@
 		** Grab a 32 bit pointer to the parmmap structure
 		*/
 		ParmMapP = (PARM_MAP *)RIO_PTR(Cad,RWORD(HostP->__ParmMapR));
-		rio_dprint(RIO_DEBUG_BOOT, ("ParmMapP : %x\n", (int)ParmMapP));
+		rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP);
 		ParmMapP = (PARM_MAP *)((unsigned long)Cad + 
 						(unsigned long)((RWORD((HostP->__ParmMapR))) & 0xFFFF)); 
-		rio_dprint(RIO_DEBUG_BOOT, ("ParmMapP : %x\n", (int)ParmMapP));
+		rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP);
 
 		/*
 		** The links entry should be 0xFFFF; we set it up
@@ -524,8 +524,8 @@
 		** which links to use.
 		*/
 		if ( (RWORD(ParmMapP->links) & 0xFFFF) != 0xFFFF ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("RIO Mesg Run Fail %s\n", HostP->Name));
-			rio_dprint(RIO_DEBUG_BOOT, ("Links = 0x%x\n",RWORD(ParmMapP->links)));
+			rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name);
+			rio_dprintk (RIO_DEBUG_BOOT, "Links = 0x%x\n",RWORD(ParmMapP->links));
 			HOST_DISABLE;
 		}
 
@@ -535,28 +535,28 @@
 		** now wait for the card to set all the parmmap->XXX stuff
 		** this is a wait of upto two seconds....
 		*/
-		rio_dprint(RIO_DEBUG_BOOT, ("Looking for init_done - %d ticks\n",p->RIOConf.StartupTime));
+		rio_dprintk (RIO_DEBUG_BOOT, "Looking for init_done - %d ticks\n",p->RIOConf.StartupTime);
 		HostP->timeout_id = 0;
 		for ( wait_count=0; (wait_count<p->RIOConf.StartupTime) && 
 						!RWORD(ParmMapP->init_done); wait_count++ ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("Waiting for init_done\n"));
+			rio_dprintk (RIO_DEBUG_BOOT, "Waiting for init_done\n");
 			delay(HostP, HUNDRED_MS);
 		}
-		rio_dprint(RIO_DEBUG_BOOT, ("OK! init_done!\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "OK! init_done!\n");
 
 		if (RWORD(ParmMapP->error) != E_NO_ERROR || 
 							!RWORD(ParmMapP->init_done) ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("RIO Mesg Run Fail %s\n", HostP->Name));
-			rio_dprint(RIO_DEBUG_BOOT, ("Timedout waiting for init_done\n"));
+			rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name);
+			rio_dprintk (RIO_DEBUG_BOOT, "Timedout waiting for init_done\n");
 			HOST_DISABLE;
 		}
 
-		rio_dprint(RIO_DEBUG_BOOT, ("Got init_done\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Got init_done\n");
 
 		/*
 		** It runs! It runs!
 		*/
-		rio_dprint(RIO_DEBUG_BOOT, ("Host ID %x Running\n",HostP->UniqueNum));
+		rio_dprintk (RIO_DEBUG_BOOT, "Host ID %x Running\n",HostP->UniqueNum);
 
 		/*
 		** set the time period between interrupts.
@@ -580,12 +580,14 @@
 			HostP->UnixRups[RupN].RupP		= &HostP->RupP[RupN];
 			HostP->UnixRups[RupN].Id		  = RupN+1;
 			HostP->UnixRups[RupN].BaseSysPort = NO_PORT;
+			HostP->UnixRups[RupN].RupLock = SPIN_LOCK_UNLOCKED;
 		}
 
 		for ( RupN = 0; RupN<LINKS_PER_UNIT; RupN++ ) {
 			HostP->UnixRups[RupN+MAX_RUP].RupP	= &HostP->LinkStrP[RupN].rup;
 			HostP->UnixRups[RupN+MAX_RUP].Id  = 0;
 			HostP->UnixRups[RupN+MAX_RUP].BaseSysPort = NO_PORT;
+			HostP->UnixRups[RupN+MAX_RUP].RupLock = SPIN_LOCK_UNLOCKED;
 		}
 
 		/*
@@ -622,7 +624,7 @@
 			}
 		}
 
-		rio_dprint(RIO_DEBUG_BOOT, ("Set the card running... \n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Set the card running... \n");
 		/*
 		** last thing - show the world that everything is in place
 		*/
@@ -638,7 +640,7 @@
 
 	p->RIOSystemUp++;
 	
-	rio_dprint(RIO_DEBUG_BOOT, ("Done everything %x\n", HostP->Ivec));
+	rio_dprintk (RIO_DEBUG_BOOT, "Done everything %x\n", HostP->Ivec);
 	func_exit ();
 	return 0;
 }
@@ -672,7 +674,7 @@
 	** If we haven't been told what to boot, we can't boot it.
 	*/
 	if ( p->RIONumBootPkts == 0 ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("No RTA code to download yet\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "No RTA code to download yet\n");
 		return 0;
 	}
 
@@ -693,7 +695,7 @@
 	** try to unhook a command block from the command free list.
 	*/
 	if ( !(CmdBlkP = RIOGetCmdBlk()) ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("No command blocks to boot RTA! come back later.\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "No command blocks to boot RTA! come back later.\n");
 		return 0;
 	}
 
@@ -716,8 +718,8 @@
 		** We only expect one type of command - a BOOT_REQUEST!
 		*/
 		if ( RBYTE(PktCmdP->Command) != BOOT_REQUEST ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("Unexpected command %d on BOOT RUP %d of host %d\n", 
-						PktCmdP->Command,Rup,HostP-p->RIOHosts));
+			rio_dprintk (RIO_DEBUG_BOOT, "Unexpected command %d on BOOT RUP %d of host %d\n", 
+						PktCmdP->Command,Rup,HostP-p->RIOHosts);
 			ShowPacket( DBG_BOOT, PacketP );
 			RIOFreeCmdBlk( CmdBlkP );
 			return 1;
@@ -754,9 +756,9 @@
 
 		bcopy("BOOT",(void *)&CmdBlkP->Packet.data[BOOT_SEQUENCE_LEN],4);
 
-		rio_dprint(RIO_DEBUG_BOOT, ("Boot RTA on Host %d Rup %d - %d (0x%x) packets to 0x%x\n",
+		rio_dprintk (RIO_DEBUG_BOOT, "Boot RTA on Host %d Rup %d - %d (0x%x) packets to 0x%x\n",
 			HostP-p->RIOHosts, Rup, p->RIONumBootPkts, p->RIONumBootPkts, 
-								p->RIOConf.RtaLoadBase));
+								p->RIOConf.RtaLoadBase);
 
 		/*
 		** If this host is in slave mode, send the RTA an invalid boot
@@ -775,11 +777,11 @@
 	*/
 	sequence = RWORD(PktCmdP->Sequence);
 
-	rio_dprint(RIO_DEBUG_BOOT, ("Boot block %d on Host %d Rup%d\n",sequence,HostP-p->RIOHosts,Rup));
+	rio_dprintk (RIO_DEBUG_BOOT, "Boot block %d on Host %d Rup%d\n",sequence,HostP-p->RIOHosts,Rup);
 
 	if ( sequence >= p->RIONumBootPkts ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("Got a request for packet %d, max is %d\n", sequence, 
-					p->RIONumBootPkts));
+		rio_dprintk (RIO_DEBUG_BOOT, "Got a request for packet %d, max is %d\n", sequence, 
+					p->RIONumBootPkts);
 		ShowPacket( DBG_BOOT, PacketP );
 	}
 
@@ -821,26 +823,26 @@
 	   driver will never think that the RTA has booted... -- REW */
 	p->RIOBooting = 0;
 
-	rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot completed - BootInProgress now %d\n", p->RIOBooting));
+	rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot completed - BootInProgress now %d\n", p->RIOBooting);
 
 	/*
 	** Determine type of unit (16/8 port RTA).
 	*/
 	RtaType = GetUnitType(RtaUniq);
         if ( Rup >= (ushort)MAX_RUP ) {
-	    rio_dprint(RIO_DEBUG_BOOT, ("RIO: Host %s has booted an RTA(%d) on link %c\n",
-	     HostP->Name, 8 * RtaType, RBYTE(PktCmdP->LinkNum)+'A' ));
+	    rio_dprintk (RIO_DEBUG_BOOT, "RIO: Host %s has booted an RTA(%d) on link %c\n",
+	     HostP->Name, 8 * RtaType, RBYTE(PktCmdP->LinkNum)+'A');
 	} else {
-	    rio_dprint(RIO_DEBUG_BOOT, ("RIO: RTA %s has booted an RTA(%d) on link %c\n",
+	    rio_dprintk (RIO_DEBUG_BOOT, "RIO: RTA %s has booted an RTA(%d) on link %c\n",
 	     HostP->Mapping[Rup].Name, 8 * RtaType,
-	     RBYTE(PktCmdP->LinkNum)+'A'));
+	     RBYTE(PktCmdP->LinkNum)+'A');
 	}
 
-	rio_dprint(RIO_DEBUG_BOOT, ("UniqNum is 0x%x\n",RtaUniq));
+	rio_dprintk (RIO_DEBUG_BOOT, "UniqNum is 0x%x\n",RtaUniq);
 
         if ( ( RtaUniq == 0x00000000 ) || ( RtaUniq == 0xffffffff ) )
 	{
-	    rio_dprint(RIO_DEBUG_BOOT, ( "Illegal RTA Uniq Number\n"));
+	    rio_dprintk (RIO_DEBUG_BOOT, "Illegal RTA Uniq Number\n");
 	    return TRUE;
 	}
 
@@ -861,8 +863,8 @@
 		*/
 		if (RIOSuspendBootRta(HostP, HostP->Mapping[Rup].ID, MyLink))
 		{
-		    rio_dprint(RIO_DEBUG_BOOT, ("RTA failed to suspend booting on link %c\n",
-		     'A' + MyLink));
+		    rio_dprintk (RIO_DEBUG_BOOT, "RTA failed to suspend booting on link %c\n",
+		     'A' + MyLink);
 		}
 	    }
 	    else
@@ -874,8 +876,8 @@
 		*/
 		WWORD(HostP->LinkStrP[MyLink].WaitNoBoot, 30);
 	    }
-	    rio_dprint(RIO_DEBUG_BOOT, ("RTA %x not owned - suspend booting down link %c on unit %x\n",
-	      RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum));
+	    rio_dprintk (RIO_DEBUG_BOOT, "RTA %x not owned - suspend booting down link %c on unit %x\n",
+	      RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum);
 	    return TRUE;
 	}
 
@@ -925,16 +927,16 @@
 		   }
 		}
 		if (RtaType == TYPE_RTA16) {
-		   rio_dprint(RIO_DEBUG_BOOT, ("RTA will be given IDs %d+%d\n",
-		    entry+1, entry2+1));
+		   rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given IDs %d+%d\n",
+		    entry+1, entry2+1);
 		} else {
-		   rio_dprint(RIO_DEBUG_BOOT, ("RTA will be given ID %d\n",entry+1));
+		   rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given ID %d\n",entry+1);
 		}
 		return TRUE;
 	    }
 	}
 
-	rio_dprint(RIO_DEBUG_BOOT, ("RTA not configured for this host\n"));
+	rio_dprintk (RIO_DEBUG_BOOT, "RTA not configured for this host\n");
 
 	if ( Rup >= (ushort)MAX_RUP )
 	{
@@ -978,13 +980,13 @@
 		    entry2 = HostP->Mapping[entry].ID2 - 1;
 		    if ( (HostP->Mapping[entry2].Flags & SLOT_TENTATIVE) &&
 			 (HostP->Mapping[entry2].RtaUniqueNum == RtaUniq) )
-			rio_dprint(RIO_DEBUG_BOOT, ("Found previous tentative slots (%d+%d)\n",
-			 entry, entry2));
+			rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slots (%d+%d)\n",
+			 entry, entry2);
 		    else
 			continue;
 		}
 		else
-			rio_dprint(RIO_DEBUG_BOOT, ("Found previous tentative slot (%d)\n",entry));
+			rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slot (%d)\n",entry);
 		if (! p->RIONoMessage)
 		    cprintf("RTA connected to %s '%s' (%c) not configured.\n",MyType,MyName,MyLink+'A');
 		return TRUE;
@@ -1013,7 +1015,7 @@
 	** + Configure RTA on host A. We now have the same RTA configured
 	**   with different ports on two different hosts.
 	*/
-	rio_dprint(RIO_DEBUG_BOOT, ("Have we seen RTA %x before?\n", RtaUniq ));
+	rio_dprintk (RIO_DEBUG_BOOT, "Have we seen RTA %x before?\n", RtaUniq );
 	found = 0;
 	Flag = 0; /* Convince the compiler this variable is initialized */
 	for ( host = 0; !found && (host < p->RIONumHosts); host++ )
@@ -1029,12 +1031,12 @@
 		    if (RtaType == TYPE_RTA16)
 		    {
 			MapP2 = &p->RIOHosts[host].Mapping[MapP->ID2 - 1];
-			rio_dprint(RIO_DEBUG_BOOT, ("This RTA is units %d+%d from host %s\n",
-			 rta+1, MapP->ID2, p->RIOHosts[host].Name ));
+			rio_dprintk (RIO_DEBUG_BOOT, "This RTA is units %d+%d from host %s\n",
+			 rta+1, MapP->ID2, p->RIOHosts[host].Name);
 		    }
 		    else
-			rio_dprint(RIO_DEBUG_BOOT, ("This RTA is unit %d from host %s\n",
-			 rta+1, p->RIOHosts[host].Name ));
+			rio_dprintk (RIO_DEBUG_BOOT, "This RTA is unit %d from host %s\n",
+			 rta+1, p->RIOHosts[host].Name);
 		    found = 1;
 		    break;
 		}
@@ -1052,12 +1054,12 @@
 	*/
 	if ( !MapP )
 	{
-	    rio_dprint(RIO_DEBUG_BOOT, ("Look for RTA %x in RIOSavedTable\n",RtaUniq));
+	    rio_dprintk (RIO_DEBUG_BOOT, "Look for RTA %x in RIOSavedTable\n",RtaUniq);
 	    for ( rta=0; rta < TOTAL_MAP_ENTRIES; rta++ )
 	    {
-		rio_dprint(RIO_DEBUG_BOOT, ("Check table entry %d (%x)",
+		rio_dprintk (RIO_DEBUG_BOOT, "Check table entry %d (%x)",
 		      rta,
-		      p->RIOSavedTable[rta].RtaUniqueNum ));
+		      p->RIOSavedTable[rta].RtaUniqueNum);
 
 		if ( (p->RIOSavedTable[rta].Flags & SLOT_IN_USE) &&
 		 (p->RIOSavedTable[rta].RtaUniqueNum == RtaUniq) )
@@ -1073,11 +1075,11 @@
                                 break;
                         }
                         MapP2 = &p->RIOSavedTable[entry2];
-                        rio_dprint(RIO_DEBUG_BOOT, ("This RTA is from table entries %d+%d\n",
-                              rta, entry2));
+                        rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entries %d+%d\n",
+                              rta, entry2);
 		    }
 		    else
-			rio_dprint(RIO_DEBUG_BOOT, ("This RTA is from table entry %d\n", rta));
+			rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entry %d\n", rta);
 		    break;
 		}
 	    }
@@ -1133,8 +1135,8 @@
 	    {
 		if (Flag & SLOT_IN_USE)
 		{
-		    rio_dprint(RIO_DEBUG_BOOT, (
-    "This RTA configured on another host - move entry to current host (1)\n"));
+		    rio_dprintk (RIO_DEBUG_BOOT, 
+    "This RTA configured on another host - move entry to current host (1)\n");
 		    HostP->Mapping[entry].SysPort = MapP->SysPort;
 		    CCOPY( MapP->Name, HostP->Mapping[entry].Name, MAX_NAME_LEN );
 		    HostP->Mapping[entry].Flags =
@@ -1147,12 +1149,12 @@
 			p->RIOFirstPortsBooted = HostP->Mapping[entry].SysPort;
 		    if ( HostP->Mapping[entry].SysPort > p->RIOLastPortsBooted )
 			p->RIOLastPortsBooted = HostP->Mapping[entry].SysPort;
-		    rio_dprint(RIO_DEBUG_BOOT, ("SysPort %d, Name %s\n",(int)MapP->SysPort,MapP->Name));
+		    rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n",(int)MapP->SysPort,MapP->Name);
 		}
 		else
 		{
-		    rio_dprint(RIO_DEBUG_BOOT, (
-   "This RTA has a tentative entry on another host - delete that entry (1)\n"));
+		    rio_dprintk (RIO_DEBUG_BOOT, 
+   "This RTA has a tentative entry on another host - delete that entry (1)\n");
 		    HostP->Mapping[entry].Flags =
 		     SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT;
 #if NEED_TO_FIX
@@ -1177,9 +1179,9 @@
 			 p->RIOFirstPortsBooted = HostP->Mapping[entry2].SysPort;
 		       if (HostP->Mapping[entry2].SysPort > p->RIOLastPortsBooted)
 			 p->RIOLastPortsBooted = HostP->Mapping[entry2].SysPort;
-			rio_dprint(RIO_DEBUG_BOOT, ("SysPort %d, Name %s\n",
+			rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n",
 			       (int)HostP->Mapping[entry2].SysPort,
-			       HostP->Mapping[entry].Name));
+			       HostP->Mapping[entry].Name);
 		    }
 		    else
 			HostP->Mapping[entry2].Flags = SLOT_TENTATIVE |
@@ -1272,7 +1274,7 @@
 {
 	int		link;
 
-	rio_dprint(RIO_DEBUG_BOOT, ("FillSlot(%d, %d, 0x%x...)\n", entry, entry2, RtaUniq));
+	rio_dprintk (RIO_DEBUG_BOOT, "FillSlot(%d, %d, 0x%x...)\n", entry, entry2, RtaUniq);
 
 	HostP->Mapping[entry].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE);
 	HostP->Mapping[entry].SysPort = NO_PORT;
diff -urN linux-2.2.17-pre15/drivers/char/rio/riocmd.c linux/drivers/char/rio/riocmd.c
--- linux-2.2.17-pre15/drivers/char/rio/riocmd.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/char/rio/riocmd.c	Mon Dec  3 22:10:50 2001
@@ -91,12 +91,12 @@
 {
 	struct CmdBlk *CmdBlkP;
 
-	rio_dprint(RIO_DEBUG_CMD, ("FOAD RTA\n"));
+	rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA\n");
 
 	CmdBlkP = RIOGetCmdBlk();
 
 	if ( !CmdBlkP ) {
-		rio_dprint(RIO_DEBUG_CMD, ("FOAD RTA: GetCmdBlk failed\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failed\n");
 		return ENXIO;
 	}
 
@@ -111,7 +111,7 @@
 	CmdBlkP->Packet.data[3]   = (IFOAD_MAGIC >> 8) & 0xFF;
 
 	if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
-		rio_dprint(RIO_DEBUG_CMD, ("FOAD RTA: Failed to queue foad command\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad command\n");
 		return EIO;
 	}
 	return 0;
@@ -124,12 +124,12 @@
 {
 	struct CmdBlk *CmdBlkP;
 
-	rio_dprint(RIO_DEBUG_CMD, ("ZOMBIE RTA\n"));
+	rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA\n");
 
 	CmdBlkP = RIOGetCmdBlk();
 
 	if ( !CmdBlkP ) {
-		rio_dprint(RIO_DEBUG_CMD, ("ZOMBIE RTA: GetCmdBlk failed\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failed\n");
 		return ENXIO;
 	}
 
@@ -144,7 +144,7 @@
 	CmdBlkP->Packet.data[3]   = (ZOMBIE_MAGIC >> 8) & 0xFF;
 
 	if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
-		rio_dprint(RIO_DEBUG_CMD, ("ZOMBIE RTA: Failed to queue zombie command\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie command\n");
 		return EIO;
 	}
 	return 0;
@@ -158,7 +158,7 @@
 {
 	uint Host;
 
-	rio_dprint(RIO_DEBUG_CMD, ("Command RTA 0x%x func 0x%x\n", RtaUnique, (int)func ));
+	rio_dprintk (RIO_DEBUG_CMD, "Command RTA 0x%x func 0x%x\n", RtaUnique, (int)func);
 
 	if ( !RtaUnique )
 		return(0);
@@ -203,7 +203,7 @@
 	uint Host;
 
 	if ( copyin( (int)arg, (caddr_t)&IdRta, sizeof(IdRta) ) == COPYFAIL ) {
-		rio_dprint(RIO_DEBUG_CMD, ("RIO_IDENTIFY_RTA copy failed\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failed\n");
 		p->RIOError.Error = COPYIN_FAILED;
 		return EFAULT;
 	}
@@ -231,12 +231,12 @@
 						*/
 						struct CmdBlk *CmdBlkP;
 
-						rio_dprint(RIO_DEBUG_CMD, ("IDENTIFY RTA\n"));
+						rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA\n");
 
 						CmdBlkP = RIOGetCmdBlk();
 
 						if ( !CmdBlkP ) {
-							rio_dprint(RIO_DEBUG_CMD, ("IDENTIFY RTA: GetCmdBlk failed\n"));
+							rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failed\n");
 							return ENXIO;
 						}
 		
@@ -249,9 +249,8 @@
 						CmdBlkP->Packet.data[1]   = 0;
 						CmdBlkP->Packet.data[2]   = IdRta.ID;
 		
-						if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) 
-										== RIO_FAIL ) {
-							rio_dprint(RIO_DEBUG_CMD, ("IDENTIFY RTA: Failed to queue command\n"));
+						if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
+							rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue command\n");
 							return EIO;
 						}
 						return 0;
@@ -274,11 +273,10 @@
 	struct Host *HostP;
 	struct CmdBlk *CmdBlkP;
 
-	rio_dprint(RIO_DEBUG_CMD, ("KILL HOST NEIGHBOUR\n"));
+	rio_dprintk (RIO_DEBUG_CMD, "KILL HOST NEIGHBOUR\n");
 
-	if ( copyin( (int)arg, (caddr_t)&KillUnit, 
-					sizeof(KillUnit) ) == COPYFAIL ) {
-		rio_dprint(RIO_DEBUG_CMD, ("RIO_KILL_NEIGHBOUR copy failed\n"));
+	if ( copyin( (int)arg, (caddr_t)&KillUnit, sizeof(KillUnit) ) == COPYFAIL ) {
+		rio_dprintk (RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failed\n");
 		p->RIOError.Error = COPYIN_FAILED;
 		return EFAULT;
 	}
@@ -289,7 +287,7 @@
 	CmdBlkP = RIOGetCmdBlk();
 
 	if ( !CmdBlkP ) {
-		rio_dprint(RIO_DEBUG_CMD, ("UFOAD: GetCmdBlk failed\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failed\n");
 		return ENXIO;
 	}
 
@@ -310,7 +308,7 @@
 		if ( HostP->UniqueNum == KillUnit.UniqueNum ) {
 			if ( RIOQueueCmdBlk( HostP, RTAS_PER_HOST+KillUnit.Link,
 							CmdBlkP) == RIO_FAIL ) {
-				rio_dprint(RIO_DEBUG_CMD, ("UFOAD: Failed queue command\n"));
+				rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
 				return EIO;
 			}
 			return 0;
@@ -320,7 +318,7 @@
 			if ( HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum ) {
 				CmdBlkP->Packet.dest_unit = ID+1;
 				if ( RIOQueueCmdBlk( HostP, ID, CmdBlkP) == RIO_FAIL ) {
-					rio_dprint(RIO_DEBUG_CMD, ("UFOAD: Failed queue command\n"));
+					rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
 					return EIO;
 				}
 				return 0;
@@ -339,12 +337,12 @@
 {
 	struct CmdBlk *CmdBlkP;
 
-	rio_dprint(RIO_DEBUG_CMD, ("SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link));
+	rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link);
 
 	CmdBlkP = RIOGetCmdBlk();
 
 	if ( !CmdBlkP ) {
-		rio_dprint(RIO_DEBUG_CMD, ("SUSPEND BOOT ON RTA: GetCmdBlk failed\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failed\n");
 		return ENXIO;
 	}
 
@@ -359,7 +357,7 @@
 	CmdBlkP->Packet.data[3]   = (IWAIT_MAGIC >> 8) & 0xFF;
 
 	if ( RIOQueueCmdBlk( HostP, ID - 1, CmdBlkP) == RIO_FAIL ) {
-		rio_dprint(RIO_DEBUG_CMD, ("SUSPEND BOOT ON RTA: Failed to queue iwait command\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait command\n");
 		return EIO;
 	}
 	return 0;
@@ -416,6 +414,7 @@
 	ushort subCommand;
 	unsigned long flags;
 
+	func_enter ();
 
 #ifdef CHECK
 	CheckHost( Host );
@@ -435,34 +434,35 @@
 	UnixRupP = &HostP->UnixRups[rup];
 	SysPort = UnixRupP->BaseSysPort + 
 			(RBYTE(PktCmdP->PhbNum) % (ushort)PORTS_PER_RTA);
-	rio_dprint(RIO_DEBUG_CMD, ("Command on rup %d, port %d\n", rup, SysPort));
+	rio_dprintk (RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort);
 
 #ifdef CHECK
 	CheckRup( rup );
 	CheckUnixRupP( UnixRupP );
 #endif
 	if ( UnixRupP->BaseSysPort == NO_PORT ) {
-		rio_dprint(RIO_DEBUG_CMD, ("OBSCURE ERROR!\n"));
-		rio_dprint(RIO_DEBUG_CMD, ("Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n"));
-		rio_dprint(RIO_DEBUG_CMD, ("CONTROL information: Host number %d, name ``%s''\n", 
-					HostP-p->RIOHosts, HostP->Name ));
-		rio_dprint(RIO_DEBUG_CMD, ("CONTROL information: Rup number  0x%x\n", rup));
-
-		if ( Rup >= (ushort)MAX_RUP )
-			rio_dprint(RIO_DEBUG_CMD, ("CONTROL information: This is the RUP for RTA ``%s''\n",
-						HostP->Mapping[Rup].Name ));
-		else
-			rio_dprint(RIO_DEBUG_CMD, ("CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", 'A' + Rup - MAX_RUP, HostP->Name ));
-
-		rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Destination 0x%x:0x%x\n",
-					PacketP->dest_unit, PacketP->dest_port ));
-		rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Source	  0x%x:0x%x\n",
-					PacketP->src_unit, PacketP->src_port ));
-		rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Length	  0x%x (%d)\n", PacketP->len,PacketP->len ));
-		rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Control	 0x%x (%d)\n", PacketP->control, PacketP->control));
-		rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Check	   0x%x (%d)\n", PacketP->csum, PacketP->csum ));
-		rio_dprint(RIO_DEBUG_CMD, ("COMMAND information: Host Port Number 0x%x, 
-					Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command ));
+		rio_dprintk (RIO_DEBUG_CMD, "OBSCURE ERROR!\n");
+		rio_dprintk (RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n");
+		rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Host number %d, name ``%s''\n", 
+			     HostP-p->RIOHosts, HostP->Name );
+		rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Rup number  0x%x\n", rup);
+
+		if ( Rup >= (ushort)MAX_RUP ) {
+			rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n",
+				     HostP->Mapping[Rup].Name);
+		} else
+			rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", 
+				     ('A' + Rup - MAX_RUP), HostP->Name);
+
+		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n",
+			     PacketP->dest_unit, PacketP->dest_port );
+		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Source	  0x%x:0x%x\n",
+			     PacketP->src_unit, PacketP->src_port );
+		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Length	  0x%x (%d)\n", PacketP->len,PacketP->len );
+		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Control	 0x%x (%d)\n", PacketP->control, PacketP->control);
+		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Check	   0x%x (%d)\n", PacketP->csum, PacketP->csum );
+		rio_dprintk (RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, 
+					Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command );
 		return TRUE;
 	}
 
@@ -470,13 +470,10 @@
 	CheckSysPort( SysPort );
 #endif
 	PortP = p->RIOPortp[ SysPort ];
-#if 0
-	ttyP = PortP->TtyP;
-#endif
 	rio_spin_lock_irqsave(&PortP->portSem, flags);
 	switch( RBYTE(PktCmdP->Command) ) {
 		case BREAK_RECEIVED:
-			rio_dprint(RIO_DEBUG_CMD, ("Received a break!\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "Received a break!\n");
 			/* If the current line disc. is not multi-threading and
 	   			the current processor is not the default, reset rup_intr
 	   			and return FALSE to ensure that the command packet is
@@ -486,16 +483,16 @@
 			break;
 
 		case COMPLETE:
-			rio_dprint(RIO_DEBUG_CMD, ("Command complete on phb %d host %d\n",
-							RBYTE(PktCmdP->PhbNum), HostP-p->RIOHosts));
+		rio_dprintk (RIO_DEBUG_CMD, "Command complete on phb %d host %d\n",
+			     RBYTE(PktCmdP->PhbNum), HostP-p->RIOHosts);
 			subCommand = 1;
 			switch (RBYTE(PktCmdP->SubCommand)) {
 				case MEMDUMP :
-					rio_dprint(RIO_DEBUG_CMD, ("Memory dump cmd (0x%x) from addr 0x%x\n",
-		 				RBYTE(PktCmdP->SubCommand), RWORD(PktCmdP->SubAddr)));
+			rio_dprintk (RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n",
+				     RBYTE(PktCmdP->SubCommand), RWORD(PktCmdP->SubAddr));
 					break;
 				case READ_REGISTER :
-					rio_dprint(RIO_DEBUG_CMD, ("Read register (0x%x)\n", RWORD(PktCmdP->SubAddr)));
+			rio_dprintk (RIO_DEBUG_CMD, "Read register (0x%x)\n", RWORD(PktCmdP->SubAddr));
 					p->CdRegister = (RBYTE(PktCmdP->ModemStatus) & MSVR1_HOST);
 					break;
 				default :
@@ -504,18 +501,16 @@
 			}
 			if (subCommand)
 				break;
-			rio_dprint(RIO_DEBUG_CMD, ("New status is 0x%x was 0x%x\n",
-					 RBYTE(PktCmdP->PortStatus),PortP->PortState));
+			rio_dprintk (RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n",
+				     RBYTE(PktCmdP->PortStatus),PortP->PortState);
 			if (PortP->PortState != RBYTE(PktCmdP->PortStatus)) {
-				rio_dprint(RIO_DEBUG_CMD, ("Mark status & wakeup\n"));
+				rio_dprintk (RIO_DEBUG_CMD, "Mark status & wakeup\n");
 				PortP->PortState = RBYTE(PktCmdP->PortStatus);
 				/* What should we do here ...
 				wakeup( &PortP->PortState );
 				*/
-			}
-			else {
-				rio_dprint(RIO_DEBUG_CMD, ("No change\n"));
-			}
+		} else 
+			rio_dprintk (RIO_DEBUG_CMD, "No change\n");
 
 			/* FALLTHROUGH */
 		case MODEM_STATUS:
@@ -527,7 +522,7 @@
 			ReportedModemStatus = RBYTE(PktCmdP->ModemStatus);
 			if ((PortP->ModemState & MSVR1_HOST) ==
 					(ReportedModemStatus & MSVR1_HOST)) {
-				rio_dprint(RIO_DEBUG_CMD, ("Modem status unchanged 0x%x\n", PortP->ModemState));
+				rio_dprintk (RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState);
 				/*
 				** Update ModemState just in case tbusy or tstop states have
 				** changed.
@@ -535,8 +530,8 @@
 				PortP->ModemState = ReportedModemStatus;
 			}
 			else {
-				rio_dprint(RIO_DEBUG_CMD, ("Modem status change from 0x%x to 0x%x\n",
-							 PortP->ModemState, ReportedModemStatus));
+				rio_dprintk (RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n",
+				     PortP->ModemState, ReportedModemStatus);
 				PortP->ModemState = ReportedModemStatus;
 #ifdef MODEM_SUPPORT
 				if ( PortP->Mapped ) {
@@ -551,50 +546,41 @@
 				** If the device is a modem, then check the modem
 				** carrier.
 				*/
-				if(!(ttyP->t_cflag & CLOCAL) && 
-					((PortP->State & (RIO_MOPEN|RIO_WOPEN))))
-				{
+				if (PortP->gs.tty == NULL)
+					break;
+			  
+				if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) &&
+				((PortP->State & (RIO_MOPEN|RIO_WOPEN)))) {
+
+					rio_dprintk (RIO_DEBUG_CMD, "Is there a Carrier?\n");
 			/*
 			** Is there a carrier?
 			*/
-			if ( PortP->ModemState & MSVR1_CD )
-			{
+					if ( PortP->ModemState & MSVR1_CD ) {
 			/*
 			** Has carrier just appeared?
 			*/
-			if (!(ttyP->t_state & CARR_ON))
-			{
-				rio_dprint(RIO_DEBUG_CMD, PortP,DBG_MODEM,"Carrier just came up.\n");
-				ttyP->t_state |=CARR_ON;
+						if (!(PortP->State & RIO_CARR_ON)) {
+							rio_dprintk (RIO_DEBUG_CMD, "Carrier just came up.\n");
+							PortP->State |= RIO_CARR_ON;
 				/*
 				** wakeup anyone in WOPEN
 				*/
-				if ( ttyP->t_state & (ISOPEN|WOPEN) )
-				wakeup((caddr_t)&ttyP->t_canq);
+							if (PortP->State & (PORT_ISOPEN | RIO_WOPEN) )
+								wake_up_interruptible (&PortP->gs.open_wait);
 #ifdef STATS
 				PortP->Stat.ModemOnCnt++;
 #endif
 			}
-			}
-			else
-			{
+					} else {
 			/*
 			** Has carrier just dropped?
 			*/
-			if (ttyP->t_state & CARR_ON)
-			{
-				/*
-				** send SIGHUP to the process group
-				*/
-				if ( ttyP->t_state & (ISOPEN|WOPEN) )
-				{
-				signal(ttyP->t_pgrp,SIGHUP);
-				ttyflush(ttyP,(FREAD|FWRITE));
-				}
-				ttyP->t_state &= ~CARR_ON;
-				wakeup( (caddr_t)&PortP->TxBufferOut );
-				wakeup( (caddr_t)&PortP->TxBufferIn );
-				rio_dprint(RIO_DEBUG_CMD, PortP,DBG_MODEM,"Carrier just went down.\n");
+						if (PortP->State & RIO_CARR_ON) {
+							if (PortP->State & (PORT_ISOPEN|RIO_WOPEN|RIO_MOPEN))
+								tty_hangup (PortP->gs.tty);
+							PortP->State &= ~RIO_CARR_ON;
+							rio_dprintk (RIO_DEBUG_CMD, "Carrirer just went down\n");
 #ifdef STATS
 				PortP->Stat.ModemOffCnt++;
 #endif
@@ -607,11 +593,14 @@
 			break;
 
 		default:
-			rio_dprint(RIO_DEBUG_CMD, ("Unknown command %d on CMD_RUP of host %d\n",
-				RBYTE(PktCmdP->Command),HostP-p->RIOHosts));
+			rio_dprintk (RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %d\n",
+			     RBYTE(PktCmdP->Command),HostP-p->RIOHosts);
 			break;
 	}
 	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
+
+	func_exit ();
+
 	return TRUE;
 }
 /*
@@ -667,11 +656,8 @@
 	CheckRup( Rup );
 	CheckCmdBlkP( CmdBlkP );
 #endif
-
-	rio_dprint(RIO_DEBUG_CMD, ("RIOQueueCmdBlk(Host, Rup %d, 0x%x)\n", Rup, (int)CmdBlkP ));
-
 	if ( Rup >= (ushort)(MAX_RUP+LINKS_PER_UNIT) ) {
-		rio_dprint(RIO_DEBUG_CMD, ("Illegal rup number %d in RIOQueueCmdBlk\n",Rup));
+		rio_dprintk (RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n",Rup);
 		RIOFreeCmdBlk( CmdBlkP );
 		return RIO_FAIL;
 	}
@@ -685,11 +671,12 @@
 	** straight on the RUP....
 	*/
 	if ( (UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) && 
-		(RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) &&
+	     (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE ) &&
 		(CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg,CmdBlkP)
 							:TRUE)) {
-		rio_dprint(RIO_DEBUG_CMD, ("RUP inactive-placing command straight on. Cmd byte is 0x%x\n",
-					CmdBlkP->Packet.data[0]));
+		rio_dprintk (RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n",
+					     CmdBlkP->Packet.data[0]);
+                                            
 
 		/*
 		** Whammy! blat that pack!
@@ -711,28 +698,27 @@
 
 		return RIO_SUCCESS;
 	}
-
-	rio_dprint(RIO_DEBUG_CMD, ("RUP active - en-queing\n"));
+	rio_dprintk (RIO_DEBUG_CMD, "RUP active - en-queing\n");
 
 	if ( UnixRupP->CmdsWaitingP != NULL)
-		rio_dprint(RIO_DEBUG_CMD, ("Rup active - command waiting\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command waiting\n");
 	if ( UnixRupP->CmdPendingP != NULL )
-		rio_dprint(RIO_DEBUG_CMD, ("Rup active - command pending\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command pending\n");
 	if ( RWORD(UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE )
-		rio_dprint(RIO_DEBUG_CMD, ("Rup active - command rup not ready\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command rup not ready\n");
 
 	Base = &UnixRupP->CmdsWaitingP;
 
-	rio_dprint(RIO_DEBUG_CMD, ("First try to queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base));
+	rio_dprintk (RIO_DEBUG_CMD, "First try to queue cmdblk 0x%x at 0x%x\n", (int)CmdBlkP,(int)Base);
 
 	while ( *Base ) {
-		rio_dprint(RIO_DEBUG_CMD, ("Command cmdblk 0x%x here\n",(int)(*Base)));
+		rio_dprintk (RIO_DEBUG_CMD, "Command cmdblk 0x%x here\n", (int)(*Base));
 		Base = &((*Base)->NextP);
-		rio_dprint(RIO_DEBUG_CMD, ("Now try to queue cmd cmdblk 0x%x at 0x%x\n",
-		       (int)CmdBlkP,(int)Base));
+		rio_dprintk (RIO_DEBUG_CMD, "Now try to queue cmd cmdblk 0x%x at 0x%x\n",
+					     (int)CmdBlkP,(int)Base);
 	}
 
-	rio_dprint(RIO_DEBUG_CMD, ("Will queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base));
+	rio_dprintk (RIO_DEBUG_CMD, "Will queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base);
 
 	*Base = CmdBlkP;
 
@@ -775,17 +761,15 @@
 		if ( RWORD(UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE ) {
 			int FreeMe;
 
-			/* rio_dprint(RIO_DEBUG_CMD, ("RIORupCmd( %d, %d )\n", HostP-p->RIOHosts, Rup )); */
-
 			PacketP =(PKT *)RIO_PTR(HostP->Caddr,RWORD(UnixRupP->RupP->rxpkt));
 
 			ShowPacket( DBG_CMD, PacketP );
 
 			switch ( RBYTE(PacketP->dest_port) ) {
 				case BOOT_RUP:
-					rio_dprint(RIO_DEBUG_CMD, ("Incoming Boot %s packet '%x'\n", 
+					rio_dprintk (RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n", 
 						RBYTE(PacketP->len) & 0x80 ? "Command":"Data", 
-						RBYTE(PacketP->data[0]) )); 
+							     RBYTE(PacketP->data[0])); 
 					rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
 					FreeMe= RIOBootRup(p, Rup,HostP,PacketP);
 					rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
@@ -800,8 +784,8 @@
 					rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
 					FreeMe= RIOCommandRup(p, Rup,HostP,PacketP);
 					if (PacketP->data[5] == MEMDUMP) {
-						rio_dprint(RIO_DEBUG_CMD, ("Memdump from 0x%x complete\n",
-			 				*(ushort *) &(PacketP->data[6])));
+						rio_dprintk (RIO_DEBUG_CMD, "Memdump from 0x%x complete\n",
+								     *(ushort *) &(PacketP->data[6]));
 						HostP->Copy( (caddr_t)&(PacketP->data[8]), 
 								(caddr_t)p->RIOMemDump, 32 );
 					}
@@ -815,19 +799,19 @@
 					break;
 
 				default:
-					rio_dprint(RIO_DEBUG_CMD, ("Unknown RUP %d\n", RBYTE(PacketP->dest_port)));
+					rio_dprintk (RIO_DEBUG_CMD, "Unknown RUP %d\n", RBYTE(PacketP->dest_port));
 					FreeMe = 1;
 					break;
 			}
 
 			if ( FreeMe ) {
-				rio_dprint(RIO_DEBUG_CMD, ("Free processed incoming command packet\n"));
+				rio_dprintk (RIO_DEBUG_CMD, "Free processed incoming command packet\n");
 				put_free_end(HostP,PacketP);
 
 				WWORD(UnixRupP->RupP->rxcontrol , RX_RUP_INACTIVE);
 
 				if ( RWORD(UnixRupP->RupP->handshake)==PHB_HANDSHAKE_SET ) {
-					rio_dprint(RIO_DEBUG_CMD, ("Handshake rup %d\n",Rup));
+					rio_dprintk (RIO_DEBUG_CMD, "Handshake rup %d\n",Rup);
 					WWORD(UnixRupP->RupP->handshake,
 						PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
 				}
@@ -839,7 +823,7 @@
 		** and it has completed, then tidy it up.
 		*/
 		if ( (CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */
-			(RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) ) {
+		     (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
 			/*
 			** we are idle.
 			** there is a command in pending.
@@ -848,11 +832,11 @@
 			** what happened).
 			*/
 			if ( CmdBlkP->Packet.dest_port == BOOT_RUP )
-				rio_dprint(RIO_DEBUG_CMD, ("Free Boot %s Command Block '%x'\n", 
+				rio_dprintk (RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'\n", 
 						CmdBlkP->Packet.len & 0x80 ? "Command":"Data", 
-							CmdBlkP->Packet.data[0] ));
+							     CmdBlkP->Packet.data[0]);
 
-			rio_dprint(RIO_DEBUG_CMD, ("Command 0x%x completed\n",(int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CMD, "Command 0x%x completed\n",(int)CmdBlkP);
 
 			/*
 			** Clear the Rup lock to prevent mutual exclusion.
@@ -880,27 +864,27 @@
 		*/
 		if ( (CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */
 			(UnixRupP->CmdPendingP == NULL) &&
-				(RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) ) {
+		     (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
 			/*
 			** if the pre-function is non-zero, call it.
 			** If it returns RIO_FAIL then don't
 			** send this command yet!
 			*/
 #ifdef CHECK
-CheckCmdBlkP( CmdBlkP );
+			CheckCmdBlkP (CmdBlkP);
 #endif
 			if ( !(CmdBlkP->PreFuncP ?
 				(*CmdBlkP->PreFuncP)(CmdBlkP->PreArg, CmdBlkP) : TRUE)) {
-				rio_dprint(RIO_DEBUG_CMD, ("Not ready to start command 0x%x\n",(int)CmdBlkP));
+				rio_dprintk (RIO_DEBUG_CMD, "Not ready to start command 0x%x\n",(int)CmdBlkP);
 			}
 			else {
-				rio_dprint(RIO_DEBUG_CMD, ("Start new command 0x%x Cmd byte is 0x%x\n",
-						(int)CmdBlkP, CmdBlkP->Packet.data[0]));
+				rio_dprintk (RIO_DEBUG_CMD, "Start new command 0x%x Cmd byte is 0x%x\n",
+							     (int)CmdBlkP, CmdBlkP->Packet.data[0]);
 				/*
 				** Whammy! blat that pack!
 				*/
 #ifdef CHECK
-CheckPacketP( (PKT *)RIO_PTR(HostP->Caddr,UnixRupP->RupP->txpkt) );
+				CheckPacketP ((PKT *)RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt));
 #endif
 				HostP->Copy( (caddr_t)&CmdBlkP->Packet, 
 					RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt), sizeof(PKT));
@@ -1026,7 +1010,7 @@
 		** MAGIC! (Basically, handshake the RX buffer, so that
 		** the RTAs upstream can be re-enabled.)
 		*/
-		rio_dprint(RIO_DEBUG_CMD, ("Util: Set RX handshake bit\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "Util: Set RX handshake bit\n");
 		WWORD(PortP->PhbP->handshake, PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
 	}
 	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -1046,7 +1030,7 @@
 #ifdef CHECK
 	CheckPortP( PortP );
 #endif
-	rio_dprint(RIO_DEBUG_CMD, ("Decrement in use count for port\n"));
+	rio_dprintk (RIO_DEBUG_CMD, "Decrement in use count for port\n");
 
 	if (PortP->InUse) {
 		if ( --PortP->InUse != NOT_INUSE ) {
diff -urN linux-2.2.17-pre15/drivers/char/rio/rioctrl.c linux/drivers/char/rio/rioctrl.c
--- linux-2.2.17-pre15/drivers/char/rio/rioctrl.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/char/rio/rioctrl.c	Mon Dec  3 22:10:50 2001
@@ -137,7 +137,7 @@
 {
   int rv;
 
-  rio_dprint (RIO_DEBUG_CTRL, ("Copying %d bytes from user %p to %p.\n", siz, (void *) arg, dp));
+  rio_dprintk (RIO_DEBUG_CTRL, "Copying %d bytes from user %p to %p.\n", siz, (void *)arg, dp);
   rv = copy_from_user (dp, (void *)arg, siz);
   if (rv < 0) return COPYFAIL;
   else return rv;
@@ -148,7 +148,7 @@
 {
   int rv;
 
-  rio_dprint (RIO_DEBUG_CTRL, ("Copying %d bytes to user %p from %p.\n", siz, (void *) arg, dp));
+  rio_dprintk (RIO_DEBUG_CTRL, "Copying %d bytes to user %p from %p.\n", siz, (void *)arg, dp);
   rv = copy_to_user ((void *)arg, dp, siz);
   if (rv < 0) return COPYFAIL;
   else return rv;
@@ -207,7 +207,7 @@
 	Host=0;
 	PortP = NULL;
 
-	rio_dprint(RIO_DEBUG_CTRL, ("control ioctl cmd: 0x%x arg: 0x%x\n", cmd, (int)arg));
+	rio_dprintk (RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: 0x%x\n", cmd, (int)arg);
 
 	switch (cmd) {
 		/*
@@ -218,7 +218,7 @@
 		** otherwise just the specified host card will be changed.
 		*/
 		case RIO_SET_TIMER:
-			rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET_TIMER to %dms\n", (uint)arg));
+			rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_TIMER to %dms\n", (uint)arg);
 			{
 				int host, value;
 				host = (uint)arg >> 16;
@@ -296,42 +296,42 @@
 			*/
 
 		case RIO_FOAD_RTA:
-			rio_dprint(RIO_DEBUG_CTRL, ("RIO_FOAD_RTA\n"));
+			rio_dprintk (RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n");
 			return RIOCommandRta(p, (uint)arg, RIOFoadRta);
 
 		case RIO_ZOMBIE_RTA:
-			rio_dprint(RIO_DEBUG_CTRL, ("RIO_ZOMBIE_RTA\n"));
+			rio_dprintk (RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n");
 			return RIOCommandRta(p, (uint)arg, RIOZombieRta);
 
 		case RIO_IDENTIFY_RTA:
-			rio_dprint(RIO_DEBUG_CTRL, ("RIO_IDENTIFY_RTA\n"));
+			rio_dprintk (RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n");
 			return RIOIdentifyRta(p, arg);
 
 		case RIO_KILL_NEIGHBOUR:
-			rio_dprint(RIO_DEBUG_CTRL, ("RIO_KILL_NEIGHBOUR\n"));
+			rio_dprintk (RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n");
 			return RIOKillNeighbour(p, arg);
 
 		case SPECIAL_RUP_CMD:
 			{
 				struct CmdBlk *CmdBlkP;
 
-				rio_dprint(RIO_DEBUG_CTRL, ("SPECIAL_RUP_CMD\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n");
 				if (copyin((int)arg, (caddr_t)&SpecialRupCmd, 
 							sizeof(SpecialRupCmd)) == COPYFAIL ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("SPECIAL_RUP_CMD copy failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n");
 					p->RIOError.Error = COPYIN_FAILED;
 		 			return EFAULT;
 				}
 				CmdBlkP = RIOGetCmdBlk();
 				if ( !CmdBlkP ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("SPECIAL_RUP_CMD GetCmdBlk failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD GetCmdBlk failed\n");
 					return ENXIO;
 				}
 				CmdBlkP->Packet = SpecialRupCmd.Packet;
 				if ( SpecialRupCmd.Host >= p->RIONumHosts )
 					SpecialRupCmd.Host = 0;
-					rio_dprint(RIO_DEBUG_CTRL, ("Queue special rup command for host %d rup %d\n",
-						SpecialRupCmd.Host, SpecialRupCmd.RupNum));
+					rio_dprintk (RIO_DEBUG_CTRL, "Queue special rup command for host %d rup %d\n",
+						SpecialRupCmd.Host, SpecialRupCmd.RupNum);
 					if (RIOQueueCmdBlk(&p->RIOHosts[SpecialRupCmd.Host], 
 							SpecialRupCmd.RupNum, CmdBlkP) == RIO_FAIL) {
 						cprintf("FAILED TO QUEUE SPECIAL RUP COMMAND\n");
@@ -348,7 +348,7 @@
 					return EPERM;
 
 			case RIO_ALL_MODEM:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_ALL_MODEM\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_ALL_MODEM\n");
 				p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
 				return EINVAL;
 
@@ -356,44 +356,44 @@
 				/*
 				** Read the routing table from the device driver to user space
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_TABLE\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_TABLE\n");
 
 				if ((retval = RIOApel(p)) != 0)
 		 			return retval;
 
 				if (copyout((caddr_t)p->RIOConnectTable, (int)arg,
 						TOTAL_MAP_ENTRIES*sizeof(struct Map)) == COPYFAIL) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_TABLE copy failed\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n");
 		 			p->RIOError.Error = COPYOUT_FAILED;
 		 			return EFAULT;
 				}
 
 				{
 					int entry;
-					rio_dprint(RIO_DEBUG_CTRL,  ("*****\nMAP ENTRIES\n") );
+					rio_dprintk (RIO_DEBUG_CTRL,  "*****\nMAP ENTRIES\n");
 					for ( entry=0; entry<TOTAL_MAP_ENTRIES; entry++ )
 					{
 					  if ((p->RIOConnectTable[entry].ID == 0) &&
 					      (p->RIOConnectTable[entry].HostUniqueNum == 0) &&
 					      (p->RIOConnectTable[entry].RtaUniqueNum == 0)) continue;
 					      
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Flags = 0x%x\n", entry, (int)p->RIOConnectTable[entry].Flags ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.SysPort = 0x%x\n", entry, (int)p->RIOConnectTable[entry].SysPort ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name ) );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Flags = 0x%x\n", entry, (int)p->RIOConnectTable[entry].Flags );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.SysPort = 0x%x\n", entry, (int)p->RIOConnectTable[entry].SysPort );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name );
 					}
-					rio_dprint(RIO_DEBUG_CTRL,  ("*****\nEND MAP ENTRIES\n") );
+					rio_dprintk (RIO_DEBUG_CTRL,  "*****\nEND MAP ENTRIES\n");
 				}
 				p->RIOQuickCheck = NOT_CHANGED;	/* a table has been gotten */
 				return 0;
@@ -402,16 +402,16 @@
 				/*
 				** Write the routing table to the device driver from user space
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_TABLE\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE\n");
 
 				if ( !su ) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_TABLE !Root\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE !Root\n");
 		 			p->RIOError.Error = NOT_SUPER_USER;
 		 			return EPERM;
 				}
 				if ( copyin((int)arg, (caddr_t)&p->RIOConnectTable[0], 
 					TOTAL_MAP_ENTRIES*sizeof(struct Map) ) == COPYFAIL ) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_TABLE copy failed\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n");
 		 			p->RIOError.Error = COPYIN_FAILED;
 		 			return EFAULT;
 				}
@@ -449,17 +449,17 @@
 				** Send bindings table, containing unique numbers of RTAs owned
 				** by this system to user space
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_BINDINGS\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS\n");
 
 				if ( !su )
 				{
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_BINDINGS !Root\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Root\n");
 		 			p->RIOError.Error = NOT_SUPER_USER;
 		 			return EPERM;
 				}
 				if (copyout((caddr_t) p->RIOBindTab, (int)arg, 
 						(sizeof(ulong) * MAX_RTA_BINDINGS)) == COPYFAIL ) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_BINDINGS copy failed\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n");
 		 			p->RIOError.Error = COPYOUT_FAILED;
 		 			return EFAULT;
 				}
@@ -470,17 +470,17 @@
 			** Receive a bindings table, containing unique numbers of RTAs owned
 			** by this system
 			*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_BINDINGS\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS\n");
 
 				if ( !su )
 				{
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_BINDINGS !Root\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Root\n");
 		 			p->RIOError.Error = NOT_SUPER_USER;
 		 			return EPERM;
 				}
 				if (copyin((int)arg, (caddr_t)&p->RIOBindTab[0], 
 						(sizeof(ulong) * MAX_RTA_BINDINGS))==COPYFAIL ) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_BINDINGS copy failed\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n");
 		 			p->RIOError.Error = COPYIN_FAILED;
 		 			return EFAULT;
 				}
@@ -493,10 +493,10 @@
 					** Bind this RTA to host, so that it will be booted by 
 					** host in 'boot owned RTAs' mode.
 					*/
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_BIND_RTA\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_BIND_RTA\n");
 
 					if ( !su ) {
-		 				rio_dprint(RIO_DEBUG_CTRL, ("RIO_BIND_RTA !Root\n"));
+		 				rio_dprintk (RIO_DEBUG_CTRL, "RIO_BIND_RTA !Root\n");
 		 				p->RIOError.Error = NOT_SUPER_USER;
 		 				return EPERM;
 					}
@@ -508,8 +508,8 @@
 							** Already exists - delete
 							*/
 							p->RIOBindTab[Entry] = 0L;
-							rio_dprint(RIO_DEBUG_CTRL, ("Removing Rta %x from p->RIOBindTab\n",
-		 												(int) arg));
+							rio_dprintk (RIO_DEBUG_CTRL, "Removing Rta %x from p->RIOBindTab\n",
+		 												(int) arg);
 							return 0;
 		 				}
 					}
@@ -518,90 +518,90 @@
 					*/
 					if (EmptySlot != -1) {
 		 				p->RIOBindTab[EmptySlot] = (int) arg;
-		 				rio_dprint(RIO_DEBUG_CTRL, ("Adding Rta %x to p->RIOBindTab\n",
-		  					(int) arg));
+		 				rio_dprintk (RIO_DEBUG_CTRL, "Adding Rta %x to p->RIOBindTab\n",
+		  					(int) arg);
 					}
 					else {
-		 				rio_dprint(RIO_DEBUG_CTRL, ("p->RIOBindTab full! - Rta %x not added\n",
-		  					(int) arg));
+		 				rio_dprintk (RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %x not added\n",
+		  					(int) arg);
 		 				return 1;
 					}
 					return 0;
 				}
 
 			case RIO_RESUME :
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME\n");
 				port = (uint) arg;
 				if ((port < 0) || (port > 511)) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME: Bad port number %d\n", port));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port);
 		 			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 		 			return EINVAL;
 				}
 				PortP = p->RIOPortp[port];
 				if (!PortP->Mapped) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME: Port %d not mapped\n", port));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mapped\n", port);
 		 			p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
 		 			return EINVAL;
 				}
 				if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME: Port %d not open\n", port));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not open\n", port);
 		 			return EINVAL;
 				}
 
 				rio_spin_lock_irqsave(&PortP->portSem, flags);
 				if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RESUME) == 
 										RIO_FAIL) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME failed\n");
 					rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 					return EBUSY;
 				}
 				else {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME: Port %d resumed\n", port));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumed\n", port);
 					PortP->State |= RIO_BUSY;
 				}
 				rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 				return retval;
 
 			case RIO_ASSIGN_RTA:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_ASSIGN_RTA\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA\n");
 				if ( !su ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_ASSIGN_RTA !Root\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Root\n");
 					p->RIOError.Error = NOT_SUPER_USER;
 					return EPERM;
 				}
 				if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
 									== COPYFAIL) {
-					rio_dprint(RIO_DEBUG_CTRL, ("Copy from user space failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "Copy from user space failed\n");
 					p->RIOError.Error = COPYIN_FAILED;
 					return EFAULT;
 				}
 				return RIOAssignRta(p, &MapEnt);
 
 			case RIO_CHANGE_NAME:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_CHANGE_NAME\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_CHANGE_NAME\n");
 				if ( !su ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_CHANGE_NAME !Root\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Root\n");
 					p->RIOError.Error = NOT_SUPER_USER;
 					return EPERM;
 				}
 				if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
 						== COPYFAIL) {
-					rio_dprint(RIO_DEBUG_CTRL, ("Copy from user space failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "Copy from user space failed\n");
 					p->RIOError.Error = COPYIN_FAILED;
 					return EFAULT;
 				}
 				return RIOChangeName(p, &MapEnt);
 
 			case RIO_DELETE_RTA:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_DELETE_RTA\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_DELETE_RTA\n");
 				if ( !su ) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_DELETE_RTA !Root\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Root\n");
 		 			p->RIOError.Error = NOT_SUPER_USER;
 		 			return EPERM;
 				}
 				if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
 							== COPYFAIL ) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("Copy from data space failed\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "Copy from data space failed\n");
 		 			p->RIOError.Error = COPYIN_FAILED;
 		 			return EFAULT;
 				}
@@ -638,7 +638,7 @@
 				return 0;
 
 			case RIO_GET_LOG:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_LOG\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_LOG\n");
 #ifdef LOGGING
 				RIOGetLog(arg);
 				return 0;
@@ -653,17 +653,17 @@
 		 			p->RIOError.Error = COPYIN_FAILED;
 		 			return EFAULT;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Get module type for port %d\n", port));
+				rio_dprintk (RIO_DEBUG_CTRL, "Get module type for port %d\n", port);
 				if ( port < 0 || port > 511 )
 				{
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_MODTYPE: Bad port number %d\n", port));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %d\n", port);
 		 			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 		 			return EINVAL;
 				}
 				PortP = (p->RIOPortp[port]);
 				if (!PortP->Mapped)
 				{
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_MODTYPE: Port %d not mapped\n", port));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mapped\n", port);
 		 			p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
 		 			return EINVAL;
 				}
@@ -703,7 +703,7 @@
 			*/
 
 	 		case RIO_BLOCK_OPENS:
-				rio_dprint(RIO_DEBUG_CTRL, ("Opens block until booted\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Opens block until booted\n");
 				for ( Entry=0; Entry < RIO_PORTS; Entry++ ) {
 		 			rio_spin_lock_irqsave(&PortP->portSem, flags);
 		 			p->RIOPortp[Entry]->WaitUntilBooted = 1;
@@ -712,33 +712,33 @@
 				return 0;
 			
 	 		case RIO_SETUP_PORTS:
-				rio_dprint(RIO_DEBUG_CTRL, ("Setup ports\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Setup ports\n");
 				if (copyin((int)arg, (caddr_t)&PortSetup, sizeof(PortSetup)) 
 						== COPYFAIL ) {
 					 p->RIOError.Error = COPYIN_FAILED;
-					 rio_dprint(RIO_DEBUG_CTRL, ("EFAULT"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "EFAULT");
 					 return EFAULT;
 				}
 				if ( PortSetup.From > PortSetup.To || 
 								PortSetup.To >= RIO_PORTS ) {
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
-					 rio_dprint(RIO_DEBUG_CTRL, ("ENXIO"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "ENXIO");
 					 return ENXIO;
 				}
 				if ( PortSetup.XpCps > p->RIOConf.MaxXpCps ||
 					 PortSetup.XpCps < p->RIOConf.MinXpCps ) {
 					 p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE;
-					 rio_dprint(RIO_DEBUG_CTRL, ("EINVAL"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "EINVAL");
 					 return EINVAL;
 				}
 				if ( !p->RIOPortp ) {
 					 cprintf("No p->RIOPortp array!\n");
-					 rio_dprint(RIO_DEBUG_CTRL, ("No p->RIOPortp array!\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "No p->RIOPortp array!\n");
 					 return EIO;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("entering loop (%d %d)!\n", PortSetup.From, PortSetup.To));
+				rio_dprintk (RIO_DEBUG_CTRL, "entering loop (%d %d)!\n", PortSetup.From, PortSetup.To);
 				for (loop=PortSetup.From; loop<=PortSetup.To; loop++) {
-				rio_dprint(RIO_DEBUG_CTRL, ("in loop (%d)!\n", loop));
+				rio_dprintk (RIO_DEBUG_CTRL, "in loop (%d)!\n", loop);
 #if 0
 					PortP = p->RIOPortp[loop];
 					if ( !PortP->TtyP )
@@ -791,12 +791,12 @@
 					 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
 #endif
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("after loop (%d)!\n", loop));
-				rio_dprint(RIO_DEBUG_CTRL,  ("Retval:%x\n", retval ) );
+				rio_dprintk (RIO_DEBUG_CTRL, "after loop (%d)!\n", loop);
+				rio_dprintk (RIO_DEBUG_CTRL, "Retval:%x\n", retval);
 				return retval;
 
 			case RIO_GET_PORT_SETUP :
-				rio_dprint(RIO_DEBUG_CTRL, ("Get port setup\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Get port setup\n");
 				if (copyin((int)arg, (caddr_t)&PortSetup, sizeof(PortSetup)) 
 							== COPYFAIL ) {
 					 p->RIOError.Error = COPYIN_FAILED;
@@ -832,7 +832,7 @@
 				return retval;
 
 			case RIO_GET_PORT_PARAMS :
-				rio_dprint(RIO_DEBUG_CTRL, ("Get port params\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Get port params\n");
 				if (copyin( (int)arg, (caddr_t)&PortParams,
 					sizeof(struct PortParams)) == COPYFAIL) {
 					p->RIOError.Error = COPYIN_FAILED;
@@ -845,7 +845,7 @@
 				PortP = (p->RIOPortp[PortParams.Port]);
 				PortParams.Config = PortP->Config;
 				PortParams.State = PortP->State;
-				rio_dprint(RIO_DEBUG_CTRL, ("Port %d\n", PortParams.Port));
+				rio_dprintk (RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port);
 
 				if (copyout((caddr_t)&PortParams, (int)arg, 
 						sizeof(struct PortParams)) == COPYFAIL ) {
@@ -855,7 +855,7 @@
 				return retval;
 
 			case RIO_GET_PORT_TTY :
-				rio_dprint(RIO_DEBUG_CTRL, ("Get port tty\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Get port tty\n");
 				if (copyin((int)arg, (caddr_t)&PortTty, sizeof(struct PortTty)) 
 						== COPYFAIL) {
 					 p->RIOError.Error = COPYIN_FAILED;
@@ -866,7 +866,7 @@
 					 return ENXIO;
 				}
 
-				rio_dprint(RIO_DEBUG_CTRL, ("Port %d\n", PortTty.port));
+				rio_dprintk (RIO_DEBUG_CTRL, "Port %d\n", PortTty.port);
 				PortP = (p->RIOPortp[PortTty.port]);
 #if 0
 				PortTty.Tty.tm.c_iflag = PortP->TtyP->tm.c_iflag;
@@ -887,7 +887,7 @@
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Set port %d tty\n", PortTty.port));
+				rio_dprintk (RIO_DEBUG_CTRL, "Set port %d tty\n", PortTty.port);
 				if (PortTty.port >= (ushort) RIO_PORTS) {
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return ENXIO;
@@ -906,7 +906,7 @@
 				return retval;
 
 			case RIO_SET_PORT_PARAMS :
-				rio_dprint(RIO_DEBUG_CTRL, ("Set port params\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Set port params\n");
 				if ( copyin((int)arg, (caddr_t)&PortParams, sizeof(PortParams))
 					== COPYFAIL ) {
 					 p->RIOError.Error = COPYIN_FAILED;
@@ -923,7 +923,7 @@
 				return retval;
 
 			case RIO_GET_PORT_STATS :
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_PORT_STATS\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n");
 				if ( copyin((int)arg, (caddr_t)&portStats, 
 						sizeof(struct portStats)) == COPYFAIL ) {
 					 p->RIOError.Error = COPYIN_FAILED;
@@ -949,7 +949,7 @@
 
 			case RIO_RESET_PORT_STATS :
 				port = (uint) arg;
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESET_PORT_STATS\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n");
 				if ( port >= RIO_PORTS ) {
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return ENXIO;
@@ -965,7 +965,7 @@
 				return retval;
 
 			case RIO_GATHER_PORT_STATS :
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_GATHER_PORT_STATS\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n");
 				if ( copyin( (int)arg, (caddr_t)&portStats, 
 						sizeof(struct portStats)) == COPYFAIL ) {
 					 p->RIOError.Error = COPYIN_FAILED;
@@ -985,22 +985,22 @@
 			case RIO_READ_LEVELS:
 				{
 					 int num;
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_LEVELS\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_LEVELS\n");
 					 for ( num=0; RIODbInf[num].Flag; num++ ) ;
-					 rio_dprint(RIO_DEBUG_CTRL, ("%d levels to copy\n",num));
+					 rio_dprintk (RIO_DEBUG_CTRL, "%d levels to copy\n",num);
 					 if (copyout((caddr_t)RIODbInf,(int)arg,
 						sizeof(struct DbInf)*(num+1))==COPYFAIL) {
-						rio_dprint(RIO_DEBUG_CTRL, ("ReadLevels Copy failed\n"));
+						rio_dprintk (RIO_DEBUG_CTRL, "ReadLevels Copy failed\n");
 						p->RIOError.Error = COPYOUT_FAILED;
 						return EFAULT;
 					 }
-					 rio_dprint(RIO_DEBUG_CTRL, ("%d levels to copied\n",num));
+					 rio_dprintk (RIO_DEBUG_CTRL, "%d levels to copied\n",num);
 					 return retval;
 				}
 #endif
 
 			 case RIO_READ_CONFIG:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_CONFIG\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n");
 				if (copyout((caddr_t)&p->RIOConf, (int)arg, 
 							sizeof(struct Conf)) ==COPYFAIL ) {
 					 p->RIOError.Error = COPYOUT_FAILED;
@@ -1009,7 +1009,7 @@
 				return retval;
 
 			case RIO_SET_CONFIG:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET_CONFIG\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_CONFIG\n");
 				if ( !su ) {
 					 p->RIOError.Error = NOT_SUPER_USER;
 					 return EPERM;
@@ -1029,11 +1029,11 @@
 				return retval;
 
 			case RIO_START_POLLER:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_START_POLLER\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_START_POLLER\n");
 				return EINVAL;
 
 			case RIO_STOP_POLLER:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_STOP_POLLER\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_STOP_POLLER\n");
 				if ( !su ) {
 					 p->RIOError.Error = NOT_SUPER_USER;
 					 return EPERM;
@@ -1043,7 +1043,7 @@
 
 			case RIO_SETDEBUG:
 			case RIO_GETDEBUG:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_SETDEBUG/RIO_GETDEBUG\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n");
 				if ( copyin( (int)arg, (caddr_t)&DebugCtrl, sizeof(DebugCtrl) )
 							==COPYFAIL ) {
 					 p->RIOError.Error = COPYIN_FAILED;
@@ -1057,18 +1057,18 @@
 						}
 						p->rio_debug = DebugCtrl.Debug;
 						p->RIODebugWait = DebugCtrl.Wait;
-						rio_dprint(RIO_DEBUG_CTRL, ("Set global debug to 0x%x set wait to 0x%x\n",
-							p->rio_debug,p->RIODebugWait));
+						rio_dprintk (RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%x\n",
+							p->rio_debug,p->RIODebugWait);
 					}
 				 	else {
-						rio_dprint(RIO_DEBUG_CTRL, ("Get global debug 0x%x wait 0x%x\n",
-										p->rio_debug,p->RIODebugWait));
+						rio_dprintk (RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n",
+										p->rio_debug,p->RIODebugWait);
 						DebugCtrl.Debug = p->rio_debug;
 						DebugCtrl.Wait  = p->RIODebugWait;
 						if ( copyout((caddr_t)&DebugCtrl,(int)arg,
 								sizeof(DebugCtrl)) == COPYFAIL ) {
-							rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET/GET DEBUG: bad port number %d\n",
-									DebugCtrl.SysPort));
+							rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n",
+									DebugCtrl.SysPort);
 						 	p->RIOError.Error = COPYOUT_FAILED;
 						 	return EFAULT;
 						}
@@ -1076,8 +1076,8 @@
 				}
 				else if ( DebugCtrl.SysPort >= RIO_PORTS && 
 							DebugCtrl.SysPort != NO_PORT ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET/GET DEBUG: bad port number %d\n",
-									DebugCtrl.SysPort));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n",
+									DebugCtrl.SysPort);
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return ENXIO;
 				}
@@ -1089,16 +1089,16 @@
 					rio_spin_lock_irqsave(&PortP->portSem, flags);
 					p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug;
 					rio_spin_unlock_irqrestore( &PortP->portSem , flags);
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_SETDEBUG 0x%x\n",
-								p->RIOPortp[DebugCtrl.SysPort]->Debug));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%x\n",
+								p->RIOPortp[DebugCtrl.SysPort]->Debug);
 				}
 				else {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_GETDEBUG 0x%x\n",
-									 p->RIOPortp[DebugCtrl.SysPort]->Debug));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n",
+									 p->RIOPortp[DebugCtrl.SysPort]->Debug);
 					DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug;
 					if ( copyout((caddr_t)&DebugCtrl,(int)arg,
 								sizeof(DebugCtrl))==COPYFAIL ) {
-						rio_dprint(RIO_DEBUG_CTRL, ("RIO_GETDEBUG: Bad copy to user space\n"));
+						rio_dprintk (RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n");
 						p->RIOError.Error = COPYOUT_FAILED;
 						return EFAULT;
 					}
@@ -1111,12 +1111,12 @@
 				** We return MAX_VERSION_LEN bytes, being a
 				** textual null terminated string.
 				*/
-				rio_dprint(RIO_DEBUG_CTRL,  ("RIO_VERSID\n") );
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_VERSID\n");
 				if ( copyout(	(caddr_t)RIOVersid(),
 						(int)arg,
 						sizeof(struct rioVersion) ) == COPYFAIL )
 				{
-					 rio_dprint(RIO_DEBUG_CTRL,  ("RIO_VERSID: Bad copy to user space (host=%d)\n",Host) );
+					 rio_dprintk (RIO_DEBUG_CTRL,  "RIO_VERSID: Bad copy to user space (host=%d)\n", Host);
 					 p->RIOError.Error = COPYOUT_FAILED;
 					 return EFAULT;
 				}
@@ -1150,10 +1150,10 @@
 				** Enquire as to the number of hosts located
 				** at init time.
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_NUM_HOSTS\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n");
 				if (copyout((caddr_t)&p->RIONumHosts, (int)arg, 
 							sizeof(p->RIONumHosts) )==COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_NUM_HOSTS: Bad copy to user space\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n");
 					 p->RIOError.Error = COPYOUT_FAILED;
 					 return EFAULT;
 				}
@@ -1163,9 +1163,9 @@
 				/*
 				** Kill host. This may not be in the final version...
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_FOAD %d\n", (int)arg));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_FOAD %d\n", (int)arg);
 				if ( !su ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_FOAD: Not super user\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n");
 					 p->RIOError.Error = NOT_SUPER_USER;
 					 return EPERM;
 				}
@@ -1213,27 +1213,27 @@
 				return retval;
 
 			case RIO_DOWNLOAD:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_DOWNLOAD\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD\n");
 				if ( !su ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_DOWNLOAD: Not super user\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super user\n");
 					 p->RIOError.Error = NOT_SUPER_USER;
 					 return EPERM;
 				}
 				if ( copyin((int)arg, (caddr_t)&DownLoad, 
 							sizeof(DownLoad) )==COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_DOWNLOAD: Copy in from user space failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n");
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
-				rio_dprint(RIO_DEBUG_CTRL,  ("Copied in download code for product code 0x%x\n",
-				    DownLoad.ProductCode ) );
+				rio_dprintk (RIO_DEBUG_CTRL, "Copied in download code for product code 0x%x\n",
+				    DownLoad.ProductCode);
 
 				/*
 				** It is important that the product code is an unsigned object!
 				*/
 				if ( DownLoad.ProductCode > MAX_PRODUCT ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_DOWNLOAD: Bad product code %d passed\n",
-							DownLoad.ProductCode));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n",
+							DownLoad.ProductCode);
 					 p->RIOError.Error = NO_SUCH_PRODUCT;
 					 return ENXIO;
 				}
@@ -1254,63 +1254,63 @@
 
 					if (copyin((int)arg, (caddr_t)&host, 
 							sizeof(host) ) == COPYFAIL ) {
-						rio_dprint(RIO_DEBUG_CTRL, (
-							"RIO_HOST_REQ: Copy in from user space failed\n"));
+						rio_dprintk (RIO_DEBUG_CTRL, 
+							"RIO_HOST_REQ: Copy in from user space failed\n");
 						p->RIOError.Error = COPYIN_FAILED;
 						return EFAULT;
 					}
 					/*
 					** Fetch the parmmap
 					*/
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_PARMS\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_PARMS\n");
 					if ( copyout( (caddr_t)p->RIOHosts[host].ParmMapP, 
 								(int)arg, sizeof(PARM_MAP) )==COPYFAIL ) {
 						p->RIOError.Error = COPYOUT_FAILED;
-						rio_dprint(RIO_DEBUG_CTRL, ("RIO_PARMS: Copy out to user space failed\n"));
+						rio_dprintk (RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n");
 						return EFAULT;
 					}
 				}
 				return retval;
 
 			case RIO_HOST_REQ:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_REQ\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ\n");
 				if (copyin((int)arg, (caddr_t)&HostReq, 
 							sizeof(HostReq) )==COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_REQ: Copy in from user space failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n");
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
 				if ( HostReq.HostNum >= p->RIONumHosts ) {
 					 p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_REQ: Illegal host number %d\n",
-							HostReq.HostNum));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %d\n",
+							HostReq.HostNum);
 					 return ENXIO;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Request for host %d\n", HostReq.HostNum));
+				rio_dprintk (RIO_DEBUG_CTRL, "Request for host %d\n", HostReq.HostNum);
 
 				if (copyout((caddr_t)&p->RIOHosts[HostReq.HostNum], 
 					(int)HostReq.HostP,sizeof(struct Host) ) == COPYFAIL) {
 					p->RIOError.Error = COPYOUT_FAILED;
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_REQ: Bad copy to user space\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user space\n");
 					return EFAULT;
 				}
 				return retval;
 
 			 case RIO_HOST_DPRAM:
-				rio_dprint(RIO_DEBUG_CTRL, ("Request for DPRAM\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Request for DPRAM\n");
 				if ( copyin( (int)arg, (caddr_t)&HostDpRam, 
 								sizeof(HostDpRam) )==COPYFAIL ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_DPRAM: Copy in from user space failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n");
 					p->RIOError.Error = COPYIN_FAILED;
 					return EFAULT;
 				}
 				if ( HostDpRam.HostNum >= p->RIONumHosts ) {
 					p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_DPRAM: Illegal host number %d\n",
-										HostDpRam.HostNum));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %d\n",
+										HostDpRam.HostNum);
 					return ENXIO;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Request for host %d\n", HostDpRam.HostNum));
+				rio_dprintk (RIO_DEBUG_CTRL, "Request for host %d\n", HostDpRam.HostNum);
 
 				if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) {
 					 int off;
@@ -1321,7 +1321,7 @@
 					if ( copyout( (caddr_t)copy, (int)HostDpRam.DpRamP, 
 							sizeof(struct DpRam) ) == COPYFAIL ) {
 						p->RIOError.Error = COPYOUT_FAILED;
-						rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_DPRAM: Bad copy to user space\n"));
+						rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
 						return EFAULT;
 					}
 				}
@@ -1329,15 +1329,15 @@
 					(int)HostDpRam.DpRamP, 
 						sizeof(struct DpRam) ) == COPYFAIL ) {
 					 p->RIOError.Error = COPYOUT_FAILED;
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_DPRAM: Bad copy to user space\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
 					 return EFAULT;
 				}
 				return retval;
 
 			 case RIO_SET_BUSY:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET_BUSY\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_BUSY\n");
 				if ( (int)arg < 0 || (int)arg > 511 ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET_BUSY: Bad port number %d\n",(int)arg));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %d\n",(int)arg);
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return EINVAL;
 				}
@@ -1351,26 +1351,26 @@
 				** The daemon want port information
 				** (probably for debug reasons)
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_PORT\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT\n");
 				if ( copyin((int)arg, (caddr_t)&PortReq, 
 					sizeof(PortReq) )==COPYFAIL ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_PORT: Copy in from user space failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n");
 					p->RIOError.Error = COPYIN_FAILED;
 					return EFAULT;
 				}
 
 				if (PortReq.SysPort >= RIO_PORTS) { /* SysPort is unsigned */
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_PORT: Illegal port number %d\n",
-											PortReq.SysPort));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %d\n",
+											PortReq.SysPort);
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return ENXIO;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Request for port %d\n", PortReq.SysPort));
+				rio_dprintk (RIO_DEBUG_CTRL, "Request for port %d\n", PortReq.SysPort);
 				if (copyout((caddr_t)p->RIOPortp[PortReq.SysPort], 
 							 (int)PortReq.PortP,
 								sizeof(struct Port) ) == COPYFAIL) {
 					 p->RIOError.Error = COPYOUT_FAILED;
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_PORT: Bad copy to user space\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user space\n");
 					 return EFAULT;
 				}
 				return retval;
@@ -1380,40 +1380,40 @@
 				** The daemon want rup information
 				** (probably for debug reasons)
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP\n");
 				if (copyin((int)arg, (caddr_t)&RupReq, 
 						sizeof(RupReq) )==COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Copy in from user space failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n");
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
 				if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Illegal host number %d\n",
-								RupReq.HostNum));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %d\n",
+								RupReq.HostNum);
 					 p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
 					 return ENXIO;
 				}
 				if ( RupReq.RupNum >= MAX_RUP+LINKS_PER_UNIT ) { /* eek! */
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Illegal rup number %d\n",
-							RupReq.RupNum));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %d\n",
+							RupReq.RupNum);
 					 p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
 					 return EINVAL;
 				}
 				HostP = &p->RIOHosts[RupReq.HostNum];
 
 				if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Host %d not running\n",
-							RupReq.HostNum));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not running\n",
+							RupReq.HostNum);
 					 p->RIOError.Error = HOST_NOT_RUNNING;
 					 return EIO;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Request for rup %d from host %d\n",
-						RupReq.RupNum,RupReq.HostNum));
+				rio_dprintk (RIO_DEBUG_CTRL, "Request for rup %d from host %d\n",
+						RupReq.RupNum,RupReq.HostNum);
 
 				if (copyout((caddr_t)HostP->UnixRups[RupReq.RupNum].RupP,
 					(int)RupReq.RupP,sizeof(struct RUP) ) == COPYFAIL) {
 					p->RIOError.Error = COPYOUT_FAILED;
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Bad copy to user space\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n");
 					return EFAULT;
 				}
 				return retval;
@@ -1423,39 +1423,39 @@
 				** The daemon want lpb information
 				** (probably for debug reasons)
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB\n");
 				if (copyin((int)arg, (caddr_t)&LpbReq, 
 					sizeof(LpbReq) )==COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Bad copy from user space\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n");
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
 				if (LpbReq.Host >= p->RIONumHosts) { /* host is unsigned */
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Illegal host number %d\n",
-							LpbReq.Host));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %d\n",
+							LpbReq.Host);
 					p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
 					return ENXIO;
 				}
 				if ( LpbReq.Link >= LINKS_PER_UNIT ) { /* eek! */
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Illegal link number %d\n",
-							LpbReq.Link));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n",
+							LpbReq.Link);
 					 p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE;
 					 return EINVAL;
 				}
 				HostP = &p->RIOHosts[LpbReq.Host];
 
 				if ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Host %d not running\n",
-						LpbReq.Host));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n",
+						LpbReq.Host );
 					 p->RIOError.Error = HOST_NOT_RUNNING;
 					 return EIO;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Request for lpb %d from host %d\n",
-					LpbReq.Link, LpbReq.Host));
+				rio_dprintk (RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n",
+					LpbReq.Link, LpbReq.Host);
 
 				if (copyout((caddr_t)&HostP->LinkStrP[LpbReq.Link],
 					(int)LpbReq.LpbP,sizeof(struct LPB) ) == COPYFAIL) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Bad copy to user space\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n");
 					p->RIOError.Error = COPYOUT_FAILED;
 					return EFAULT;
 				}
@@ -1494,7 +1494,7 @@
 					 p->RIOError.Error = NOT_RECEIVING_PROCESS;
 					 return EPERM;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Clear signal process to zero\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Clear signal process to zero\n");
 				p->RIOSignalProcess = 0;
 				return retval;
 
@@ -1526,10 +1526,10 @@
 			case RIO_MAP_B50_TO_57600:
 			case RIO_MAP_B110_TO_110:
 			case RIO_MAP_B110_TO_115200:
-				rio_dprint(RIO_DEBUG_CTRL, ("Baud rate mapping\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping\n");
 				port = (uint) arg;
 				if ( port < 0 || port > 511 ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("Baud rate mapping: Bad port number %d\n", port));
+					 rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port);
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return EINVAL;
 				}
@@ -1553,14 +1553,14 @@
 				return retval;
 
 			case RIO_STREAM_INFO:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_STREAM_INFO\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_STREAM_INFO\n");
 				return EINVAL;
 
 			case RIO_SEND_PACKET:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_SEND_PACKET\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n");
 				if ( copyin( (int)arg, (caddr_t)&SendPack,
 									sizeof(SendPack) )==COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_SEND_PACKET: Bad copy from user space\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n");
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
@@ -1605,7 +1605,7 @@
 			case RIO_WHAT_MESG:
 				if ( copyout( (caddr_t)&p->RIONoMessage, (int)arg, 
 					sizeof(p->RIONoMessage) )==COPYFAIL ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_WHAT_MESG: Bad copy to user space\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n");
 					p->RIOError.Error = COPYOUT_FAILED;
 					return EFAULT;
 				}
@@ -1617,8 +1617,8 @@
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_MEM_DUMP host %d rup %d addr %x\n", 
-						SubCmd.Host, SubCmd.Rup, SubCmd.Addr));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %x\n", 
+						SubCmd.Host, SubCmd.Rup, SubCmd.Addr);
 
 				if (SubCmd.Rup >= MAX_RUP+LINKS_PER_UNIT ) {
 					 p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
@@ -1638,7 +1638,7 @@
 				rio_spin_lock_irqsave(&PortP->portSem, flags);
 
 				if ( RIOPreemptiveCmd(p,  PortP, MEMDUMP ) == RIO_FAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_MEM_DUMP failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n");
 					 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
 					 return EBUSY;
 				}
@@ -1648,7 +1648,7 @@
 				rio_spin_unlock_irqrestore( &PortP->portSem , flags);
 				if ( copyout( (caddr_t)p->RIOMemDump, (int)arg, 
 							MEMDUMP_SIZE) == COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_MEM_DUMP copy failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n");
 					 p->RIOError.Error = COPYOUT_FAILED;
 					 return EFAULT;
 				}
@@ -1657,14 +1657,14 @@
 			case RIO_TICK:
 				if ((int)arg < 0 || (int)arg >= p->RIONumHosts)
 					 return EINVAL;
-				rio_dprint(RIO_DEBUG_CTRL, ("Set interrupt for host %d\n", (int)arg ));
+				rio_dprintk (RIO_DEBUG_CTRL, "Set interrupt for host %d\n", (int)arg);
 				WBYTE(p->RIOHosts[(int)arg].SetInt , 0xff);
 				return 0;
 
 			case RIO_TOCK:
 				if ((int)arg < 0 || (int)arg >= p->RIONumHosts)
 					 return EINVAL;
-				rio_dprint(RIO_DEBUG_CTRL, ("Clear interrupt for host %d\n", (int)arg ));
+				rio_dprintk (RIO_DEBUG_CTRL, "Clear interrupt for host %d\n", (int)arg);
 				WBYTE((p->RIOHosts[(int)arg].ResetInt) , 0xff);
 				return 0;
 
@@ -1684,12 +1684,12 @@
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_REGISTER host %d rup %d port %d reg %x\n", 
-						SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER host %d rup %d port %d reg %x\n", 
+						SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr);
 
 				if (SubCmd.Port > 511) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("Baud rate mapping: Bad port number %d\n", 
-								SubCmd.Port));
+					 rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", 
+								SubCmd.Port);
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return EINVAL;
 				}
@@ -1711,7 +1711,7 @@
 				rio_spin_lock_irqsave(&PortP->portSem, flags);
 
 				if (RIOPreemptiveCmd(p, PortP, READ_REGISTER) == RIO_FAIL) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_REGISTER failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n");
 					 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
 					 return EBUSY;
 				}
@@ -1721,7 +1721,7 @@
 				rio_spin_unlock_irqrestore( &PortP->portSem , flags);
 				if (copyout((caddr_t)&p->CdRegister, (int)arg, 
 							sizeof(uint)) == COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_REGISTER copy failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n");
 					 p->RIOError.Error = COPYOUT_FAILED;
 					 return EFAULT;
 				}
@@ -1738,18 +1738,18 @@
 					switch ( (uint)arg & RIO_DEV_MASK ) {
 						case RIO_DEV_DIRECT:
 							arg = (caddr_t)drv_makedev(major(dev), port);
-							rio_dprint(RIO_DEBUG_CTRL, ("Makedev direct 0x%x is 0x%x\n",port, (int)arg ));
+							rio_dprintk (RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n",port, (int)arg);
 							return (int)arg;
 					 	case RIO_DEV_MODEM:
 							arg =  (caddr_t)drv_makedev(major(dev), (port|RIO_MODEM_BIT) );
-							rio_dprint(RIO_DEBUG_CTRL, ("Makedev modem 0x%x is 0x%x\n",port, (int)arg ));
+							rio_dprintk (RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%x\n",port, (int)arg);
 							return (int)arg;
 						case RIO_DEV_XPRINT:
 							arg = (caddr_t)drv_makedev(major(dev), port);
-							rio_dprint(RIO_DEBUG_CTRL, ("Makedev printer 0x%x is 0x%x\n",port, (int)arg ));
+							rio_dprintk (RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%x\n",port, (int)arg);
 							return (int)arg;
 					}
-					rio_dprint(RIO_DEBUG_CTRL, ("MAKE Device is called\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "MAKE Device is called\n");
 					return EINVAL;
 				}
 				/*
@@ -1766,17 +1766,17 @@
 					mino = RIO_UNMODEM(dv);
 
 					if ( RIO_ISMODEM(dv) ) {
-						rio_dprint(RIO_DEBUG_CTRL, ("Minor for device 0x%x: modem %d\n", dv, mino));
+						rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %d\n", dv, mino);
 						arg = (caddr_t)(mino | RIO_DEV_MODEM);
 					}
 					else {
-						rio_dprint(RIO_DEBUG_CTRL, ("Minor for device 0x%x: direct %d\n", dv, mino));
+						rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %d\n", dv, mino);
 						arg = (caddr_t)(mino | RIO_DEV_DIRECT);
 					}
 					return (int)arg;
 				}
 	}
-	rio_dprint(RIO_DEBUG_CTRL, ("INVALID DAEMON IOCTL 0x%x\n",cmd));
+	rio_dprintk (RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%x\n",cmd);
 	p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
 
 	func_exit ();
@@ -1803,18 +1803,18 @@
 #endif
 
 	if ( PortP->State & RIO_DELETED ) {
-		rio_dprint(RIO_DEBUG_CTRL, ("Preemptive command to deleted RTA ignored\n"));
+		rio_dprintk (RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignored\n");
 		return RIO_FAIL;
 	}
 
 	if (((int)((char)PortP->InUse) == -1) || ! (CmdBlkP = RIOGetCmdBlk()) ) {
-		rio_dprint(RIO_DEBUG_CTRL, ("Cannot allocate command block for command %d on port %d\n",
-		       Cmd, PortP->PortNum));
+		rio_dprintk (RIO_DEBUG_CTRL, "Cannot allocate command block for command %d on port %d\n",
+		       Cmd, PortP->PortNum);
 		return RIO_FAIL;
 	}
 
-	rio_dprint(RIO_DEBUG_CTRL, ("Command blk 0x%x - InUse now %d\n", 
-	       (int)CmdBlkP,PortP->InUse));
+	rio_dprintk (RIO_DEBUG_CTRL, "Command blk 0x%x - InUse now %d\n", 
+	       (int)CmdBlkP,PortP->InUse);
 
 	PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0];
 
@@ -1840,40 +1840,40 @@
 
 	switch ( Cmd ) {
 		case MEMDUMP:
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue MEMDUMP command blk 0x%x (addr 0x%x)\n",
-			       (int)CmdBlkP, (int)SubCmd.Addr));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue MEMDUMP command blk 0x%x (addr 0x%x)\n",
+			       (int)CmdBlkP, (int)SubCmd.Addr);
 			PktCmdP->SubCommand		= MEMDUMP;
 			PktCmdP->SubAddr		= SubCmd.Addr;
 			break;
 		case FCLOSE:
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue FCLOSE command blk 0x%x\n",(int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue FCLOSE command blk 0x%x\n",(int)CmdBlkP);
 			break;
 		case READ_REGISTER:
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue READ_REGISTER (0x%x) command blk 0x%x\n",
-		 		(int)SubCmd.Addr, (int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) command blk 0x%x\n",
+		 		(int)SubCmd.Addr, (int)CmdBlkP);
 			PktCmdP->SubCommand		= READ_REGISTER;
 			PktCmdP->SubAddr		= SubCmd.Addr;
 			break;
 		case RESUME:
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue RESUME command blk 0x%x\n",(int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue RESUME command blk 0x%x\n",(int)CmdBlkP);
 			break;
 		case RFLUSH:
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue RFLUSH command blk 0x%x\n",(int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue RFLUSH command blk 0x%x\n",(int)CmdBlkP);
 			CmdBlkP->PostFuncP = RIORFlushEnable;
 			break;
 		case SUSPEND:
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue SUSPEND command blk 0x%x\n",(int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue SUSPEND command blk 0x%x\n",(int)CmdBlkP);
 			break;
 
 		case MGET :
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue MGET command blk 0x%x\n", (int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue MGET command blk 0x%x\n", (int)CmdBlkP);
 			break;
 
 		case MSET :
 		case MBIC :
 		case MBIS :
 			CmdBlkP->Packet.data[4] = (char) PortP->ModemLines;
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue MSET/MBIC/MBIS command blk 0x%x\n", (int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command blk 0x%x\n", (int)CmdBlkP);
 			break;
 
 		case WFLUSH:
@@ -1883,12 +1883,12 @@
 			** RTA.
 			*/
 			if ((int)((char)PortP->WflushFlag) == (int)-1) {
-				rio_dprint(RIO_DEBUG_CTRL, ("Trashed WFLUSH, WflushFlag about to wrap!"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Trashed WFLUSH, WflushFlag about to wrap!");
 				RIOFreeCmdBlk(CmdBlkP);
 				return(RIO_FAIL);
 			} else {
-				rio_dprint(RIO_DEBUG_CTRL, ("Queue WFLUSH command blk 0x%x\n",
-				       (int)CmdBlkP));
+				rio_dprintk (RIO_DEBUG_CTRL, "Queue WFLUSH command blk 0x%x\n",
+				       (int)CmdBlkP);
 				CmdBlkP->PostFuncP = RIOWFlushMark;
 			}
 			break;
diff -urN linux-2.2.17-pre15/drivers/char/rio/rioinit.c linux/drivers/char/rio/rioinit.c
--- linux-2.2.17-pre15/drivers/char/rio/rioinit.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/char/rio/rioinit.c	Mon Dec  3 22:10:50 2001
@@ -81,7 +81,7 @@
 #include "control.h"
 #include "cirrus.h"
 #include "rioioctl.h"
-
+#include "rio_linux.h"
 
 #undef bcopy
 #define bcopy rio_pcicopy
@@ -109,7 +109,7 @@
 	*/
 	if ( !p->RIOPortp )
 	{
-		rio_dprint(RIO_DEBUG_INIT,  ("Allocating and setting up driver data structures\n") );
+		rio_dprintk (RIO_DEBUG_INIT,  "Allocating and setting up driver data structures\n");
 
 		RIOAllocDataStructs(p);		/* allocate host/port structs */
 		RIOSetupDataStructs(p);		/* setup topology structs */
@@ -155,16 +155,16 @@
 
 	if ( info->bus & ISA_BUS )
 	{
-		rio_dprint(RIO_DEBUG_INIT,  ("initialising card %d (ISA)\n", p->RIONumHosts) );
+		rio_dprintk (RIO_DEBUG_INIT,  "initialising card %d (ISA)\n", p->RIONumHosts);
 		RIOISAinit(p, p->mode);
 	}
 	else
 	{
-		rio_dprint(RIO_DEBUG_INIT,  ("initialising card %d (PCI)\n", p->RIONumHosts) );
+		rio_dprintk (RIO_DEBUG_INIT,  "initialising card %d (PCI)\n", p->RIONumHosts);
 		RIOPCIinit(p, RIO_PCI_DEFAULT_MODE);
 	}
 
-	rio_dprint(RIO_DEBUG_INIT,  ("Total hosts initialised so far : %d\n", p->RIONumHosts) );
+	rio_dprintk (RIO_DEBUG_INIT,  "Total hosts initialised so far : %d\n", p->RIONumHosts);
 
 
 #ifdef FUTURE_RELEASE
@@ -193,13 +193,13 @@
 	p->intr_tid = iointset(p->RIOHosts[p->RIONumHosts].Ivec,
 					(int (*)())rio_intr, (char*)p->RIONumHosts);
 
-	rio_dprint(RIO_DEBUG_INIT,  ("Set interrupt handler, intr_tid = 0x%x\n", p->intr_tid ) );
+	rio_dprintk (RIO_DEBUG_INIT,  "Set interrupt handler, intr_tid = 0x%x\n", p->intr_tid );
 
 	if (RIODoAT(p, p->RIOHosts[p->RIONumHosts].PaddrP, mode)) {
 		return;
 	}
 	else {
-		rio_dprint(RIO_DEBUG_INIT, ("RIODoAT failed\n"));
+		rio_dprintk (RIO_DEBUG_INIT, "RIODoAT failed\n");
 		p->RIOFailed++;
 	}
 #endif
@@ -268,7 +268,7 @@
 	** map it in in one 64K block.
 	*/
 	if (RIOMapin(Base, RIO_AT_MEM_SIZE, &virtAddr) == -1) {
-		rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Couldn't map the board in!\n"));
+		rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Couldn't map the board in!\n");
 		return((caddr_t)0);
 	}
 
@@ -285,8 +285,8 @@
 			** Signature mismatch - card not at this address
 			*/
 			RIOMapout(Base, RIO_AT_MEM_SIZE, virtAddr);
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Couldn't match the signature 0x%x 0x%x!\n",
-						(int)cardp, off));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Couldn't match the signature 0x%x 0x%x!\n",
+						(int)cardp, off);
 			return((caddr_t)0);
 		}
 	}
@@ -356,10 +356,10 @@
 		((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1])&0xFF)<<8)|
 		((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)|
 		((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24);
-	rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum));
+	rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum);
 
 	p->RIONumHosts++;
-	rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Tests Passed at 0x%x\n", Base));
+	rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Tests Passed at 0x%x\n", Base);
 	return(1);
 }
 #if 0
@@ -378,7 +378,7 @@
 	** is only FAST LINKS
 	*/
 	Mode = (Mode & FAST_LINKS) ? McaTpFastLinks : McaTpSlowLinks;
-	rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"RIOMCAinit(%d)\n",Mode);
+	rio_dprintk (RIO_DEBUG_INIT, "RIOMCAinit(%d)\n",Mode);
 
 
 	/*
@@ -395,7 +395,7 @@
 	*/
 	if (((inb(McaIdHigh)<< 8)|inb(McaIdLow)) == McaRIOId)
 	{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Potential MCA card in slot %d\n",SlotNumber);
+		rio_dprintk (RIO_DEBUG_INIT, "Potential MCA card in slot %d\n", SlotNumber);
 
 		/*
 		** Card appears to be a RIO MCA card!
@@ -417,48 +417,44 @@
 		*/
 		Ivec = inb(McaIrqEnable);
 
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Ivec is %x\n",Ivec);
+		rio_dprintk (RIO_DEBUG_INIT, "Ivec is %x\n", Ivec);
 
 		switch ( Ivec & McaIrqMask )
 		{
 		case McaIrq9:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ9\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ9\n");
 		break;
 		case McaIrq3:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ3\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ3\n");
 		break;
 		case McaIrq4:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ4\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ4\n");
 		break;
 		case McaIrq7:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ7\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ7\n");
 		break;
 		case McaIrq10:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ10\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ10\n");
 		break;
 		case McaIrq11:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ11\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ11\n");
 		break;
 		case McaIrq12:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ12\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ12\n");
 		break;
 		case McaIrq15:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ15\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ15\n");
 		break;
 		}
 
 		/*
 		** If the card enable bit isn't set, then set it!
 		*/
-		if ((Ivec & McaCardEnable) != McaCardEnable )
-		{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"McaCardEnable not set - setting!\n");
-		outb(McaIrqEnable,Ivec|McaCardEnable);
-		}
-		else
-		{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"McaCardEnable already set\n");
-		}
+		if ((Ivec & McaCardEnable) != McaCardEnable) {
+			rio_dprintk (RIO_DEBUG_INIT, "McaCardEnable not set - setting!\n");
+			outb(McaIrqEnable,Ivec|McaCardEnable);
+		} else
+			rio_dprintk (RIO_DEBUG_INIT, "McaCardEnable already set\n");
 
 		/*
 		** Convert the IRQ enable mask into something useful
@@ -468,10 +464,10 @@
 		/*
 		** Find the physical address
 		*/
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"inb(McaMemory) is %x\n",inb(McaMemory));
+		rio_dprintk (RIO_DEBUG_INIT, "inb(McaMemory) is %x\n", inb(McaMemory));
 		Paddr = McaAddress(inb(McaMemory));
 
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"MCA card has Ivec %d Addr %x\n",Ivec,Paddr);
+		rio_dprintk (RIO_DEBUG_INIT, "MCA card has Ivec %d Addr %x\n", Ivec, Paddr);
 
 		if ( Paddr != 0 )
 		{
@@ -482,21 +478,20 @@
 		Handle = RIOMapin( Paddr, RIO_MCA_MEM_SIZE, &Caddr );
 
 		if ( Handle == -1 ) {
-			rio_dprint(RIO_DEBUG_INIT, ("Couldn't map %d bytes at %x\n", RIO_MCA_MEM_SIZE,Paddr);
+			rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at %x\n", RIO_MCA_MEM_SIZE, Paddr;
 			continue;
 		}
 
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Board mapped to vaddr 0x%x\n",Caddr);
+		rio_dprintk (RIO_DEBUG_INIT, "Board mapped to vaddr 0x%x\n", Caddr);
 
 		/*
 		** And check that it is actually there!
 		*/
 		if ( RIOBoardTest( Paddr,Caddr,RIO_MCA,SlotNumber ) == RIO_SUCCESS )
 		{
-			rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Board has passed test\n");
-			rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,
-	"Slot %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n",
-			SlotNumber,RIO_MCA,Paddr,Caddr,Mode);
+			rio_dprintk (RIO_DEBUG_INIT, "Board has passed test\n");
+			rio_dprintk (RIO_DEBUG_INIT, "Slot %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n",
+			                            SlotNumber, RIO_MCA, Paddr, Caddr, Mode);
 
 			/*
 			** Board has passed its scrub test. Fill in all the
@@ -524,25 +519,25 @@
 			/*
 			** It failed the test, so ignore it.
 			*/
-			rio_dprint(RIO_DEBUG_INIT, NULL,DBG_FAIL,"TEST FAILED\n");
+			rio_dprintk (RIO_DEBUG_INIT, "TEST FAILED\n");
 			RIOMapout(Paddr, RIO_MCA_MEM_SIZE, Caddr );
 		}
 		}
 		else
 		{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Slot %d - Paddr zero!\n",SlotNumber);
+		rio_dprintk (RIO_DEBUG_INIT, "Slot %d - Paddr zero!\n", SlotNumber);
 		}
 	}
 	else
 	{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Slot %d NOT RIO\n",SlotNumber);
+		rio_dprintk (RIO_DEBUG_INIT, "Slot %d NOT RIO\n", SlotNumber);
 	}
 	}
 	/*
 	** Now we have checked all the slots, turn off the MCA slot selector
 	*/
 	outb(McaSlotSelect,0);
-	rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Slot %d NOT RIO\n",SlotNumber);
+	rio_dprintk (RIO_DEBUG_INIT, "Slot %d NOT RIO\n", SlotNumber);
 	return ret;
 }
 
@@ -565,13 +560,13 @@
 
 	if ( EISADone )
 	{
-	rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"RIOEISAinit() - already done, return.\n");
+		rio_dprintk (RIO_DEBUG_INIT, "RIOEISAinit() - already done, return.\n");
 		return(0);
 	}
 
 	EISADone++;
 
-	rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"RIOEISAinit()\n");
+	rio_dprintk (RIO_DEBUG_INIT, "RIOEISAinit()\n");
 
 
 	/*
@@ -584,23 +579,21 @@
 	Ident = (INBZ(EisaSlot,EISA_PRODUCT_IDENT_HI)<<8) |
 		 INBZ(EisaSlot,EISA_PRODUCT_IDENT_LO);
 
-	/* rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT, "Check EISA slot %d, ID=%x\n",EisaSlot,Ident); */
-
 	if ( Ident == RIO_EISA_IDENT )
 	{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Found Specialix product\n");
+		rio_dprintk (RIO_DEBUG_INIT, "Found Specialix product\n");
 
 		if ( INBZ(EisaSlot,EISA_PRODUCT_NUMBER) != RIO_EISA_PRODUCT_CODE )
 		{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Not Specialix RIO - Product number %x\n",
-						INBZ(EisaSlot,EISA_PRODUCT_NUMBER));
+		rio_dprintk (RIO_DEBUG_INIT, "Not Specialix RIO - Product number %x\n",
+						INBZ(EisaSlot, EISA_PRODUCT_NUMBER));
 		continue;  /* next slot */
 		}
 		/*
 		** Its a Specialix RIO!
 		*/
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"RIO Revision %d\n",
-					INBZ(EisaSlot,EISA_REVISION_NUMBER));
+		rio_dprintk (RIO_DEBUG_INIT, "RIO Revision %d\n",
+					INBZ(EisaSlot, EISA_REVISION_NUMBER));
 		
 		RIOMachineType |= (1<<RIO_EISA);
 
@@ -627,43 +620,43 @@
 		switch ( Ivec & EISA_INTERRUPT_MASK )
 		{
 		case EISA_IRQ_3:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 3\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 3\n");
 		break;
 		case EISA_IRQ_4:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 4\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 4\n");
 		break;
 		case EISA_IRQ_5:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 5\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 5\n");
 		break;
 		case EISA_IRQ_6:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 6\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 6\n");
 		break;
 		case EISA_IRQ_7:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 7\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 7\n");
 		break;
 		case EISA_IRQ_9:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 9\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 9\n");
 		break;
 		case EISA_IRQ_10:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 10\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 10\n");
 		break;
 		case EISA_IRQ_11:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 11\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 11\n");
 		break;
 		case EISA_IRQ_12:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 12\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 12\n");
 		break;
 		case EISA_IRQ_14:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 14\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 14\n");
 		break;
 		case EISA_IRQ_15:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 15\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 15\n");
 		break;
 		case EISA_POLLED:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA POLLED\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA POLLED\n");
 		break;
 		default:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT|DBG_FAIL,"Shagged interrupt number!\n");
+			rio_dprintk (RIO_DEBUG_INIT, NULL,DBG_INIT|DBG_FAIL,"Shagged interrupt number!\n");
 		Ivec &= EISA_CONTROL_MASK;
 		}
 #endif
@@ -741,7 +734,7 @@
 		*/
 		Ivec = RIOEisaToIvec(Ivec);
 
-		rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT, "EISA host in slot %d has Ivec 0x%x\n",
+		rio_dprintk (RIO_DEBUG_INIT, "EISA host in slot %d has Ivec 0x%x\n",
 		 EisaSlot, Ivec);
 
 		/*
@@ -750,11 +743,11 @@
 		Paddr = (INBZ(EisaSlot,EISA_MEMORY_BASE_HI)<<24) |
 				(INBZ(EisaSlot,EISA_MEMORY_BASE_LO)<<16);
 
-		rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT,"EISA card has Ivec %d Addr %x\n",Ivec,Paddr);
+		rio_dprintk (RIO_DEBUG_INIT, "EISA card has Ivec %d Addr %x\n", Ivec, Paddr);
 
 		if ( Paddr == 0 )
 		{
-		rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT | DBG_FAIL,
+		rio_dprintk (RIO_DEBUG_INIT,
 		 "Board in slot %d configured for address zero!\n", EisaSlot);
 		continue;
 		}
@@ -762,23 +755,23 @@
 		/*
 		** Tell the memory mapper that we want to talk to it
 		*/
-		rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT,"About to map EISA card \n");
+		rio_dprintk (RIO_DEBUG_INIT, "About to map EISA card \n");
 
 		if (RIOMapin( Paddr, RIO_EISA_MEM_SIZE, &Caddr) == -1) {
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_FAIL,"Couldn't map %d bytes at %x\n",
+		rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at %x\n",
 							RIO_EISA_MEM_SIZE,Paddr);
 		continue;
 		}
 
-		rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT,"Board mapped to vaddr 0x%x\n",Caddr);
+		rio_dprintk (RIO_DEBUG_INIT, "Board mapped to vaddr 0x%x\n", Caddr);
 
 		/*
 		** And check that it is actually there!
 		*/
 		if ( RIOBoardTest( Paddr,Caddr,RIO_EISA,EisaSlot) == RIO_SUCCESS )
 			{
-		rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT,"Board has passed test\n");
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,
+		rio_dprintk (RIO_DEBUG_INIT, "Board has passed test\n");
+		rio_dprintk (RIO_DEBUG_INIT, 
 		"Slot %d. Ivec %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n",
 			EisaSlot,Ivec,RIO_EISA,Paddr,Caddr,Mode);
 
@@ -818,7 +811,7 @@
 		/*
 		** It failed the test, so ignore it.
 		*/
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_FAIL,"TEST FAILED\n");
+		rio_dprintk (RIO_DEBUG_INIT, "TEST FAILED\n");
 
 		RIOMapout(Paddr, RIO_EISA_MEM_SIZE, Caddr );
 		}
@@ -917,7 +910,7 @@
 	int		Handle;	/* Handle to Virtual memory allocated for current PCI host */
 
 
-	rio_dprint(RIO_DEBUG_INIT,  ("Search for a RIO PCI card - start at slot %d\n", slot ) );
+	rio_dprintk (RIO_DEBUG_INIT,  "Search for a RIO PCI card - start at slot %d\n", slot);
 
 	/*
 	** Initialise the search status
@@ -926,7 +919,7 @@
 
 	while ( (slot < MAX_PCI_SLOT) & (p->RIOLastPCISearch != RIO_SUCCESS) )
 	{
-		rio_dprint(RIO_DEBUG_INIT,  ("Currently testing slot %d\n", slot ) );
+		rio_dprintk (RIO_DEBUG_INIT,  "Currently testing slot %d\n", slot);
 
 		if (read_config(0,slot,0) == RIO_PCI_JET_CARD) {
 			p->RIOHosts[p->RIONumHosts].Ivec = 0;
@@ -934,7 +927,7 @@
 			Paddr = Paddr - (Paddr & 0x1); /* Mask off the io bit */
 
 			if ( (Paddr == 0) || ((Paddr & 0xffff0000) == 0xffff0000) ) {
-				rio_dprint(RIO_DEBUG_INIT,  ("Goofed up slot\n") );	/* what! */
+				rio_dprintk (RIO_DEBUG_INIT,  "Goofed up slot\n");	/* what! */
 				slot++;
 				continue;
 			}
@@ -942,11 +935,11 @@
 			p->RIOHosts[p->RIONumHosts].PaddrP = Paddr;
 			Ivec = (read_config(0,slot,0x3c) & 0xff);
 
-			rio_dprint(RIO_DEBUG_INIT,  ("PCI Host at 0x%x, Intr %d\n", (int)Paddr, Ivec ) );
+			rio_dprintk (RIO_DEBUG_INIT,  "PCI Host at 0x%x, Intr %d\n", (int)Paddr, Ivec);
 
 			Handle = RIOMapin( Paddr, RIO_PCI_MEM_SIZE, &Caddr );
 			if (Handle == -1) {
-				rio_dprint(RIO_DEBUG_INIT,  ("Couldn't map %d bytes at 0x%x\n", RIO_PCI_MEM_SIZE, (int)Paddr ) );
+				rio_dprintk (RIO_DEBUG_INIT,  "Couldn't map %d bytes at 0x%x\n", RIO_PCI_MEM_SIZE, (int)Paddr);
 				slot++;
 				continue;
 			}
@@ -954,9 +947,8 @@
 			p->intr_tid = iointset(p->RIOHosts[p->RIONumHosts].Ivec,
 						(int (*)())rio_intr, (char *)p->RIONumHosts);
 			if (RIOBoardTest( Paddr, Caddr, RIO_PCI, 0 ) == RIO_SUCCESS) {
-				rio_dprint(RIO_DEBUG_INIT, ("Board has passed test\n"));
-				rio_dprint(RIO_DEBUG_INIT, ("Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n", Paddr, Caddr, 
-																Mode));
+				rio_dprintk (RIO_DEBUG_INIT, ("Board has passed test\n");
+				rio_dprintk (RIO_DEBUG_INIT, ("Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n", Paddr, Caddr, Mode);
 
 				/*
 				** Board has passed its scrub test. Fill in all the
@@ -991,8 +983,8 @@
 					((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)|
 					((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24);
 
-				rio_dprint(RIO_DEBUG_INIT,  ("Unique no 0x%x.\n", 
-				    p->RIOHosts[p->RIONumHosts].UniqueNum ) );
+				rio_dprintk (RIO_DEBUG_INIT, "Unique no 0x%x.\n", 
+				    p->RIOHosts[p->RIONumHosts].UniqueNum);
 
 				p->RIOLastPCISearch = RIO_SUCCESS;
 				p->RIONumHosts++;
@@ -1002,8 +994,8 @@
 	}
 
 	if ( slot >= MAX_PCI_SLOT ) {
-		rio_dprint(RIO_DEBUG_INIT,  ("All %d PCI slots have tested for RIO cards !!!\n",
-		    MAX_PCI_SLOT ) );
+		rio_dprintk (RIO_DEBUG_INIT,  "All %d PCI slots have tested for RIO cards !!!\n",
+			     MAX_PCI_SLOT);
 	}
 
 
@@ -1025,7 +1017,7 @@
 	int host;
 	for ( host=0; host<p->RIONumHosts; host++ )
 	{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Stop host %d\n",host);
+		rio_dprintk (RIO_DEBUG_INIT, "Stop host %d\n", host);
 		(void)RIOBoardTest( p->RIOHosts[host].PaddrP, p->RIOHosts[host].Caddr, p->RIOHosts[host].Type,p->RIOHosts[host].Slot );
 	}
 }
@@ -1058,8 +1050,8 @@
 	int  op, bank;
 	int  nbanks;
 
-	rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Reset host type=%d, DpRam=0x%x, slot=%d\n",
-			type,(int)DpRam,slot));
+	rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Reset host type=%d, DpRam=0x%x, slot=%d\n",
+			type,(int)DpRam, slot);
 
 	RIOHostReset(type, DpRam, slot);
 
@@ -1071,7 +1063,7 @@
 	** scratch	- 1000h bytes
 	*/
 
-	rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Setup ram/size arrays\n"));
+	rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Setup ram/size arrays\n");
 
 	size[0] = DP_SRAM1_SIZE;
 	size[1] = DP_SRAM2_SIZE;
@@ -1087,12 +1079,12 @@
 
 
 	if (nbanks == 3) {
-		rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Memory: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
-				(int)ram[0], size[0], (int)ram[1], size[1], (int)ram[2], size[2]));
+		rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Memory: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
+				(int)ram[0], size[0], (int)ram[1], size[1], (int)ram[2], size[2]);
 	} else {
-		rio_dprint(RIO_DEBUG_INIT, ("RIO-init: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
+		rio_dprintk (RIO_DEBUG_INIT, "RIO-init: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
 			(int)ram[0], size[0], (int)ram[1], size[1], (int)ram[2], size[2], (int)ram[3], 
-					size[3]));
+					size[3]);
 	}
 
 	/*
@@ -1103,14 +1095,14 @@
 	for (op=0; op<TEST_END; op++) {
 		for (bank=0; bank<nbanks; bank++) {
 			if (RIOScrub(op, (BYTE *)ram[bank], size[bank]) == RIO_FAIL) {
-				rio_dprint(RIO_DEBUG_INIT, ("RIO-init: RIOScrub band %d, op %d failed\n", 
-							bank, op));
+				rio_dprintk (RIO_DEBUG_INIT, "RIO-init: RIOScrub band %d, op %d failed\n", 
+							bank, op);
 				return RIO_FAIL;
 			}
 		}
 	}
 
-	rio_dprint(RIO_DEBUG_INIT, ("Test completed\n"));
+	rio_dprintk (RIO_DEBUG_INIT, "Test completed\n");
 	return RIO_SUCCESS;
 }
 
@@ -1158,14 +1150,14 @@
 	if (op) {
 		for (off=0; off<size; off++) {
 			if (RBYTE(ram[off]) != oldbyte) {
-				rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Byte Pre Check 1: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, RBYTE(ram[off])));
+				rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 1: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, RBYTE(ram[off]));
 				return RIO_FAIL;
 			}
 		}
 		for (off=0; off<size; off+=2) {
 			if (*(ushort *)&ram[off] != oldword) {
-				rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Word Pre Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,oldword,*(ushort *)&ram[off]));
-				rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Word Pre Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+				rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,oldword,*(ushort *)&ram[off]);
+				rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
 				return RIO_FAIL;
 			}
 		}
@@ -1180,12 +1172,12 @@
 	*/
 	for (off=0; off<size; off++) {
 		if (op && (RBYTE(ram[off]) != oldbyte)) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Byte Pre Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n",off,oldbyte,RBYTE(ram[off])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, RBYTE(ram[off]));
 			return RIO_FAIL;
 		}
 		WBYTE(ram[off],invbyte);
 		if (RBYTE(ram[off]) != invbyte) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Byte Inv Check: BYTE at offset 0x%x should have been=%x, was=%x\n",off,invbyte,RBYTE(ram[off])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Inv Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, invbyte, RBYTE(ram[off]));
 			return RIO_FAIL;
 		}
 	}
@@ -1199,15 +1191,15 @@
 	*/
 	for (off=0; off<size; off+=2) {
 		if (*(ushort *)&ram[off] != invword) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Word Inv Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,invword,*(ushort *)&ram[off]));
-		rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Word Inv Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: WORD at offset 0x%x should have been=%x, was=%x\n", off, invword, *(ushort *)&ram[off]);
+		rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
 			return RIO_FAIL;
 		}
 
 		*(ushort *)&ram[off] = newword;
 		if ( *(ushort *)&ram[off] != newword ) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Word Check 1: WORD at offset 0x%x should have been=%x, was=%x\n",off,newword,*(ushort *)&ram[off]));
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Word Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, *(ushort *)&ram[off]);
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
 			return RIO_FAIL;
 		}
 	}
@@ -1219,15 +1211,15 @@
 	*/
 	for (off=0; off<size; off++) {
 		if (RBYTE(ram[off]) != newbyte) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Byte Check: BYTE at offset 0x%x should have been=%x, was=%x\n",off,newbyte,RBYTE(ram[off])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Byte Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, RBYTE(ram[off]));
 			return RIO_FAIL;
 		}
 	}
 
 	for (off=0; off<size; off+=2) {
 		if ( *(ushort *)&ram[off] != newword ) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Word Check 2: WORD at offset 0x%x should have been=%x, was=%x\n",off,newword,*(ushort *)&ram[off]));
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Word Check 2: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, *(ushort *)&ram[off]);
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
 			return RIO_FAIL;
 		}
 	}
@@ -1244,8 +1236,8 @@
 
 	for ( off=0; off<size; off+=2 ) {
 		if (*(ushort *)&ram[off] != swapword) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: SwapWord Check 1: WORD at offset 0x%x should have been=%x, was=%x\n",off,swapword,*((ushort *)&ram[off])));
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: SwapWord Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, swapword, *((ushort *)&ram[off]));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
 			return RIO_FAIL;
 		}
 		*((ushort *)&ram[off]) = ~swapword;
@@ -1253,11 +1245,11 @@
 
 	for (off=0; off<size; off+=2) {
 		if (RBYTE(ram[off]) != newbyte) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n",off,newbyte,RBYTE(ram[off])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, RBYTE(ram[off]));
 			return RIO_FAIL;
 		}
 		if (RBYTE(ram[off+1]) != invbyte) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n",off+1,invbyte,RBYTE(ram[off+1])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off+1, invbyte, RBYTE(ram[off+1]));
 			return RIO_FAIL;
 		}
 		*((ushort *)&ram[off]) = newword;
@@ -1384,14 +1376,14 @@
 
 	p->RIOPortp = (struct Port *)sysbrk(RIO_PORTS * sizeof(struct Port));
 	if (!p->RIOPortp) {
-		rio_dprint(RIO_DEBUG_INIT, ("RIO-init: No memory for port structures\n"));
+		rio_dprintk (RIO_DEBUG_INIT, "RIO-init: No memory for port structures\n");
 		p->RIOFailed++;
 		return;
 	} 
 	bzero( p->RIOPortp, sizeof(struct Port) * RIO_PORTS );
-	rio_dprint(RIO_DEBUG_INIT,  ("RIO-init: allocated and cleared memory for port structs\n") );
-	rio_dprint(RIO_DEBUG_INIT,  ("First RIO port struct @0x%x, size=0x%x bytes\n",
-	    (int)p->RIOPortp, sizeof(struct Port) ) );
+	rio_dprintk (RIO_DEBUG_INIT,  "RIO-init: allocated and cleared memory for port structs\n");
+	rio_dprintk (RIO_DEBUG_INIT,  "First RIO port struct @0x%x, size=0x%x bytes\n",
+	    (int)p->RIOPortp, sizeof(struct Port));
 
 	for( port=0; port<RIO_PORTS; port++ ) {
 		p->RIOPortp[port].PortNum = port;
@@ -1404,14 +1396,14 @@
 
 	p->RIOHosts = (struct Host *)sysbrk(RIO_HOSTS * sizeof(struct Host));
 	if (!p->RIOHosts) {
-		rio_dprint(RIO_DEBUG_INIT, ("RIO-init: No memory for host structures\n"));
+		rio_dprintk (RIO_DEBUG_INIT, "RIO-init: No memory for host structures\n");
 		p->RIOFailed++;
 		return;
 	}
 	bzero(p->RIOHosts, sizeof(struct Host)*RIO_HOSTS);
-	rio_dprint(RIO_DEBUG_INIT,  ("RIO-init: allocated and cleared memory for host structs\n"));
-	rio_dprint(RIO_DEBUG_INIT,  ("First RIO host struct @0x%x, size=0x%x bytes\n",
-	    (int)p->RIOHosts, sizeof(struct Host) ) );
+	rio_dprintk (RIO_DEBUG_INIT,  "RIO-init: allocated and cleared memory for host structs\n");
+	rio_dprintk (RIO_DEBUG_INIT,  "First RIO host struct @0x%x, size=0x%x bytes\n",
+	    (int)p->RIOHosts, sizeof(struct Host));
 
 	for( host=0; host<RIO_HOSTS; host++ ) {
 		spin_lock_init (&p->RIOHosts[host].HostLock);
@@ -1494,10 +1486,10 @@
 	char *	RIORelID = RELEASE_ID;
 	int		host;
 
-	rio_dprint(RIO_DEBUG_INIT, ("RIO : Release: %s ID: %s\n", RIORelease, RIORelID));
+	rio_dprintk (RIO_DEBUG_INIT, "RIO : Release: %s ID: %s\n", RIORelease, RIORelID);
 
 	if ( p->RIONumHosts==0 ) {
-		rio_dprint(RIO_DEBUG_INIT, ("\nNo Hosts configured\n"));
+		rio_dprintk (RIO_DEBUG_INIT, "\nNo Hosts configured\n");
 		return(0);
 	}
 
@@ -1505,7 +1497,7 @@
 		struct Host *HostP = &p->RIOHosts[host];
 		switch ( HostP->Type ) {
 			case RIO_AT:
-				rio_dprint(RIO_DEBUG_INIT, ("AT BUS : found the card at 0x%x\n", HostP->PaddrP));
+				rio_dprintk (RIO_DEBUG_INIT, "AT BUS : found the card at 0x%x\n", HostP->PaddrP);
 		}
 	}
 	return 0;
@@ -1587,17 +1579,17 @@
 	/*
 	** Reset the Tpu
 	*/
-	rio_dprint(RIO_DEBUG_INIT,  ("RIOHostReset: type 0x%x", Type ) );
+	rio_dprintk (RIO_DEBUG_INIT,  "RIOHostReset: type 0x%x", Type);
 	switch ( Type ) {
 		case RIO_AT:
-			rio_dprint(RIO_DEBUG_INIT, (" (RIO_AT)\n"));
+			rio_dprintk (RIO_DEBUG_INIT, " (RIO_AT)\n");
 			WBYTE(DpRamP->DpControl,  BOOT_FROM_RAM | EXTERNAL_BUS_OFF | 
 					  INTERRUPT_DISABLE | BYTE_OPERATION |
 					  SLOW_LINKS | SLOW_AT_BUS);
 			WBYTE(DpRamP->DpResetTpu, 0xFF);
 			rio_udelay (3);
 
-			rio_dprint(RIO_DEBUG_INIT,  ("RIOHostReset: Don't know if it worked. Try reset again\n") );
+			rio_dprintk (RIO_DEBUG_INIT,  "RIOHostReset: Don't know if it worked. Try reset again\n");
 			WBYTE(DpRamP->DpControl,  BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
 					  INTERRUPT_DISABLE | BYTE_OPERATION |
 					  SLOW_LINKS | SLOW_AT_BUS);
@@ -1630,7 +1622,7 @@
 		break;
 #endif
 	case RIO_PCI:
-		rio_dprint(RIO_DEBUG_INIT,  (" (RIO_PCI)\n") );
+		rio_dprintk (RIO_DEBUG_INIT, " (RIO_PCI)\n");
 		DpRamP->DpControl  = RIO_PCI_BOOT_FROM_RAM;
 		DpRamP->DpResetInt = 0xFF;
 		DpRamP->DpResetTpu = 0xFF;
@@ -1645,7 +1637,7 @@
 #endif
 
 	default:
-		rio_dprint(RIO_DEBUG_INIT,  (" (UNKNOWN)\n") );
+		rio_dprintk (RIO_DEBUG_INIT, " (UNKNOWN)\n");
 		break;
 	}
 	return;
diff -urN linux-2.2.17-pre15/drivers/char/rio/riointr.c linux/drivers/char/rio/riointr.c
--- linux-2.2.17-pre15/drivers/char/rio/riointr.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/char/rio/riointr.c	Mon Dec  3 22:10:50 2001
@@ -190,8 +190,8 @@
   tty = PortP->gs.tty;
 
 
-  rio_dprint (RIO_DEBUG_INTR, ("tx port %d: %d chars queued.\n", 
-	      PortP->PortNum, PortP->gs.xmit_cnt));
+  rio_dprintk (RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", 
+	      PortP->PortNum, PortP->gs.xmit_cnt);
 
   if (!PortP->gs.xmit_cnt) return;
   
@@ -215,10 +215,10 @@
     { int t;
     t = (c > 10)?10:c;
     
-    rio_dprint (RIO_DEBUG_INTR, ("tx port %d: copying %d chars: %s - %s\n", 
-				 PortP->PortNum, c, 
-	 firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail      , t),
-	 firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail + c-t, t)));
+    rio_dprintk (RIO_DEBUG_INTR, "rio: tx port %d: copying %d chars: %s - %s\n", 
+		 PortP->PortNum, c, 
+		 firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail      , t),
+		 firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail + c-t, t));
     }
     /* If for one reason or another, we can't copy more data, 
        we're done! */
@@ -244,14 +244,14 @@
   rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 
   if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2*PKT_MAX_DATA_LEN)) {
-    rio_dprint (RIO_DEBUG_INTR, ("Waking up.... ldisc:%d (%d/%d)....",
+    rio_dprintk (RIO_DEBUG_INTR, "Waking up.... ldisc:%d (%d/%d)....",
 		 (int)(PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)),
-		 PortP->gs.wakeup_chars, PortP->gs.xmit_cnt)); 
+		 PortP->gs.wakeup_chars, PortP->gs.xmit_cnt); 
     if ((PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 	PortP->gs.tty->ldisc.write_wakeup)
       (PortP->gs.tty->ldisc.write_wakeup)(PortP->gs.tty);
-    rio_dprint (RIO_DEBUG_INTR, ("(%d/%d)\n",
-		PortP->gs.wakeup_chars, PortP->gs.xmit_cnt)); 
+    rio_dprintk (RIO_DEBUG_INTR, "(%d/%d)\n",
+		PortP->gs.wakeup_chars, PortP->gs.xmit_cnt); 
     wake_up_interruptible(&PortP->gs.tty->write_wait);
   }
 
@@ -273,7 +273,7 @@
 	for ( host=0; host<p->RIONumHosts; host++ ) {
 		struct Host *HostP = &p->RIOHosts[host];
 
-		rio_dprint(RIO_DEBUG_INTR,  ("riointr() doing host %d type %d\n", host, HostP->Type ) );
+		rio_dprintk (RIO_DEBUG_INTR,  "riointr() doing host %d type %d\n", host, HostP->Type);
 
 		switch( HostP->Type ) {
 			case RIO_AT:
@@ -363,7 +363,7 @@
     static int t =0;
     rio_spin_unlock (&HostP->HostLock); 
     if ((t++ % 200) == 0)
-      rio_dprint(RIO_DEBUG_INTR, ("Interrupt but host not running. flags=%x.\n", (int)HostP->Flags));
+      rio_dprintk (RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int)HostP->Flags);
     return;
   }
   rio_spin_unlock (&HostP->HostLock); 
@@ -372,7 +372,7 @@
     WWORD( HostP->ParmMapP->rup_intr , 0 );
     p->RIORupCount++;
     RupIntr++;
-    rio_dprint(RIO_DEBUG_INTR, ("RUP interrupt on host %d\n", HostP-p->RIOHosts ));
+    rio_dprintk (RIO_DEBUG_INTR, "rio: RUP interrupt on host %d\n", HostP-p->RIOHosts);
     RIOPollHostCommands(p, HostP );
   }
 
@@ -383,7 +383,7 @@
     p->RIORxCount++;
     RxIntr++;
 
-    rio_dprint(RIO_DEBUG_INTR, ("RX interrupt on host %d\n", HostP-p->RIOHosts));
+    rio_dprintk (RIO_DEBUG_INTR, "rio: RX interrupt on host %d\n", HostP-p->RIOHosts);
     /*
     ** Loop through every port. If the port is mapped into
     ** the system ( i.e. has /dev/ttyXXXX associated ) then it is
@@ -451,7 +451,7 @@
 				** MAGIC! ( Basically, handshake the RX buffer, so that
 				** the RTAs upstream can be re-enabled. )
 				*/
-	rio_dprint(RIO_DEBUG_INTR, ("Set RX handshake bit\n" ));
+	rio_dprintk (RIO_DEBUG_INTR, "Set RX handshake bit\n");
 	WWORD( PortP->PhbP->handshake, 
 	       PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET );
       }
@@ -466,7 +466,7 @@
 
     p->RIOTxCount++;
     TxIntr++;
-    rio_dprint(RIO_DEBUG_INTR, ("TX interrupt on host %d\n", HostP-p->RIOHosts));
+    rio_dprintk (RIO_DEBUG_INTR, "rio: TX interrupt on host %d\n", HostP-p->RIOHosts);
 
     /*
     ** Loop through every port.
@@ -504,7 +504,7 @@
 	continue;
       }
 
-      rio_dprint (RIO_DEBUG_INTR, ("Looking into port %d.\n", port));
+      rio_dprintk (RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port);
       /*
       ** Lock the port before we begin working on it.
       */
@@ -515,7 +515,7 @@
       ** we need do none of this processing.
       */
       if ( !can_add_transmit( &PacketP, PortP ) ) {
-	rio_dprint (RIO_DEBUG_INTR, ("Can't add to port, so skipping.\n"));
+	rio_dprintk (RIO_DEBUG_INTR, "Can't add to port, so skipping.\n");
 	rio_spin_unlock(&PortP->portSem);
 	continue;
       }
@@ -527,7 +527,7 @@
       ttyP = PortP->gs.tty;
       /* If ttyP is NULL, the port is getting closed. Forget about it. */
       if (!ttyP) {
-	rio_dprint (RIO_DEBUG_INTR, ("no tty, so skipping.\n"));
+	rio_dprintk (RIO_DEBUG_INTR, "no tty, so skipping.\n");
 	rio_spin_unlock(&PortP->portSem);
 	continue;
       }
@@ -603,10 +603,10 @@
 	** with WFLUSH
 	*/
 	if ( PortP->WflushFlag ) {
-	  rio_dprint(RIO_DEBUG_INTR, ("Want to WFLUSH mark this port\n"));
+	  rio_dprintk (RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n");
 
 	  if ( PortP->InUse )
-	    rio_dprint(RIO_DEBUG_INTR, ("FAILS - PORT IS IN USE\n"));
+	    rio_dprintk (RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n");
 	}
 				
 	while ( PortP->WflushFlag &&
@@ -615,7 +615,7 @@
 	  int p;
 	  struct PktCmd *PktCmdP;
 
-	  rio_dprint(RIO_DEBUG_INTR, ("Add WFLUSH marker to data queue\n"));
+	  rio_dprintk (RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n");
 	  /*
 	  ** make it look just like a WFLUSH command
 	  */
@@ -670,8 +670,8 @@
 	    PortP->MagicFlags &= ~MAGIC_FLUSH;
 	  }
 
-	  rio_dprint(RIO_DEBUG_INTR, ("Wflush count now stands at %d\n", 
-		 PortP->WflushFlag));
+	  rio_dprintk (RIO_DEBUG_INTR, "Wflush count now stands at %d\n", 
+		 PortP->WflushFlag);
 	}
 	if ( PortP->MagicFlags & MORE_OUTPUT_EYGOR ) {
 	  if ( PortP->MagicFlags & MAGIC_FLUSH ) {
@@ -747,12 +747,12 @@
 
   TtyP = PortP->gs.tty;
   if (!TtyP) {
-    rio_dprint (RIO_DEBUG_INTR, ("RIOReceive: tty is null. \n"));
+    rio_dprintk (RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");
     return;
   }
 
   if (PortP->State & RIO_THROTTLE_RX) {
-    rio_dprint (RIO_DEBUG_INTR, ("RIOReceive: Throttled. Can't handle more input.\n"));
+    rio_dprintk (RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n");
     return;
   }
 
@@ -786,18 +786,18 @@
 	  ** check that it is not a command!
 	  */
 	  if ( PacketP->len & PKT_CMD_BIT ) {
-	    rio_dprint(RIO_DEBUG_INTR, ("RIO: unexpected command packet received on PHB\n"));
+	    rio_dprintk (RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");
 	    /*	    rio_dprint(RIO_DEBUG_INTR, (" sysport   = %d\n", p->RIOPortp->PortNum)); */
-	    rio_dprint(RIO_DEBUG_INTR, (" dest_unit = %d\n", PacketP->dest_unit));
-	    rio_dprint(RIO_DEBUG_INTR, (" dest_port = %d\n", PacketP->dest_port));
-	    rio_dprint(RIO_DEBUG_INTR, (" src_unit  = %d\n", PacketP->src_unit));
-	    rio_dprint(RIO_DEBUG_INTR, (" src_port  = %d\n", PacketP->src_port));
-	    rio_dprint(RIO_DEBUG_INTR, (" len	   = %d\n", PacketP->len));
-	    rio_dprint(RIO_DEBUG_INTR, (" control   = %d\n", PacketP->control));
-	    rio_dprint(RIO_DEBUG_INTR, (" csum	   = %d\n", PacketP->csum));
-	    rio_dprint(RIO_DEBUG_INTR, ("	 data bytes: "));
+	    rio_dprintk (RIO_DEBUG_INTR, " dest_unit = %d\n", PacketP->dest_unit);
+	    rio_dprintk (RIO_DEBUG_INTR, " dest_port = %d\n", PacketP->dest_port);
+	    rio_dprintk (RIO_DEBUG_INTR, " src_unit  = %d\n", PacketP->src_unit);
+	    rio_dprintk (RIO_DEBUG_INTR, " src_port  = %d\n", PacketP->src_port);
+	    rio_dprintk (RIO_DEBUG_INTR, " len	   = %d\n", PacketP->len);
+	    rio_dprintk (RIO_DEBUG_INTR, " control   = %d\n", PacketP->control);
+	    rio_dprintk (RIO_DEBUG_INTR, " csum	   = %d\n", PacketP->csum);
+	    rio_dprintk (RIO_DEBUG_INTR, "	 data bytes: ");
 	    for ( DataCnt=0; DataCnt<PKT_MAX_DATA_LEN; DataCnt++ )
-	      rio_dprint(RIO_DEBUG_INTR, ("%d\n", PacketP->data[DataCnt]));
+	      rio_dprintk (RIO_DEBUG_INTR, "%d\n", PacketP->data[DataCnt]);
 	    remove_receive( PortP );
 	    put_free_end( PortP->HostP, PacketP );
 	    continue; /* with next packet */
@@ -820,8 +820,8 @@
 			
 	  transCount = min(PacketP->len & PKT_LEN_MASK,
 			   TTY_FLIPBUF_SIZE - TtyP->flip.count);
-	  rio_dprint(RIO_DEBUG_REC,  ("port %d: Copy %d bytes\n", 
-				      PortP->PortNum, transCount ) );
+	  rio_dprintk (RIO_DEBUG_REC,  "port %d: Copy %d bytes\n", 
+				      PortP->PortNum, transCount);
 	  /*
 	  ** To use the following 'kkprintfs' for debugging - change the '#undef'
 	  ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the
@@ -880,7 +880,7 @@
 	}
     }
   if (copied) {
-    rio_dprint ( RIO_DEBUG_REC, ("port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum,  copied));
+    rio_dprintk (RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied);
     tty_flip_buffer_push (TtyP);
   }
 
@@ -906,25 +906,25 @@
 	SysPort = port;	/* Believe me, it works. */
 
 	if ( SysPort < 0 || SysPort >= RIO_PORTS ) {
-		rio_dprint(RIO_DEBUG_INTR, ("Illegal port %d derived from TTY in riotproc()\n",SysPort));
+		rio_dprintk (RIO_DEBUG_INTR, "Illegal port %d derived from TTY in riotproc()\n",SysPort);
 		return 0;
 	}
 	PortP = p->RIOPortp[SysPort];
 
 	if ((uint)PortP->PhbP < (uint)PortP->Caddr || 
 			(uint)PortP->PhbP >= (uint)PortP->Caddr+SIXTY_FOUR_K ) {
-		rio_dprint(RIO_DEBUG_INTR, ("RIO: NULL or BAD PhbP on sys port %d in proc routine\n",
-							SysPort));
-		rio_dprint(RIO_DEBUG_INTR, ("	 PortP = 0x%x\n",PortP));
-		rio_dprint(RIO_DEBUG_INTR, ("	 PortP->PhbP = 0x%x\n",PortP->PhbP));
-		rio_dprint(RIO_DEBUG_INTR, ("	 PortP->Caddr = 0x%x\n",PortP->PhbP));
-		rio_dprint(RIO_DEBUG_INTR, ("	 PortP->HostPort = 0x%x\n",PortP->HostPort));
+		rio_dprintk (RIO_DEBUG_INTR, "RIO: NULL or BAD PhbP on sys port %d in proc routine\n",
+							SysPort);
+		rio_dprintk (RIO_DEBUG_INTR, "	 PortP = 0x%x\n",PortP);
+		rio_dprintk (RIO_DEBUG_INTR, "	 PortP->PhbP = 0x%x\n",PortP->PhbP);
+		rio_dprintk (RIO_DEBUG_INTR, "	 PortP->Caddr = 0x%x\n",PortP->PhbP);
+		rio_dprintk (RIO_DEBUG_INTR, "	 PortP->HostPort = 0x%x\n",PortP->HostPort);
 		return 0;
 	}
 
 	switch(cmd) {
 		case T_WFLUSH:
-			rio_dprint(RIO_DEBUG_INTR, "T_WFLUSH\n");
+			rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH\n");
 			/*
 			** Because of the spooky way the RIO works, we don't need
 			** to issue a flush command on any of the SET*F commands,
@@ -941,14 +941,14 @@
 				** form a wflush packet - 1 byte long, no data
 				*/
 				if ( PortP->State & RIO_DELETED ) {
-					rio_dprint(RIO_DEBUG_INTR, ("WFLUSH on deleted RTA\n"));
+					rio_dprintk (RIO_DEBUG_INTR, "WFLUSH on deleted RTA\n");
 				}
 				else {
 					if ( RIOPreemptiveCmd(p, PortP, WFLUSH ) == RIO_FAIL ) {
-						rio_dprint(RIO_DEBUG_INTR, ("T_WFLUSH Command failed\n"));
+						rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command failed\n");
 					}
 					else
-						rio_dprint(RIO_DEBUG_INTR, ("T_WFLUSH Command\n"));
+						rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command\n");
 				}
 				/*
 				** WFLUSH operation - flush the data!
@@ -956,7 +956,7 @@
 				PortP->TxBufferIn = PortP->TxBufferOut = 0;
 			}
 			else {
-				rio_dprint(RIO_DEBUG_INTR, ("T_WFLUSH Command ignored\n"));
+				rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command ignored\n");
 			}
 			/*
 			** sort out the line discipline
@@ -966,16 +966,16 @@
 			break;
 	
 		case T_RESUME:
-			rio_dprint(RIO_DEBUG_INTR, ("T_RESUME\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_RESUME\n");
 			/*
 			** send pre-emptive resume packet
 			*/
 			if ( PortP->State & RIO_DELETED ) {
-				rio_dprint(RIO_DEBUG_INTR, ("RESUME on deleted RTA\n"));
+				rio_dprintk (RIO_DEBUG_INTR, "RESUME on deleted RTA\n");
 			}
 			else {
 				if ( RIOPreemptiveCmd(p, PortP, RESUME ) == RIO_FAIL ) {
-					rio_dprint(RIO_DEBUG_INTR, ("T_RESUME Command failed\n"));
+					rio_dprintk (RIO_DEBUG_INTR, "T_RESUME Command failed\n");
 				}
 			}
 			/*
@@ -986,7 +986,7 @@
 			break;
 	
 		case T_TIME:
-			rio_dprint(RIO_DEBUG_INTR, ("T_TIME\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_TIME\n");
 			/*
 			** T_TIME is called when xDLY is set in oflags and
 			** the line discipline timeout has expired. It's
@@ -1008,16 +1008,16 @@
 			break;
 	
 		case T_SUSPEND:
-			rio_dprint(RIO_DEBUG_INTR, ("T_SUSPEND\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_SUSPEND\n");
 			/*
 			** send a suspend pre-emptive packet.
 			*/
 			if ( PortP->State & RIO_DELETED ) {
-				rio_dprint(RIO_DEBUG_INTR, ("SUSPEND deleted RTA\n"));
+				rio_dprintk (RIO_DEBUG_INTR, "SUSPEND deleted RTA\n");
 			}
 			else {
 				if ( RIOPreemptiveCmd(p, PortP, SUSPEND ) == RIO_FAIL ) {
-					rio_dprint(RIO_DEBUG_INTR, ("T_SUSPEND Command failed\n"));
+					rio_dprintk (RIO_DEBUG_INTR, "T_SUSPEND Command failed\n");
 				}
 			}
 			/*
@@ -1026,18 +1026,18 @@
 			break;
 	
 		case T_BLOCK:
-			rio_dprint(RIO_DEBUG_INTR, ("T_BLOCK\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_BLOCK\n");
 			break;
 	
 		case T_RFLUSH:
-			rio_dprint(RIO_DEBUG_INTR, ("T_RFLUSH\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_RFLUSH\n");
 			if ( PortP->State & RIO_DELETED ) {
-				rio_dprint(RIO_DEBUG_INTR, ("RFLUSH on deleted RTA\n"));
+				rio_dprintk (RIO_DEBUG_INTR, "RFLUSH on deleted RTA\n");
 				PortP->RxDataStart = 0;
 			}
 			else {
 				if ( RIOPreemptiveCmd( p, PortP, RFLUSH ) == RIO_FAIL ) {
-					rio_dprint(RIO_DEBUG_INTR, ("T_RFLUSH Command failed\n"));
+					rio_dprintk (RIO_DEBUG_INTR, "T_RFLUSH Command failed\n");
 					return 0;
 				}
 				PortP->RxDataStart = 0;
@@ -1050,14 +1050,14 @@
 					/*
 					** MAGIC!
 					*/
-					rio_dprint(RIO_DEBUG_INTR, ("Set receive handshake bit\n"));
+					rio_dprintk (RIO_DEBUG_INTR, "Set receive handshake bit\n");
 					PortP->PhbP->handshake |= PHB_HANDSHAKE_RESET;
 				}
 			}
 			break;
 			/* FALLTHROUGH */
 		case T_UNBLOCK:
-			rio_dprint(RIO_DEBUG_INTR, ("T_UNBLOCK\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_UNBLOCK\n");
 			/*
 			** If there is any data to receive set a timeout to service it.
 			*/
@@ -1065,7 +1065,7 @@
 			break;
 	
 		case T_BREAK:
-			rio_dprint(RIO_DEBUG_INTR, ("T_BREAK\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_BREAK\n");
 			/*
 			** Send a break command. For Sys V
 			** this is a timed break, so we
@@ -1075,12 +1075,12 @@
 			** Build a BREAK command
 			*/
 			if ( PortP->State & RIO_DELETED ) {
-				rio_dprint(RIO_DEBUG_INTR, ("BREAK on deleted RTA\n"));
+				rio_dprintk (RIO_DEBUG_INTR, "BREAK on deleted RTA\n");
 			}
 			else {
 				if (RIOShortCommand(PortP,SBREAK,2,
 								p->RIOConf.BreakInterval)==RIO_FAIL) {
-			   		rio_dprint(RIO_DEBUG_INTR, ("SBREAK RIOShortCommand failed\n"));
+			   		rio_dprintk (RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n");
 				}
 			}
 	
@@ -1090,18 +1090,18 @@
 			break;
 	
 		case T_INPUT:
-			rio_dprint(RIO_DEBUG_INTR, ("Proc T_INPUT called - I don't know what to do!\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "Proc T_INPUT called - I don't know what to do!\n");
 			break;
 		case T_PARM:
-			rio_dprint(RIO_DEBUG_INTR, ("Proc T_PARM called - I don't know what to do!\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "Proc T_PARM called - I don't know what to do!\n");
 			break;
 	
 		case T_SWTCH:
-			rio_dprint(RIO_DEBUG_INTR, ("Proc T_SWTCH called - I don't know what to do!\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "Proc T_SWTCH called - I don't know what to do!\n");
 			break;
 	
 		default:
-			rio_dprint(RIO_DEBUG_INTR, ("Proc UNKNOWN command %d\n",cmd));
+			rio_dprintk (RIO_DEBUG_INTR, "Proc UNKNOWN command %d\n",cmd);
 	}
 	/*
 	** T_OUTPUT returns without passing through this point!
diff -urN linux-2.2.17-pre15/drivers/char/rio/rioparam.c linux/drivers/char/rio/rioparam.c
--- linux-2.2.17-pre15/drivers/char/rio/rioparam.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/char/rio/rioparam.c	Mon Dec  3 22:10:50 2001
@@ -176,13 +176,18 @@
 	int		retries = 0xff;
 	unsigned long flags;
 
+	func_enter ();
+
 	TtyP = PortP->gs.tty;
 
-	rio_dprint(RIO_DEBUG_PARAM, ("RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n",
-	    PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP) );
+	rio_dprintk (RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n",
+	    PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP);
 
 	if (!TtyP) {
-	  rio_dprint (RIO_DEBUG_PARAM, ("Can't call rioparam with null tty.\n"));
+	  rio_dprintk (RIO_DEBUG_PARAM, "Can't call rioparam with null tty.\n");
+
+	  func_exit ();
+
 	  return RIO_FAIL;
 	}
 	rio_spin_lock_irqsave(&PortP->portSem, flags );
@@ -205,7 +210,7 @@
 			PortP->FirstOpen = 0;
 		}
 		else if (PortP->Store || PortP->Lock) {
-			rio_dprint(RIO_DEBUG_PARAM, ("OPEN: Restoring stored/locked params\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "OPEN: Restoring stored/locked params\n");
 			TtyP->tm.c_iflag = PortP->StoredTty.iflag;
 			TtyP->tm.c_oflag = PortP->StoredTty.oflag;
 			TtyP->tm.c_cflag = PortP->StoredTty.cflag;
@@ -226,41 +231,49 @@
 			break;
 		}
 		if ( PortP->InUse != NOT_INUSE ) {
-			rio_dprint(RIO_DEBUG_PARAM, ("Port IN_USE for pre-emptive command\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "Port IN_USE for pre-emptive command\n");
 		}
 
 		if ( !res ) {
-			rio_dprint(RIO_DEBUG_PARAM, ("Port has no space on transmit queue\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "Port has no space on transmit queue\n");
 		}
 
 		if ( SleepFlag != OK_TO_SLEEP ) {
 			rio_spin_unlock_irqrestore( &PortP->portSem, flags);
+			func_exit();
+			
 			return RIO_FAIL;
 		}
 
-		rio_dprint(RIO_DEBUG_PARAM, ("wait for can_add_transmit\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "wait for can_add_transmit\n");
 		rio_spin_unlock_irqrestore( &PortP->portSem, flags);
 		retval = RIODelay(PortP, HUNDRED_MS);
 		rio_spin_lock_irqsave( &PortP->portSem, flags);
 		if (retval == RIO_FAIL) {
-			rio_dprint(RIO_DEBUG_PARAM, ("wait for can_add_transmit broken by signal\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "wait for can_add_transmit broken by signal\n");
 			rio_spin_unlock_irqrestore( &PortP->portSem, flags);
 			pseterr(EINTR);
+			func_exit();
+
 			return RIO_FAIL;
 		}
 		if ( PortP->State & RIO_DELETED ) {
 			rio_spin_unlock_irqrestore( &PortP->portSem, flags);
+			func_exit ();
+
 			return RIO_SUCCESS;
 		}
 	}
 
 	if (!res) {
 		rio_spin_unlock_irqrestore( &PortP->portSem, flags);
+		func_exit ();
+
 		return RIO_FAIL;
 	}
 
-	rio_dprint(RIO_DEBUG_PARAM, ("can_add_transmit() returns %x\n",res));
-	rio_dprint(RIO_DEBUG_PARAM, ("Packet is 0x%x\n",(int) PacketP));
+	rio_dprintk (RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n",res);
+	rio_dprintk (RIO_DEBUG_PARAM, "Packet is 0x%x\n",(int) PacketP);
 
 	phb_param_ptr = (struct phb_param *)PacketP->data;
 
@@ -270,7 +283,7 @@
 	** COR 1
 	*/
 	if ( TtyP->tm.c_iflag & INPCK ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Parity checking on input enabled\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Parity checking on input enabled\n");
 		Cor1 |= COR1_INPCK;
 	}
 #endif
@@ -278,53 +291,53 @@
 	switch ( TtyP->termios->c_cflag & CSIZE ) {
 		case CS5:
 		{
-			rio_dprint(RIO_DEBUG_PARAM, ("5 bit data\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "5 bit data\n");
 			Cor1 |= COR1_5BITS;
 			break;
 		}
 		case CS6:
 		{
-			rio_dprint(RIO_DEBUG_PARAM, ("6 bit data\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "6 bit data\n");
 			Cor1 |= COR1_6BITS;
 			break;
 		}
 		case CS7:
 		{
-			rio_dprint(RIO_DEBUG_PARAM, ("7 bit data\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "7 bit data\n");
 			Cor1 |= COR1_7BITS;
 			break;
 		}
 		case CS8:
 		{
-			rio_dprint(RIO_DEBUG_PARAM, ("8 bit data\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "8 bit data\n");
 			Cor1 |= COR1_8BITS;
 			break;
 		}
 	}
 
 	if ( TtyP->termios->c_cflag & CSTOPB ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("2 stop bits\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "2 stop bits\n");
 		Cor1 |= COR1_2STOP;
 	}
 	else {
-		rio_dprint(RIO_DEBUG_PARAM, ("1 stop bit\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "1 stop bit\n");
 		Cor1 |= COR1_1STOP;
 	}
 
 	if ( TtyP->termios->c_cflag & PARENB ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable parity\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable parity\n");
 		Cor1 |= COR1_NORMAL;
 	}
 	else {
-		rio_dprint(RIO_DEBUG_PARAM, ("Disable parity\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Disable parity\n");
 		Cor1 |= COR1_NOP;
 	}
 	if ( TtyP->termios->c_cflag & PARODD ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Odd parity\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Odd parity\n");
 		Cor1 |= COR1_ODD;
 	}
 	else {
-		rio_dprint(RIO_DEBUG_PARAM, ("Even parity\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Even parity\n");
 		Cor1 |= COR1_EVEN; 
 	}
 
@@ -332,89 +345,89 @@
 	** COR 2
 	*/
 	if ( TtyP->termios->c_iflag & IXON ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable start/stop output control\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable start/stop output control\n");
 		Cor2 |= COR2_IXON;
 	}
 	else {
 		if ( PortP->Config & RIO_IXON ) {
-			rio_dprint(RIO_DEBUG_PARAM, ("Force enable start/stop output control\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "Force enable start/stop output control\n");
 			Cor2 |= COR2_IXON;
 		}
 		else
-			rio_dprint(RIO_DEBUG_PARAM, ("IXON has been disabled.\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "IXON has been disabled.\n");
 	}
 
 	if (TtyP->termios->c_iflag & IXANY) {
 		if ( PortP->Config & RIO_IXANY ) {
-			rio_dprint(RIO_DEBUG_PARAM, ("Enable any key to restart output\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "Enable any key to restart output\n");
 			Cor2 |= COR2_IXANY;
 		}
 		else
-			rio_dprint(RIO_DEBUG_PARAM, ("IXANY has been disabled due to sanity reasons.\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n");
 	}
 
 	if ( TtyP->termios->c_iflag & IXOFF ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable start/stop input control 2\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable start/stop input control 2\n");
 		Cor2 |= COR2_IXOFF;
 	}
 
 	if ( TtyP->termios->c_cflag & HUPCL ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Hangup on last close\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Hangup on last close\n");
 		Cor2 |= COR2_HUPCL;
 	}
 
 	if ( C_CRTSCTS (TtyP)) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Rx hardware flow control enabled\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n");
 		Cor2 |= COR2_CTSFLOW;
 		Cor2 |= COR2_RTSFLOW;
 	} else {
-		rio_dprint(RIO_DEBUG_PARAM, ("Rx hardware flow control disabled\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n");
 		Cor2 &= ~COR2_CTSFLOW;
 		Cor2 &= ~COR2_RTSFLOW;
 	}
 
 
 	if ( TtyP->termios->c_cflag & CLOCAL ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Local line\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Local line\n");
 	}
 	else {
-		rio_dprint(RIO_DEBUG_PARAM, ("Possible Modem line\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Possible Modem line\n");
 	}
 
 	/*
 	** COR 4 (there is no COR 3)
 	*/
 	if ( TtyP->termios->c_iflag & IGNBRK ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Ignore break condition\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Ignore break condition\n");
 		Cor4 |= COR4_IGNBRK;
 	}
 	if ( !(TtyP->termios->c_iflag & BRKINT) ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Break generates NULL condition\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Break generates NULL condition\n");
 		Cor4 |= COR4_NBRKINT;
 	} else {
-		rio_dprint(RIO_DEBUG_PARAM, ("Interrupt on	break condition\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Interrupt on	break condition\n");
 	}
 
 	if ( TtyP->termios->c_iflag & INLCR ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Map newline to carriage return on input\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Map newline to carriage return on input\n");
 		Cor4 |= COR4_INLCR;
 	}
 
 	if ( TtyP->termios->c_iflag & IGNCR ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Ignore carriage return on input\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Ignore carriage return on input\n");
 		Cor4 |= COR4_IGNCR;
 	}
 
 	if ( TtyP->termios->c_iflag & ICRNL ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Map carriage return to newline on input\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Map carriage return to newline on input\n");
 		Cor4 |= COR4_ICRNL;
 	}
 	if ( TtyP->termios->c_iflag & IGNPAR ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Ignore characters with parity errors\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Ignore characters with parity errors\n");
 		Cor4 |= COR4_IGNPAR;
 	}
 	if ( TtyP->termios->c_iflag & PARMRK ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Mark parity errors\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Mark parity errors\n");
 		Cor4 |= COR4_PARMRK;
 	}
 
@@ -444,24 +457,24 @@
 	** Could set LNE here if you wanted LNext processing. SVR4 will use it.
 	*/
 	if ( TtyP->termios->c_iflag & ISTRIP ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Strip input characters\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Strip input characters\n");
 		if (! (PortP->State & RIO_TRIAD_MODE)) {
 			Cor5 |= COR5_ISTRIP;
 		}
 	}
 
 	if ( TtyP->termios->c_oflag & ONLCR ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Map newline to carriage-return, newline on output\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n");
 		if ( PortP->CookMode == COOK_MEDIUM )
 			Cor5 |= COR5_ONLCR;
 	}
 	if ( TtyP->termios->c_oflag & OCRNL ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Map carriage return to newline on output\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Map carriage return to newline on output\n");
 		if ( PortP->CookMode == COOK_MEDIUM )
 			Cor5 |= COR5_OCRNL;
 	}
 	if ( ( TtyP->termios->c_oflag & TABDLY) == TAB3 ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Tab delay 3 set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Tab delay 3 set\n");
 		if ( PortP->CookMode == COOK_MEDIUM )
 			Cor5 |= COR5_TAB3;
 	}
@@ -481,8 +494,8 @@
 	/*
 	** Baud rate bytes
 	*/
-	rio_dprint(RIO_DEBUG_PARAM, ("Mapping of rx/tx baud %x (%x)\n", 
-				     TtyP->termios->c_cflag, CBAUD));
+	rio_dprintk (RIO_DEBUG_PARAM, "Mapping of rx/tx baud %x (%x)\n", 
+				     TtyP->termios->c_cflag, CBAUD);
 
 	switch (TtyP->termios->c_cflag & CBAUD) {
 #define e(b) case B ## b : RxBaud = TxBaud = RIO_B ## b ;break
@@ -494,77 +507,77 @@
 	/* XXX MIssing conversion table. XXX */
 	/* 	 (TtyP->termios->c_cflag & V_CBAUD); */
 
-	rio_dprint(RIO_DEBUG_PARAM, ("tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud));
+	rio_dprintk (RIO_DEBUG_PARAM, "tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud);
 
 
 	/*
 	** Leftovers
 	*/
 	if ( TtyP->termios->c_cflag & CREAD )
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable receiver\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable receiver\n");
 #ifdef RCV1EN
 	if ( TtyP->termios->c_cflag & RCV1EN )
-		rio_dprint(RIO_DEBUG_PARAM, ("RCV1EN (?)\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "RCV1EN (?)\n");
 #endif
 #ifdef XMT1EN
 	if ( TtyP->termios->c_cflag & XMT1EN )
-		rio_dprint(RIO_DEBUG_PARAM, ("XMT1EN (?)\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "XMT1EN (?)\n");
 #endif
 #if 0
 	if ( TtyP->termios->c_cflag & LOBLK )
-		rio_dprint(RIO_DEBUG_PARAM, ("LOBLK - JCL output blocks when not current\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "LOBLK - JCL output blocks when not current\n");
 #endif
 	if ( TtyP->termios->c_lflag & ISIG )
-		rio_dprint(RIO_DEBUG_PARAM, ("Input character signal generating enabled\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Input character signal generating enabled\n");
 	if ( TtyP->termios->c_lflag & ICANON )
-		rio_dprint(RIO_DEBUG_PARAM, ("Canonical input: erase and kill enabled\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Canonical input: erase and kill enabled\n");
 	if ( TtyP->termios->c_lflag & XCASE )
-		rio_dprint(RIO_DEBUG_PARAM, ("Canonical upper/lower presentation\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Canonical upper/lower presentation\n");
 	if ( TtyP->termios->c_lflag & ECHO )
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable input echo\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable input echo\n");
 	if ( TtyP->termios->c_lflag & ECHOE )
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable echo erase\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable echo erase\n");
 	if ( TtyP->termios->c_lflag & ECHOK )
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable echo kill\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable echo kill\n");
 	if ( TtyP->termios->c_lflag & ECHONL )
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable echo newline\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable echo newline\n");
 	if ( TtyP->termios->c_lflag & NOFLSH )
-		rio_dprint(RIO_DEBUG_PARAM, ("Disable flush after interrupt or quit\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Disable flush after interrupt or quit\n");
 #ifdef TOSTOP
 	if ( TtyP->termios->c_lflag & TOSTOP )
-		rio_dprint(RIO_DEBUG_PARAM, ("Send SIGTTOU for background output\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Send SIGTTOU for background output\n");
 #endif
 #ifdef XCLUDE
 	if ( TtyP->termios->c_lflag & XCLUDE )
-		rio_dprint(RIO_DEBUG_PARAM, ("Exclusive use of this line\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Exclusive use of this line\n");
 #endif
 	if ( TtyP->termios->c_iflag & IUCLC )
-		rio_dprint(RIO_DEBUG_PARAM, ("Map uppercase to lowercase on input\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Map uppercase to lowercase on input\n");
 	if ( TtyP->termios->c_oflag & OPOST )
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable output post-processing\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable output post-processing\n");
 	if ( TtyP->termios->c_oflag & OLCUC )
-		rio_dprint(RIO_DEBUG_PARAM, ("Map lowercase to uppercase on output\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Map lowercase to uppercase on output\n");
 	if ( TtyP->termios->c_oflag & ONOCR )
-		rio_dprint(RIO_DEBUG_PARAM, ("No carriage return output at column 0\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "No carriage return output at column 0\n");
 	if ( TtyP->termios->c_oflag & ONLRET )
-		rio_dprint(RIO_DEBUG_PARAM, ("Newline performs carriage return function\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Newline performs carriage return function\n");
 	if ( TtyP->termios->c_oflag & OFILL )
-		rio_dprint(RIO_DEBUG_PARAM, ("Use fill characters for delay\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Use fill characters for delay\n");
 	if ( TtyP->termios->c_oflag & OFDEL )
-		rio_dprint(RIO_DEBUG_PARAM, ("Fill character is DEL\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Fill character is DEL\n");
 	if ( TtyP->termios->c_oflag & NLDLY )
-		rio_dprint(RIO_DEBUG_PARAM, ("Newline delay set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Newline delay set\n");
 	if ( TtyP->termios->c_oflag & CRDLY )
-		rio_dprint(RIO_DEBUG_PARAM, ("Carriage return delay set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Carriage return delay set\n");
 	if ( TtyP->termios->c_oflag & TABDLY )
-		rio_dprint(RIO_DEBUG_PARAM, ("Tab delay set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Tab delay set\n");
 #if 0
 	if ( TtyP->termios->c_oflag & BSDLY )
-		rio_dprint(RIO_DEBUG_PARAM, ("Back-space delay set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Back-space delay set\n");
 	if ( TtyP->termios->c_oflag & VTDLY )
-		rio_dprint(RIO_DEBUG_PARAM, ("Vertical tab delay set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Vertical tab delay set\n");
 	if ( TtyP->termios->c_oflag & FFDLY )
-		rio_dprint(RIO_DEBUG_PARAM, ("Form-feed delay set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Form-feed delay set\n");
 #endif
 	/*
 	** These things are kind of useful in a later life!
@@ -573,6 +586,8 @@
 
 	if ( PortP->State & RIO_DELETED ) {
 		rio_spin_unlock_irqrestore( &PortP->portSem, flags);
+		func_exit ();
+
 		return RIO_FAIL;
 	}
 
@@ -610,10 +625,12 @@
 
 	rio_spin_unlock_irqrestore( &PortP->portSem, flags);
 
-	rio_dprint(RIO_DEBUG_PARAM, ("add_transmit returned.\n"));
+	rio_dprintk (RIO_DEBUG_PARAM, "add_transmit returned.\n");
 	/*
 	** job done.
 	*/
+	func_exit ();
+
 	return RIO_SUCCESS;
 }
 
@@ -644,7 +661,7 @@
 struct Port *PortP; 
 {
   if (RWORD(*PortP->TxAdd) & PKT_IN_USE) {
-    rio_dprint (RIO_DEBUG_PARAM, ("add_transmit: Packet has been stolen!"));
+    rio_dprintk (RIO_DEBUG_PARAM, "add_transmit: Packet has been stolen!");
   }
 	WWORD( *(ushort *)PortP->TxAdd, RWORD(*PortP->TxAdd) | PKT_IN_USE);
 	PortP->TxAdd = (PortP->TxAdd == PortP->TxEnd) ? PortP->TxStart : 
@@ -672,7 +689,7 @@
 	*
 	************************************************/
 
-	rio_dprint(RIO_DEBUG_PFE, ("put_free_end(PktP=%x)\n",(int)PktP));
+	rio_dprintk (RIO_DEBUG_PFE,  "put_free_end(PktP=%x)\n",(int)PktP);
 
 	if ((old_end=RWORD(HostP->ParmMapP->free_list_end)) != TPNULL) {
 		new_end = RIO_OFF(HostP->Caddr,PktP);
@@ -683,12 +700,13 @@
 		WWORD(HostP->ParmMapP->free_list_end, new_end);
 	}
 	else {	/* First packet on the free list this should never happen! */
-		rio_dprint(RIO_DEBUG_PFE, ("put_free_end(): This should never happen\n"));
+		rio_dprintk (RIO_DEBUG_PFE, "put_free_end(): This should never happen\n");
 		WWORD(HostP->ParmMapP->free_list_end , RIO_OFF(HostP->Caddr,PktP));
 		tmp_pointer = (FREE_LIST *)PktP;
 		WWORD(tmp_pointer->prev , TPNULL);
 		WWORD(tmp_pointer->next , TPNULL);
 	}
+	rio_dprintk (RIO_DEBUG_CMD, "Before unlock: %p\n", &HostP->HostLock);
 	rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
 }
 
diff -urN linux-2.2.17-pre15/drivers/char/rio/rioroute.c linux/drivers/char/rio/rioroute.c
--- linux-2.2.17-pre15/drivers/char/rio/rioroute.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/char/rio/rioroute.c	Mon Dec  3 22:10:50 2001
@@ -178,8 +178,8 @@
 
     if ( Lies )
     {
-      rio_dprint(RIO_DEBUG_ROUTE, ("LIES! DAMN LIES! %d LIES!\n",Lies));
-      rio_dprint(RIO_DEBUG_ROUTE, ("%d:%c %d:%c %d:%c %d:%c\n",
+      rio_dprintk (RIO_DEBUG_ROUTE, "LIES! DAMN LIES! %d LIES!\n",Lies);
+      rio_dprintk (RIO_DEBUG_ROUTE, "%d:%c %d:%c %d:%c %d:%c\n",
           RBYTE(PktCmdP->RouteTopology[0].Unit), 
 	  'A'+RBYTE(PktCmdP->RouteTopology[0].Link),
           RBYTE(PktCmdP->RouteTopology[1].Unit),
@@ -187,7 +187,7 @@
           RBYTE(PktCmdP->RouteTopology[2].Unit),
 	  'A'+RBYTE(PktCmdP->RouteTopology[2].Link),
           RBYTE(PktCmdP->RouteTopology[3].Unit),
-	  'A'+RBYTE(PktCmdP->RouteTopology[3].Link)));
+	  'A'+RBYTE(PktCmdP->RouteTopology[3].Link));
       return TRUE;
     }
 
@@ -219,11 +219,11 @@
 	     NewUnit != ROUTE_NO_ID &&
 	     NewUnit != ROUTE_INTERCONNECT )
 	{
-	    rio_dprint(RIO_DEBUG_ROUTE, ("I have a link from %s %s to unit %d:%d - I don't like it.\n",
+	    rio_dprintk (RIO_DEBUG_ROUTE, "I have a link from %s %s to unit %d:%d - I don't like it.\n",
 		  MyType,
 		  MyName,
 		  NewUnit,
-		  NewLink));
+		  NewLink);
 	}
 	else
 	{
@@ -248,8 +248,8 @@
 	    RIOConCon(p,HostP,ThisUnit,ThisLink,NewUnit,NewLink,CONNECT);
 
 	  if ( NewUnit == ROUTE_NO_ID )
-	    rio_dprint(RIO_DEBUG_ROUTE, ("%s %s (%c) is connected to an unconfigured unit.\n",
-		    MyType,MyName,'A'+ThisLink));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "%s %s (%c) is connected to an unconfigured unit.\n",
+		    MyType,MyName,'A'+ThisLink);
 
 	  if ( NewUnit == ROUTE_INTERCONNECT )
 	  {
@@ -267,14 +267,14 @@
 	    if ( HostP->Topology[OldLink].Unit == ThisUnit &&
 		 HostP->Topology[OldLink].Link == ThisLink )
 	    {
-	      rio_dprint(RIO_DEBUG_ROUTE, ("SETTING HOST (%c) TO DISCONNECTED!\n", OldLink+'A'));
+	      rio_dprintk (RIO_DEBUG_ROUTE, "SETTING HOST (%c) TO DISCONNECTED!\n", OldLink+'A');
 	      HostP->Topology[OldLink].Unit = ROUTE_DISCONNECT;
 	      HostP->Topology[OldLink].Link = NO_LINK;
 	    }
 	    else
 	    {
-	      rio_dprint(RIO_DEBUG_ROUTE, ("HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n",
-		    OldLink+'A',HostP->Mapping[ThisUnit-1].Name,ThisLink+'A'));
+	      rio_dprintk (RIO_DEBUG_ROUTE, "HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n",
+		    OldLink+'A',HostP->Mapping[ThisUnit-1].Name,ThisLink+'A');
 	    }
 	  }
 	  else if ( OldUnit <= MAX_RUP )
@@ -282,29 +282,29 @@
 	    if ( HostP->Mapping[OldUnit-1].Topology[OldLink].Unit == ThisUnit &&
 	         HostP->Mapping[OldUnit-1].Topology[OldLink].Link == ThisLink )
 	    {
-	      rio_dprint(RIO_DEBUG_ROUTE, ("SETTING RTA %s (%c) TO DISCONNECTED!\n",
-				   HostP->Mapping[OldUnit-1].Name,OldLink+'A'));
+	      rio_dprintk (RIO_DEBUG_ROUTE, "SETTING RTA %s (%c) TO DISCONNECTED!\n",
+				   HostP->Mapping[OldUnit-1].Name,OldLink+'A');
 	      HostP->Mapping[OldUnit-1].Topology[OldLink].Unit=ROUTE_DISCONNECT;
 	      HostP->Mapping[OldUnit-1].Topology[OldLink].Link=NO_LINK;
 	    }
 	    else
 	    {
-	      rio_dprint(RIO_DEBUG_ROUTE, ("RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n",
+	      rio_dprintk (RIO_DEBUG_ROUTE, "RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n",
 			    HostP->Mapping[OldUnit-1].Name,OldLink+'A',
-			    HostP->Mapping[ThisUnit-1].Name,ThisLink+'A'));
+			    HostP->Mapping[ThisUnit-1].Name,ThisLink+'A');
 	    }
 	  }
 	  if ( NewUnit == HOST_ID )
 	  {
-	    rio_dprint(RIO_DEBUG_ROUTE, ("MARKING HOST (%c) CONNECTED TO %s (%c)\n",
-				NewLink+'A',MyName,ThisLink+'A'));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "MARKING HOST (%c) CONNECTED TO %s (%c)\n",
+				NewLink+'A',MyName,ThisLink+'A');
 	    HostP->Topology[NewLink].Unit = ThisUnit;
 	    HostP->Topology[NewLink].Link = ThisLink;
 	  }
 	  else if ( NewUnit <= MAX_RUP )
 	  {
-	    rio_dprint(RIO_DEBUG_ROUTE, ("MARKING RTA %s (%c) CONNECTED TO %s (%c)\n",
-	      HostP->Mapping[NewUnit-1].Name,NewLink+'A',MyName,ThisLink+'A'));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "MARKING RTA %s (%c) CONNECTED TO %s (%c)\n",
+	      HostP->Mapping[NewUnit-1].Name,NewLink+'A',MyName,ThisLink+'A');
 	    HostP->Mapping[NewUnit-1].Topology[NewLink].Unit=ThisUnit;
 	    HostP->Mapping[NewUnit-1].Topology[NewLink].Link=ThisLink;
 	  }
@@ -321,8 +321,8 @@
   */
   if ( RBYTE(PktCmdP->Command) != ROUTE_REQUEST )
   {
-    rio_dprint(RIO_DEBUG_ROUTE, ("Unknown command %d received on rup %d host %d ROUTE_RUP\n", 
-	   RBYTE(PktCmdP->Command),Rup,(int)HostP));
+    rio_dprintk (RIO_DEBUG_ROUTE, "Unknown command %d received on rup %d host %d ROUTE_RUP\n", 
+	   RBYTE(PktCmdP->Command),Rup,(int)HostP);
     return TRUE;
   }
       
@@ -336,7 +336,7 @@
   */
   RtaType = GetUnitType(RtaUniq);
 
-  rio_dprint(RIO_DEBUG_ROUTE, ("Received a request for an ID for serial number %x\n", RtaUniq));
+  rio_dprintk (RIO_DEBUG_ROUTE, "Received a request for an ID for serial number %x\n", RtaUniq);
 
   Mod = RBYTE(PktCmdP->ModuleTypes);
   Mod1 = LONYBLE(Mod);
@@ -347,14 +347,14 @@
     ** with 8 port, set 2nd ident in Mod2 to the same as Mod1.
     */
     Mod2 = Mod1;
-    rio_dprint(RIO_DEBUG_ROUTE, ("Backplane type is %s (all ports)\n",
-     p->RIOModuleTypes[Mod1].Name ));
+    rio_dprintk (RIO_DEBUG_ROUTE, "Backplane type is %s (all ports)\n",
+     p->RIOModuleTypes[Mod1].Name);
   }
   else
   {
     Mod2 = HINYBLE(Mod);
-    rio_dprint(RIO_DEBUG_ROUTE, ("Module types are %s (ports 0-3) and %s (ports 4-7)\n",
-     p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name ));
+    rio_dprintk (RIO_DEBUG_ROUTE, "Module types are %s (ports 0-3) and %s (ports 4-7)\n",
+     p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name);
   }
 
   if ( RtaUniq == 0xffffffff )
@@ -367,7 +367,7 @@
   */
   if ( !(CmdBlkP = RIOGetCmdBlk()) )
   {
-    rio_dprint(RIO_DEBUG_ROUTE, ("No command blocks to route RTA! come back later.\n"));
+    rio_dprintk (RIO_DEBUG_ROUTE, "No command blocks to route RTA! come back later.\n");
     return 0;
   }
 
@@ -384,8 +384,8 @@
 
   if (! RIOBootOk(p, HostP, RtaUniq))
   {
-    rio_dprint(RIO_DEBUG_ROUTE, ("RTA %x tried to get an ID, but does not belong - FOAD it!\n",
-	  RtaUniq));
+    rio_dprintk (RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n",
+	  RtaUniq);
     PktReplyP->Command = ROUTE_FOAD;
     HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7);
     RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
@@ -397,13 +397,13 @@
   */
   for ( ThisUnit=0; ThisUnit<MAX_RUP; ThisUnit++ )
   {
-    rio_dprint(RIO_DEBUG_ROUTE, ("Entry %d Flags=%s %s UniqueNum=0x%x\n",
+    rio_dprintk (RIO_DEBUG_ROUTE, "Entry %d Flags=%s %s UniqueNum=0x%x\n",
 			ThisUnit,
 			HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE ?
 					    "Slot-In-Use":"Not In Use",
 			HostP->Mapping[ThisUnit].Flags & SLOT_TENTATIVE ? 
 					    "Slot-Tentative":"Not Tentative",
-			HostP->Mapping[ThisUnit].RtaUniqueNum ));
+			HostP->Mapping[ThisUnit].RtaUniqueNum);
 
     /*
     ** We have an entry for it.
@@ -414,12 +414,12 @@
       if (RtaType == TYPE_RTA16)
       {
 	  ThisUnit2 = HostP->Mapping[ThisUnit].ID2 - 1;
-          rio_dprint(RIO_DEBUG_ROUTE, ("Found unit 0x%x at slots %d+%d\n",
-					    RtaUniq,ThisUnit,ThisUnit2));
+          rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slots %d+%d\n",
+					    RtaUniq,ThisUnit,ThisUnit2);
       }
       else
-          rio_dprint(RIO_DEBUG_ROUTE, ("Found unit 0x%x at slot %d\n",
-					    RtaUniq,ThisUnit));
+          rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slot %d\n",
+					    RtaUniq,ThisUnit);
       /*
       ** If we have no knowledge of booting it, then the host has
       ** been re-booted, and so we must kill the RTA, so that it
@@ -458,14 +458,14 @@
 	    */
 	    RIOFixPhbs(p, HostP, ThisUnit2);
 	    PktReplyP->IDNum2  = ThisUnit2+1;
-	    rio_dprint(RIO_DEBUG_ROUTE, ("RTA '%s' has been allocated IDs %d+%d\n",
-	          HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated IDs %d+%d\n",
+	          HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2);
       }
       else
       {
 	    PktReplyP->IDNum2 = ROUTE_NO_ID;
-	    rio_dprint(RIO_DEBUG_ROUTE, ("RTA '%s' has been allocated ID %d\n",
-	          HostP->Mapping[ThisUnit].Name,PktReplyP->IDNum));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n",
+	          HostP->Mapping[ThisUnit].Name,PktReplyP->IDNum);
       }
       HostP->Copy("RT_ALLOCAT",PktReplyP->CommandText,10);
 
@@ -489,7 +489,7 @@
 	  PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort];
 	  if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) )
 	  {
-	    rio_dprint(RIO_DEBUG_ROUTE, ("Re-opened this port\n"));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n");
 	    rio_spin_lock_irqsave(&PortP->portSem, flags);
 	    PortP->MagicFlags |= MAGIC_REBOOT;
 	    rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -502,7 +502,7 @@
 	    PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort];
 	    if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) )
 	    {
-	      rio_dprint(RIO_DEBUG_ROUTE, ("Re-opened this port\n"));
+	      rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n");
 	      rio_spin_lock_irqsave(&PortP->portSem, flags);
 	      PortP->MagicFlags |= MAGIC_REBOOT;
 	      rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -628,7 +628,7 @@
 	unsigned long flags;
 	int PortN = HostP->Mapping[unit].SysPort;
 
-	rio_dprint(RIO_DEBUG_ROUTE, ("RIOFixPhbs unit %d sysport %d\n", unit, PortN));
+	rio_dprintk (RIO_DEBUG_ROUTE, "RIOFixPhbs unit %d sysport %d\n", unit, PortN);
 
 	if (PortN != -1) {
 		ushort		dest_unit = HostP->Mapping[unit].ID2;
@@ -656,7 +656,7 @@
 			** unset, so go no further.
 			*/
 			if (PortP->TxStart == 0) {
-					rio_dprint(RIO_DEBUG_ROUTE, ("Tx pkts not set up yet\n"));
+					rio_dprintk (RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n");
 					break;
 			}
 
@@ -691,10 +691,10 @@
 				WBYTE(Pkt->dest_unit, dest_unit);
 				WBYTE(Pkt->dest_port, dest_port);
 			}
-			rio_dprint(RIO_DEBUG_ROUTE, ("phb dest: Old %x:%x New %x:%x\n",
+			rio_dprintk (RIO_DEBUG_ROUTE, "phb dest: Old %x:%x New %x:%x\n",
 					RWORD(PortP->PhbP->destination) & 0xff,
 					(RWORD(PortP->PhbP->destination) >> 8) & 0xff,
-					dest_unit, dest_port));
+					dest_unit, dest_port);
 			WWORD(PortP->PhbP->destination, dest_unit + (dest_port << 8));
 			WWORD(PortP->PhbP->link, link);
 
@@ -706,7 +706,7 @@
 		*/
 		if (link > 3) return;
 		if (((unit * 8) + 7) > RWORD(HostP->LinkStrP[link].last_port)) {
-			rio_dprint(RIO_DEBUG_ROUTE, ("last port on host link %d: %d\n", link, (unit * 8) + 7));
+			rio_dprintk (RIO_DEBUG_ROUTE, "last port on host link %d: %d\n", link, (unit * 8) + 7);
 			WWORD(HostP->LinkStrP[link].last_port, (unit * 8) + 7);
 		}
 	}
@@ -732,7 +732,7 @@
 	CheckUnitId( UnitId );
 #endif
 	if ( RIOCheck( HostP, UnitId ) ) {
-		rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated\n",UnitId));
+		rio_dprintk (RIO_DEBUG_ROUTE, "Unit %d is NOT isolated\n", UnitId);
 		rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
 		return(0);
 	}
@@ -771,7 +771,7 @@
 	HostP->Mapping[UnitId].Flags |= BEEN_HERE;
 
 	if ( p->RIOPrintDisabled == DO_PRINT )
-		rio_dprint(RIO_DEBUG_ROUTE, ("RIOMesgIsolated %s",HostP->Mapping[UnitId].Name));
+		rio_dprintk (RIO_DEBUG_ROUTE, "RIOMesgIsolated %s", HostP->Mapping[UnitId].Name);
 
 	for ( link=0; link<LINKS_PER_UNIT; link++) {
 		unit = HostP->Mapping[UnitId].Topology[link].Unit;
@@ -795,7 +795,7 @@
 	CheckUnitId( UnitId );
 #endif
 /* 	rio_dprint(RIO_DEBUG_ROUTE, ("Check to see if unit %d has a route to the host\n",UnitId)); */
-	rio_dprint(RIO_DEBUG_ROUTE, ("RIOCheck : UnitID = %d\n",UnitId));
+	rio_dprintk (RIO_DEBUG_ROUTE, "RIOCheck : UnitID = %d\n", UnitId);
 
 	if ( UnitId == HOST_ID ) {
 		/* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated - it IS the host!\n", UnitId)); */
@@ -854,16 +854,16 @@
 		case RIO_MCA:
 		case RIO_EISA:
 		case RIO_PCI:
-			rio_dprint(RIO_DEBUG_ROUTE, ("Unit type: Host\n"));
+			rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: Host\n");
 			return(TYPE_HOST);
 		case RIO_RTA_16:
-			rio_dprint(RIO_DEBUG_ROUTE, ("Unit type: 16 port RTA\n"));
+			rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: 16 port RTA\n");
 			return(TYPE_RTA16);
 		case RIO_RTA:
-			rio_dprint(RIO_DEBUG_ROUTE, ("Unit type: 8 port RTA\n"));
+			rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: 8 port RTA\n");
 			return(TYPE_RTA8);
 		default :
-			rio_dprint(RIO_DEBUG_ROUTE, ("Unit type: Unrecognised\n"));
+			rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: Unrecognised\n");
 			return(99);
 	}
 }
@@ -876,7 +876,7 @@
 		return(0);
 	p->RIOQuickCheck = CHANGED;
 	if ( p->RIOSignalProcess ) {
-		rio_dprint(RIO_DEBUG_ROUTE, ("Send SIG-HUP"));
+		rio_dprintk (RIO_DEBUG_ROUTE, "Send SIG-HUP");
 		/*
 		psignal( RIOSignalProcess, SIGHUP );
 		*/
@@ -951,10 +951,10 @@
     ToName = ToId ? HostP->Mapping[ToId-1].Name : HostP->Name;
     ToType = ToId ? "RTA" : "HOST";
 
-    rio_dprint(RIO_DEBUG_ROUTE, ("Link between %s '%s' (%c) and %s '%s' (%c) %s.\n",
+    rio_dprintk (RIO_DEBUG_ROUTE, "Link between %s '%s' (%c) and %s '%s' (%c) %s.\n",
 			    FromType, FromName, 'A'+FromLink,
 			    ToType,   ToName,   'A'+ToLink,
-			    (Change==CONNECT) ? "established" : "disconnected"));
+			    (Change==CONNECT) ? "established" : "disconnected");
     cprintf("Link between %s '%s' (%c) and %s '%s' (%c) %s.\n",
 			    FromType, FromName, 'A'+FromLink,
 			    ToType,   ToName,   'A'+ToLink,
@@ -1000,7 +1000,7 @@
     int		link;
 
 
-    rio_dprint(RIO_DEBUG_ROUTE, ("RIOFreeDisconnect unit %d\n",unit));
+    rio_dprintk (RIO_DEBUG_ROUTE, "RIOFreeDisconnect unit %d\n", unit);
     /*
     ** If the slot is tentative and does not belong to the
     ** second half of a 16 port RTA then scan to see if
@@ -1023,17 +1023,17 @@
     ** made this slot tentative and not yet received a topology update.
     ** Lets check how long ago we made it tentative.
     */
-    rio_dprint(RIO_DEBUG_ROUTE, ("Just about to check LBOLT on entry %d\n",unit));
+    rio_dprintk (RIO_DEBUG_ROUTE, "Just about to check LBOLT on entry %d\n", unit);
     if (drv_getparm(LBOLT, (ulong_t *) &current_time))
-        rio_dprint(RIO_DEBUG_ROUTE, ("drv_getparm(LBOLT,....) Failed.\n"));
+        rio_dprintk (RIO_DEBUG_ROUTE, "drv_getparm(LBOLT,....) Failed.\n");
 
     elapse_time = current_time - TentTime[unit];
-    rio_dprint(RIO_DEBUG_ROUTE, ("elapse %d = current %d - tent %d (%d usec)\n",
-        elapse_time, current_time, TentTime[unit],drv_hztousec(elapse_time)));
+    rio_dprintk (RIO_DEBUG_ROUTE, "elapse %d = current %d - tent %d (%d usec)\n",
+        elapse_time, current_time, TentTime[unit], drv_hztousec(elapse_time));
     if (drv_hztousec(elapse_time) < WAIT_TO_FINISH)
     {
-        rio_dprint(RIO_DEBUG_ROUTE, ("Skipping slot %d, not timed out yet %d\n"
-            ,unit,drv_hztousec(elapse_time)));
+      rio_dprintk (RIO_DEBUG_ROUTE, "Skipping slot %d, not timed out yet %d\n",
+            unit, drv_hztousec(elapse_time));
         return 1;
     }
 #endif
@@ -1046,7 +1046,7 @@
     {
 	int nOther = (HostP->Mapping[unit].ID2) -1;
 
-	rio_dprint(RIO_DEBUG_ROUTE, ("RioFreedis second slot %d.\n",nOther));
+	rio_dprintk (RIO_DEBUG_ROUTE, "RioFreedis second slot %d.\n", nOther);
 	bzero((caddr_t)&HostP->Mapping[nOther], sizeof(struct Map));
     }
     RIORemoveFromSavedTable(p, &HostP->Mapping[unit]);
@@ -1082,19 +1082,19 @@
     */
     for (unit = 0; unit < MAX_RUP; unit++)
     {
-	rio_dprint(RIO_DEBUG_ROUTE, ("Scanning unit %d\n",unit));
+	rio_dprintk (RIO_DEBUG_ROUTE, "Scanning unit %d\n",unit);
 	/*
 	** If the flags are zero then the slot is empty.
 	*/
 	if (HostP->Mapping[unit].Flags == 0)
 	{
-	    rio_dprint(RIO_DEBUG_ROUTE, ("      This slot is empty.\n"));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "      This slot is empty.\n");
 	    /*
 	    ** If we haven't allocated the first ID then do it now.
 	    */
 	    if (*pID1 == MAX_RUP)
 	    {
-		rio_dprint(RIO_DEBUG_ROUTE, ("Make tentative entry for first unit %d\n", unit));
+		rio_dprintk (RIO_DEBUG_ROUTE, "Make tentative entry for first unit %d\n", unit);
 		*pID1 = unit;
 
 		/*
@@ -1109,7 +1109,7 @@
 		/*
 		** Allocate the second slot and return.
 		*/
-		rio_dprint(RIO_DEBUG_ROUTE, ("Make tentative entry for second unit %d\n", unit));
+		rio_dprintk (RIO_DEBUG_ROUTE, "Make tentative entry for second unit %d\n", unit);
 		*pID2 = unit;
 		return 0;
 	    }
@@ -1121,18 +1121,18 @@
     ** need to start all over again looking for tentative slots
     ** that we can re-use.
     */
-    rio_dprint(RIO_DEBUG_ROUTE, ("Starting to scan for tentative slots\n"));
+    rio_dprintk (RIO_DEBUG_ROUTE, "Starting to scan for tentative slots\n");
     for (unit = 0; unit < MAX_RUP; unit++)
     {
 	if (((HostP->Mapping[unit].Flags & SLOT_TENTATIVE) ||
 	                       (HostP->Mapping[unit].Flags == 0))  && ! 
 	   (HostP->Mapping[unit].Flags & RTA16_SECOND_SLOT ))
 	{
-	    rio_dprint(RIO_DEBUG_ROUTE, ("    Slot %d looks promising.\n",unit));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "    Slot %d looks promising.\n",unit);
 
 	    if(unit == *pID1)
 	    {
-	    	rio_dprint(RIO_DEBUG_ROUTE, ("    No it isn't, its the 1st half\n"));
+	    	rio_dprintk (RIO_DEBUG_ROUTE, "    No it isn't, its the 1st half\n");
 		continue;
 	    }
 
@@ -1152,7 +1152,7 @@
 	    */
 	    if (*pID1 == MAX_RUP)
 	    {
-		rio_dprint(RIO_DEBUG_ROUTE, ("Grab tentative entry for first unit %d\n", unit));
+		rio_dprintk (RIO_DEBUG_ROUTE, "Grab tentative entry for first unit %d\n", unit);
 		*pID1 = unit;
 
 		/*
@@ -1172,8 +1172,8 @@
 		/*
 		** Allocate the second slot and return.
 		*/
-		rio_dprint(RIO_DEBUG_ROUTE, ("Grab tentative/empty  entry for second unit %d\n",
-		      unit));
+		rio_dprintk (RIO_DEBUG_ROUTE, "Grab tentative/empty  entry for second unit %d\n",
+		      unit);
 		*pID2 = unit;
 
 		/*
@@ -1190,7 +1190,7 @@
 
 		if (*pID1 > *pID2)
 		{
-			rio_dprint(RIO_DEBUG_ROUTE, ("Swapping IDS %d %d\n",*pID1,*pID2));
+			rio_dprintk (RIO_DEBUG_ROUTE, "Swapping IDS %d %d\n", *pID1, *pID2);
 			tempID = *pID1;
 			*pID1 = *pID2;
 			*pID2 = tempID;
diff -urN linux-2.2.17-pre15/drivers/char/rio/riotable.c linux/drivers/char/rio/riotable.c
--- linux-2.2.17-pre15/drivers/char/rio/riotable.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/char/rio/riotable.c	Mon Dec  3 22:10:50 2001
@@ -120,7 +120,7 @@
 	** (9)	That names aren't duplicated
 	** xx (10) That hosts that actually exist are mentioned in the table. xx
 	*/
-	rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(1)\n")); 
+	rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(1)\n"); 
 	if ( p->RIOSystemUp ) {		/* (1) */
 		p->RIOError.Error = HOST_HAS_ALREADY_BEEN_BOOTED;
 		return EBUSY;
@@ -133,7 +133,7 @@
 	for ( Entry=0; Entry<TOTAL_MAP_ENTRIES; Entry++ ) {
 		MapP = &p->RIOConnectTable[Entry];
 		if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) {
-			rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(2)\n"));
+			rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(2)\n");
 			cptr = MapP->Name;		/* (2) */
 			cptr[MAX_NAME_LEN-1]='\0';
 			if ( cptr[0]=='\0' ) {
@@ -161,19 +161,19 @@
 			continue;
 		}
 
-		rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(3)\n"));
+		rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(3)\n");
 		if ( !MapP->RtaUniqueNum && !MapP->HostUniqueNum ) { /* (3) */
 			if ( MapP->ID || MapP->SysPort || MapP->Flags ) {
-				rio_dprint(RIO_DEBUG_TABLE, ("%s pretending to be empty but isn't\n",MapP->Name));
+				rio_dprintk (RIO_DEBUG_TABLE, "%s pretending to be empty but isn't\n",MapP->Name);
 				p->RIOError.Error = TABLE_ENTRY_ISNT_PROPERLY_NULL;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
 			}
-			rio_dprint(RIO_DEBUG_TABLE, ("!RIO: Daemon: test (3) passes\n"));
+			rio_dprintk (RIO_DEBUG_TABLE, "!RIO: Daemon: test (3) passes\n");
 			continue;
 		}
 
-		rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(4)\n"));
+		rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(4)\n");
 		for ( Host=0; Host<p->RIONumHosts; Host++ ) { /* (4) */
 			if ( p->RIOHosts[Host].UniqueNum==MapP->HostUniqueNum ) {
 				HostP = &p->RIOHosts[Host];
@@ -187,8 +187,8 @@
 		}
 
 		if ( Host >= p->RIONumHosts ) {
-			rio_dprint(RIO_DEBUG_TABLE, ("RTA %s has unknown host unique number 0x%x\n",
-									MapP->Name,MapP->HostUniqueNum));
+			rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has unknown host unique number 0x%x\n",
+									MapP->Name, MapP->HostUniqueNum);
 			MapP->HostUniqueNum = 0;
 			/* MapP->RtaUniqueNum	= 0; */
 			/* MapP->ID			= 0; */
@@ -198,18 +198,18 @@
 			continue;
 		}
 
-		rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(5)\n")); 
+		rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(5)\n"); 
 		if ( MapP->RtaUniqueNum ) { /* (5) */
 			if ( !MapP->ID ) {
-				rio_dprint(RIO_DEBUG_TABLE, ("RIO: RTA %s has been allocated an ID of zero!\n",
-							MapP->Name));
+				rio_dprintk (RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an ID of zero!\n",
+							MapP->Name);
 				p->RIOError.Error		 = ZERO_RTA_ID;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
 			}
 			if ( MapP->ID > MAX_RUP ) {
-				rio_dprint(RIO_DEBUG_TABLE, ("RIO: RTA %s has been allocated an illegal ID %d\n",
-							MapP->Name, MapP->ID));
+				rio_dprintk (RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an illegal ID %d\n",
+							MapP->Name, MapP->ID);
 				p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
@@ -218,8 +218,8 @@
 				if ( MapP->HostUniqueNum == 
 						p->RIOConnectTable[SubEnt].HostUniqueNum && 
 						MapP->ID == p->RIOConnectTable[SubEnt].ID ) {
-					rio_dprint(RIO_DEBUG_TABLE, ("Dupl. ID number allocated to RTA %s and RTA %s\n",
-							MapP->Name,p->RIOConnectTable[SubEnt].Name));
+					rio_dprintk (RIO_DEBUG_TABLE, "Dupl. ID number allocated to RTA %s and RTA %s\n",
+							MapP->Name, p->RIOConnectTable[SubEnt].Name);
 					p->RIOError.Error = DUPLICATED_RTA_ID;
 					p->RIOError.Entry = Entry;
 					p->RIOError.Other = SubEnt;
@@ -232,29 +232,29 @@
 				if ((MapP->RtaUniqueNum == 
 						p->RIOConnectTable[SubEnt].RtaUniqueNum)
 				 		&& (MapP->ID2 != p->RIOConnectTable[SubEnt].ID)) {
-					rio_dprint(RIO_DEBUG_TABLE, ("RTA %s has duplicate unique number\n",MapP->Name));
-					rio_dprint(RIO_DEBUG_TABLE, ("RTA %s has duplicate unique number\n",
-										p->RIOConnectTable[SubEnt].Name));
+					rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n",MapP->Name);
+					rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n",
+										p->RIOConnectTable[SubEnt].Name);
 					p->RIOError.Error = DUPLICATE_UNIQUE_NUMBER;
 					p->RIOError.Entry = Entry;
 					p->RIOError.Other = SubEnt;
 					return ENXIO;
 				}
 			}
-			rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(7a)\n")); 
+			rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(7a)\n"); 
 			/* (7a) */
 			if ((MapP->SysPort != NO_PORT)&&(MapP->SysPort % PORTS_PER_RTA)) {
-				rio_dprint(RIO_DEBUG_TABLE, ("TTY Port number %d-RTA %s is not a multiple of %d!\n",
-					(int)MapP->SysPort,MapP->Name,PORTS_PER_RTA));
+				rio_dprintk (RIO_DEBUG_TABLE, "TTY Port number %d-RTA %s is not a multiple of %d!\n",
+					(int)MapP->SysPort,MapP->Name, PORTS_PER_RTA);
 				p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
 			}
-			rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(7b)\n")); 
+			rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(7b)\n"); 
 			/* (7b) */
 			if ((MapP->SysPort != NO_PORT)&&(MapP->SysPort >= RIO_PORTS)) {
-				rio_dprint(RIO_DEBUG_TABLE, ("TTY Port number %d for RTA %s is too big\n",
-							(int)MapP->SysPort,MapP->Name));
+				rio_dprintk (RIO_DEBUG_TABLE, "TTY Port number %d for RTA %s is too big\n",
+							(int)MapP->SysPort, MapP->Name);
 				p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
@@ -263,22 +263,22 @@
 				if ( p->RIOConnectTable[SubEnt].Flags & RTA16_SECOND_SLOT )
 						continue;
 				if ( p->RIOConnectTable[SubEnt].RtaUniqueNum ) {
-					rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(8)\n")); 
+					rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(8)\n"); 
 					/* (8) */
 					if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort == 
 									p->RIOConnectTable[SubEnt].SysPort) ) {
-						rio_dprint(RIO_DEBUG_TABLE, ("RTA %s:same TTY port # as RTA %s (%d)\n",
+						rio_dprintk (RIO_DEBUG_TABLE, "RTA %s:same TTY port # as RTA %s (%d)\n",
 							MapP->Name, p->RIOConnectTable[SubEnt].Name,
-							(int)MapP->SysPort));
+							(int)MapP->SysPort);
 						p->RIOError.Error = TTY_NUMBER_IN_USE;
 						p->RIOError.Entry = Entry;
 						p->RIOError.Other = SubEnt;
 						return ENXIO;
 					}
-					rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(9)\n")); 
+					rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(9)\n"); 
 					if (RIOStrCmp(MapP->Name,
 							p->RIOConnectTable[SubEnt].Name)==0 && !(MapP->Flags & RTA16_SECOND_SLOT)) { /* (9) */
-						rio_dprint(RIO_DEBUG_TABLE, ("RTA name %s used twice\n",MapP->Name));
+						rio_dprintk (RIO_DEBUG_TABLE, "RTA name %s used twice\n", MapP->Name);
 						p->RIOError.Error = NAME_USED_TWICE;
 						p->RIOError.Entry = Entry;
 						p->RIOError.Other = SubEnt;
@@ -288,17 +288,17 @@
 			}
 		}
 		else { /* (6) */
-			rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(6)\n")); 
+			rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(6)\n"); 
 			if ( MapP->ID ) {
-				rio_dprint(RIO_DEBUG_TABLE, ("RIO:HOST %s has been allocated ID that isn't zero!\n",
-					MapP->Name));
+				rio_dprintk (RIO_DEBUG_TABLE, "RIO:HOST %s has been allocated ID that isn't zero!\n",
+					MapP->Name);
 				p->RIOError.Error = HOST_ID_NOT_ZERO;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
 			}
 			if ( MapP->SysPort != NO_PORT ) {
-				rio_dprint(RIO_DEBUG_TABLE, ("RIO: HOST %s has been allocated port numbers!\n",
-					MapP->Name));
+				rio_dprintk (RIO_DEBUG_TABLE, "RIO: HOST %s has been allocated port numbers!\n",
+					MapP->Name);
 				p->RIOError.Error = HOST_SYSPORT_BAD;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
@@ -326,7 +326,7 @@
 	** Copy in the new table entries
 	*/
 	for ( Entry=0; Entry< TOTAL_MAP_ENTRIES; Entry++ ) {
-		rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: Copy table for Host entry %d\n", Entry));
+		rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: Copy table for Host entry %d\n", Entry);
 		MapP = &p->RIOConnectTable[Entry];
 
 		/*
@@ -344,7 +344,7 @@
 		** If it is a host, then we only need to fill in the name field.
 		*/
 		if ( MapP->ID==0 ) {
-			rio_dprint(RIO_DEBUG_TABLE, ("Host entry found. Name %s\n",MapP->Name));
+			rio_dprintk (RIO_DEBUG_TABLE, "Host entry found. Name %s\n", MapP->Name);
 			bcopy(MapP->Name,HostP->Name,MAX_NAME_LEN);
 			continue;
 		}
@@ -357,7 +357,7 @@
 		HostMapP = &HostP->Mapping[MapP->ID-1];
 
 		if (MapP->Flags & SLOT_IN_USE) {
-			rio_dprint(RIO_DEBUG_TABLE, ("Rta entry found. Name %s\n",MapP->Name));
+			rio_dprintk (RIO_DEBUG_TABLE, "Rta entry found. Name %s\n", MapP->Name);
 			/*
 			** structure assign, then sort out the bits we shouldn't have done
 			*/
@@ -370,7 +370,7 @@
 			RIOReMapPorts(p, HostP, HostMapP );
 		}
 		else {
-			rio_dprint(RIO_DEBUG_TABLE, ("TENTATIVE Rta entry found. Name %s\n",MapP->Name));
+			rio_dprintk (RIO_DEBUG_TABLE, "TENTATIVE Rta entry found. Name %s\n", MapP->Name);
 		}
 	}
 
@@ -420,11 +420,11 @@
 		*/
 		if (Host1 != Host)
 		{
-			rio_dprint(RIO_DEBUG_TABLE, ("Default name %s already used\n", p->RIOHosts[Host].Name));
+			rio_dprintk (RIO_DEBUG_TABLE, "Default name %s already used\n", p->RIOHosts[Host].Name);
 			bcopy("HOST 1",p->RIOHosts[Host].Name,7);
 			p->RIOHosts[Host].Name[5] += Host1;
 		}
-		rio_dprint(RIO_DEBUG_TABLE, ("Assigning default name %s\n", p->RIOHosts[Host].Name));
+		rio_dprintk (RIO_DEBUG_TABLE, "Assigning default name %s\n", p->RIOHosts[Host].Name);
 	}
 	return 0;
 }
@@ -447,13 +447,13 @@
 
 	disable(oldspl);		/* strange but true! */
  
-	rio_dprint(RIO_DEBUG_TABLE, ("Generating a table to return to config.rio\n"));
+	rio_dprintk (RIO_DEBUG_TABLE, "Generating a table to return to config.rio\n");
 
 	bzero((caddr_t)&p->RIOConnectTable[0], 
 					sizeof(struct Map) * TOTAL_MAP_ENTRIES );
 
 	for ( Host=0; Host<RIO_HOSTS; Host++ ) {
-		rio_dprint(RIO_DEBUG_TABLE, ("Processing host %d\n", Host));
+		rio_dprintk (RIO_DEBUG_TABLE, "Processing host %d\n", Host);
 		HostP = &p->RIOHosts[Host];
 		MapP = &p->RIOConnectTable[Next++];
 		MapP->HostUniqueNum = HostP->UniqueNum;
@@ -501,8 +501,8 @@
 	int work_done = 0;
 	unsigned long flags;
 
-	rio_dprint(RIO_DEBUG_TABLE, ("Delete entry on host %x, rta %x\n",
-								MapP->HostUniqueNum,MapP->RtaUniqueNum));
+	rio_dprintk (RIO_DEBUG_TABLE, "Delete entry on host %x, rta %x\n",
+								MapP->HostUniqueNum, MapP->RtaUniqueNum);
 
 	for ( host=0; host < p->RIONumHosts; host++ ) {
 		HostP = &p->RIOHosts[host];
@@ -517,15 +517,15 @@
 		for ( entry=0; entry<MAX_RUP; entry++ ) {
 			if ( MapP->RtaUniqueNum == HostP->Mapping[entry].RtaUniqueNum ) {
 				HostMapP = &HostP->Mapping[entry];
-				rio_dprint(RIO_DEBUG_TABLE, ("Found entry offset %d on host %s\n", 
-						entry,HostP->Name));
+				rio_dprintk (RIO_DEBUG_TABLE, "Found entry offset %d on host %s\n", 
+						entry, HostP->Name);
 
 				/*
 				** Check all four links of the unit are disconnected
 				*/
 				for ( link=0; link< LINKS_PER_UNIT; link++ ) {
 					if ( HostMapP->Topology[link].Unit != ROUTE_DISCONNECT ) {
-						rio_dprint(RIO_DEBUG_TABLE, ("Entry is in use and cannot be deleted!\n"));
+						rio_dprintk (RIO_DEBUG_TABLE, "Entry is in use and cannot be deleted!\n");
 						p->RIOError.Error = UNIT_IS_IN_USE;
 						rio_spin_unlock_irqrestore( &HostP->HostLock, flags);
 						return EBUSY;
@@ -540,7 +540,7 @@
 				if ( SysPort != NO_PORT ) {
 					for (port=SysPort; port < SysPort+PORTS_PER_RTA; port++) {
 						PortP = p->RIOPortp[port];
-						rio_dprint(RIO_DEBUG_TABLE, ("Unmap port\n"));
+						rio_dprintk (RIO_DEBUG_TABLE, "Unmap port\n");
 
 						rio_spin_lock_irqsave( &PortP->portSem, flags );
 
@@ -548,7 +548,7 @@
 
 						if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) ) {
 
-							rio_dprint(RIO_DEBUG_TABLE, ("Gob on port\n"));
+							rio_dprintk (RIO_DEBUG_TABLE, "Gob on port\n");
 							PortP->TxBufferIn = PortP->TxBufferOut = 0;
 							/* What should I do 
 							wakeup( &PortP->TxBufferIn );
@@ -585,25 +585,25 @@
 								*/
 								Pkt = (PKT *) RIO_PTR(HostP->Caddr,
 								 	RWORD(*TxPktP));
-								rio_dprint(RIO_DEBUG_TABLE, (
+								rio_dprintk (RIO_DEBUG_TABLE, 
 						"Tx packet (%x) destination: Old %x:%x New %x:%x\n",
 								 *TxPktP, Pkt->dest_unit,
-								 Pkt->dest_port, dest_unit, dest_port));
+								 Pkt->dest_port, dest_unit, dest_port);
 								WWORD(Pkt->dest_unit, dest_unit);
 								WWORD(Pkt->dest_port, dest_port);
 							}
-							rio_dprint(RIO_DEBUG_TABLE, (
+							rio_dprintk (RIO_DEBUG_TABLE, 
 						"Port %d phb destination: Old %x:%x New %x:%x\n",
 							 port, PortP->PhbP->destination & 0xff,
 							 (PortP->PhbP->destination >> 8) & 0xff,
-							 dest_unit, dest_port));
+							 dest_unit, dest_port);
 							WWORD(PortP->PhbP->destination,
 							 dest_unit + (dest_port << 8));
 						}
 						rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 					}
 				}
-				rio_dprint(RIO_DEBUG_TABLE, ("Entry nulled.\n"));
+				rio_dprintk (RIO_DEBUG_TABLE, "Entry nulled.\n");
 				bzero((char *)HostMapP,sizeof(struct Map));
 				work_done++;
 			}
@@ -625,7 +625,7 @@
 	if ( work_done )
 		return 0;
 
-	rio_dprint(RIO_DEBUG_TABLE, ("Couldn't find entry to be deleted\n"));
+	rio_dprintk (RIO_DEBUG_TABLE, "Couldn't find entry to be deleted\n");
 	p->RIOError.Error = COULDNT_FIND_ENTRY;
 	return ENXIO;
 }
@@ -638,32 +638,32 @@
     int	link;
 
 
-    rio_dprint(RIO_DEBUG_TABLE, ("Assign entry on host %x, rta %x, ID %d, Sysport %d\n",
+    rio_dprintk (RIO_DEBUG_TABLE, "Assign entry on host %x, rta %x, ID %d, Sysport %d\n",
 				MapP->HostUniqueNum,MapP->RtaUniqueNum,
-				MapP->ID, (int)MapP->SysPort ));
+				MapP->ID, (int)MapP->SysPort);
 
     if ((MapP->ID != (ushort)-1) &&
 	((int)MapP->ID < (int)1 || (int)MapP->ID > MAX_RUP ))
     {
-	rio_dprint(RIO_DEBUG_TABLE, ("Bad ID in map entry!\n"));
+	rio_dprintk (RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
 	p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
 	return EINVAL;
     }
     if (MapP->RtaUniqueNum == 0)
     {
-	rio_dprint(RIO_DEBUG_TABLE, ("Rta Unique number zero!\n"));
+	rio_dprintk (RIO_DEBUG_TABLE, "Rta Unique number zero!\n");
 	p->RIOError.Error = RTA_UNIQUE_NUMBER_ZERO;
 	return EINVAL;
     }
     if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA) )
     {
-	rio_dprint(RIO_DEBUG_TABLE, ("Port %d not multiple of %d!\n",(int)MapP->SysPort,PORTS_PER_RTA));
+	rio_dprintk (RIO_DEBUG_TABLE, "Port %d not multiple of %d!\n",(int)MapP->SysPort,PORTS_PER_RTA);
 	p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
 	return EINVAL;
     }
     if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS) )
     {
-	rio_dprint(RIO_DEBUG_TABLE, ("Port %d not valid!\n",(int)MapP->SysPort));
+	rio_dprintk (RIO_DEBUG_TABLE, "Port %d not valid!\n",(int)MapP->SysPort);
 	p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
 	return EINVAL;
     }
@@ -677,7 +677,7 @@
     {
     if ( *sptr<' ' || *sptr>'~' )
     {
-	rio_dprint(RIO_DEBUG_TABLE, ("Name entry contains non-printing characters!\n"));
+	rio_dprintk (RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
 	p->RIOError.Error = BAD_CHARACTER_IN_NAME;
 	return EINVAL;
     }
@@ -702,8 +702,8 @@
 	    {
 		int nNewID;
 
-		rio_dprint(RIO_DEBUG_TABLE, ("Attempting to get a new ID for rta \"%s\"\n",
-		      MapP->Name));
+		rio_dprintk (RIO_DEBUG_TABLE, "Attempting to get a new ID for rta \"%s\"\n",
+		      MapP->Name);
 		/*
 		** The idea here is to allow RTA's to be assigned
 		** before they actually appear on the network.
@@ -721,7 +721,7 @@
 		    return EBUSY;
 		}
 		MapP->ID = (ushort)nNewID + 1;
-		rio_dprint(RIO_DEBUG_TABLE, ("Allocated ID %d for this new RTA.\n",MapP->ID));
+		rio_dprintk (RIO_DEBUG_TABLE, "Allocated ID %d for this new RTA.\n", MapP->ID);
 		HostMapP = &p->RIOHosts[host].Mapping[nNewID];
 		HostMapP->RtaUniqueNum = MapP->RtaUniqueNum;
 		HostMapP->HostUniqueNum = MapP->HostUniqueNum;
@@ -747,9 +747,9 @@
 		    HostMapP->Flags |= RTA16_SECOND_SLOT;
 		    HostMapP->ID2 = MapP->ID2 = p->RIOHosts[host].Mapping[unit].ID;
 		    p->RIOHosts[host].Mapping[unit].ID2 = MapP->ID;
-		    rio_dprint(RIO_DEBUG_TABLE, ("Cross referenced id %d to ID %d.\n",
+		    rio_dprintk (RIO_DEBUG_TABLE, "Cross referenced id %d to ID %d.\n",
 			  MapP->ID,
-			  p->RIOHosts[host].Mapping[unit].ID));
+			  p->RIOHosts[host].Mapping[unit].ID);
 		}
 	    }
 
@@ -757,7 +757,7 @@
 
 	    if ( HostMapP->Flags & SLOT_IN_USE )
 	    {
-		rio_dprint(RIO_DEBUG_TABLE, ("Map table slot for ID %d is already in use.\n",MapP->ID));
+		rio_dprintk (RIO_DEBUG_TABLE, "Map table slot for ID %d is already in use.\n", MapP->ID);
 		p->RIOError.Error = ID_ALREADY_IN_USE;
 		return EBUSY;
 	    }
@@ -791,15 +791,15 @@
 		    p->RIOLastPortsBooted = HostMapP->SysPort;
 	    }
 	    if (MapP->Flags & RTA16_SECOND_SLOT)
-	        rio_dprint(RIO_DEBUG_TABLE, ("Second map of RTA %s added to configuration\n",
-		 p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name));
+	        rio_dprintk (RIO_DEBUG_TABLE, "Second map of RTA %s added to configuration\n",
+		 p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name);
 	    else
-	        rio_dprint(RIO_DEBUG_TABLE, ("RTA %s added to configuration\n",MapP->Name));
+	        rio_dprintk (RIO_DEBUG_TABLE, "RTA %s added to configuration\n", MapP->Name);
 	    return 0;
 	}
     }
     p->RIOError.Error = UNKNOWN_HOST_NUMBER;
-    rio_dprint(RIO_DEBUG_TABLE, ("Unknown host %x\n",MapP->HostUniqueNum));
+    rio_dprintk (RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
     return ENXIO;
 }
 
@@ -822,7 +822,7 @@
 	CheckHostMapP( HostMapP );
 #endif
 
-	rio_dprint(RIO_DEBUG_TABLE, ("Mapping sysport %d to id %d\n",(int)HostMapP->SysPort, HostMapP->ID));
+	rio_dprintk (RIO_DEBUG_TABLE, "Mapping sysport %d to id %d\n", (int)HostMapP->SysPort, HostMapP->ID);
 
 	/*
 	** We need to tell the UnixRups which sysport the rup corresponds to
@@ -833,26 +833,26 @@
 		return(0);
 
 	RtaType = GetUnitType(HostMapP->RtaUniqueNum);
-	rio_dprint(RIO_DEBUG_TABLE, ("Mapping sysport %d-%d\n",
-				(int)HostMapP->SysPort,(int)HostMapP->SysPort+PORTS_PER_RTA-1));
+	rio_dprintk (RIO_DEBUG_TABLE, "Mapping sysport %d-%d\n",
+				(int)HostMapP->SysPort, (int)HostMapP->SysPort+PORTS_PER_RTA-1);
 
 	/*
 	** now map each of its eight ports
 	*/
 	for ( SubEnt=0; SubEnt<PORTS_PER_RTA; SubEnt++) {
-	  rio_dprint  (RIO_DEBUG_TABLE, ("subent = %d, HostMapP->SysPort = %d\n", 
-		  SubEnt, (int) HostMapP->SysPort));
+	  rio_dprintk (RIO_DEBUG_TABLE, "subent = %d, HostMapP->SysPort = %d\n", 
+		  SubEnt, (int)HostMapP->SysPort);
 		SysPort = HostMapP->SysPort+SubEnt;		/* portnumber within system */
 					/* portnumber on host */
 		
 		HostPort = (HostMapP->ID-1)*PORTS_PER_RTA+SubEnt; 
 
-		rio_dprint (RIO_DEBUG_TABLE, ("c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp));
+		rio_dprintk (RIO_DEBUG_TABLE, "c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp);
 		PortP = p->RIOPortp[SysPort];
 #if 0
 		PortP->TtyP	= &p->channel[SysPort];
 #endif
-		rio_dprint(RIO_DEBUG_TABLE, ("Map port\n"));
+		rio_dprintk (RIO_DEBUG_TABLE, "Map port\n");
 
 		/*
 		** Point at all the real neat data structures
@@ -1008,12 +1008,12 @@
 	struct Map *HostMapP;
 	char *sptr;
 
-	rio_dprint(RIO_DEBUG_TABLE, ("Change name entry on host %x, rta %x, ID %d, Sysport %d\n",
+	rio_dprintk (RIO_DEBUG_TABLE, "Change name entry on host %x, rta %x, ID %d, Sysport %d\n",
 								MapP->HostUniqueNum,MapP->RtaUniqueNum,
-								MapP->ID, (int)MapP->SysPort ));
+								MapP->ID, (int)MapP->SysPort);
 
 	if ( MapP->ID > MAX_RUP ) {
-		rio_dprint(RIO_DEBUG_TABLE, ("Bad ID in map entry!\n"));
+		rio_dprintk (RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
 		p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
 		return EINVAL;
 	}
@@ -1023,7 +1023,7 @@
 
 	while ( *sptr ) {
 		if ( *sptr<' ' || *sptr>'~' ) {
-			rio_dprint(RIO_DEBUG_TABLE, ("Name entry contains non-printing characters!\n"));
+			rio_dprintk (RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
 			p->RIOError.Error = BAD_CHARACTER_IN_NAME;
 			return EINVAL;
 		}
@@ -1052,6 +1052,6 @@
 		}
 	}
 	p->RIOError.Error = UNKNOWN_HOST_NUMBER;
-	rio_dprint(RIO_DEBUG_TABLE, ("Unknown host %x\n",MapP->HostUniqueNum));
+	rio_dprintk (RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
 	return ENXIO;
 }
diff -urN linux-2.2.17-pre15/drivers/char/rio/riotty.c linux/drivers/char/rio/riotty.c
--- linux-2.2.17-pre15/drivers/char/rio/riotty.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/char/rio/riotty.c	Mon Dec  3 22:10:50 2001
@@ -164,15 +164,15 @@
 	Modem   = rio_ismodem (tty->device);
 
 	if ( p->RIOFailed ) {
-		rio_dprint(RIO_DEBUG_TTY, ("System initialisation failed\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "System initialisation failed\n");
 		pseterr(ENXIO);
 		func_exit ();
 		return -ENXIO;
 	}
 
-	rio_dprint(RIO_DEBUG_TTY, ("port open SysPort %d (%s) (mapped:%d)\n",
+	rio_dprintk (RIO_DEBUG_TTY, "port open SysPort %d (%s) (mapped:%d)\n",
 	       SysPort,  Modem ? "Modem" : "tty",
-				   p->RIOPortp[SysPort]->Mapped  ) );
+				   p->RIOPortp[SysPort]->Mapped);
 
 	/*
 	** Validate that we have received a legitimate request.
@@ -181,7 +181,7 @@
 	** has been mapped onto a host.
 	*/
 	if (SysPort >= RIO_PORTS) {	/* out of range ? */
-		rio_dprint(RIO_DEBUG_TTY, ("Illegal port number %d\n",SysPort));
+		rio_dprintk (RIO_DEBUG_TTY, "Illegal port number %d\n",SysPort);
 		pseterr(ENXIO);
 		func_exit();
 		return -ENXIO;
@@ -197,7 +197,7 @@
 		** The system doesn't know which RTA this port
 		** corresponds to.
 		*/
-		rio_dprint(RIO_DEBUG_TTY, ("port not mapped into system\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "port not mapped into system\n");
 		func_exit ();
 		pseterr(ENXIO);
 		return -ENXIO;
@@ -206,17 +206,26 @@
 	tty->driver_data = PortP;
 
 	PortP->gs.tty = tty;
+	if (!PortP->gs.count)
+		rio_inc_mod_count ();
 	PortP->gs.count++;
-	rio_dprint(RIO_DEBUG_TTY, ("%d bytes in tx buffer\n",
-				   PortP->gs.xmit_cnt));
-	gs_init_port (&PortP->gs);
 
+	rio_dprintk (RIO_DEBUG_TTY, "%d bytes in tx buffer\n",
+				   PortP->gs.xmit_cnt);
+
+	retval = gs_init_port (&PortP->gs);
+	if (retval) {
+		PortP->gs.count--;
+		if (PortP->gs.count)
+			rio_dec_mod_count ();
+		return -ENXIO;
+	}
 	/*
 	** If the host hasn't been booted yet, then 
 	** fail
 	*/
 	if ( (PortP->HostP->Flags & RUN_STATE) != RC_RUNNING ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Host not running\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Host not running\n");
 		pseterr(ENXIO);
 		func_exit ();
 		return -ENXIO;
@@ -230,24 +239,24 @@
 #if 0
 	if (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
 		if (PortP->WaitUntilBooted) {
-			rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot\n");
 			do {
 				if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
-					rio_dprint(RIO_DEBUG_TTY, ("RTA EINTR in delay \n"));
+					rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");
 					func_exit ();
 					return -EINTR;
 				}
 				if (repeat_this -- <= 0) {
-					rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot timeout\n"));
+					rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");
 					RIOPreemptiveCmd(p, PortP, FCLOSE ); 
 					pseterr(EINTR);
 					func_exit ();
 					return -EIO;
 				}
 			} while(!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED));
-			rio_dprint(RIO_DEBUG_TTY, ("RTA has been booted\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "RTA has been booted\n");
 		} else {
-			rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "RTA never booted\n");
 			pseterr(ENXIO);
 			func_exit ();
 			return 0;
@@ -258,10 +267,10 @@
            easier to read and shorter. Now, if it works too that would
 	   be great... -- REW 
 	*/
-	rio_dprint(RIO_DEBUG_TTY, ("Checking if RTA has booted... \n"));
+	rio_dprintk (RIO_DEBUG_TTY, "Checking if RTA has booted... \n");
 	while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
 	  if (!PortP->WaitUntilBooted) {
-	    rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n"));
+	    rio_dprintk (RIO_DEBUG_TTY, "RTA never booted\n");
 	    func_exit ();
 	    return -ENXIO;
 	  }
@@ -271,17 +280,17 @@
 	     now. --REW 
 	  */
 	  if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
-	    rio_dprint(RIO_DEBUG_TTY, ("RTA_wait_for_boot: EINTR in delay \n"));
+	    rio_dprintk (RIO_DEBUG_TTY, "RTA_wait_for_boot: EINTR in delay \n");
 	    func_exit ();
 	    return -EINTR;
 	  }
 	  if (repeat_this -- <= 0) {
-	    rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot timeout\n"));
+	    rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");
 	    func_exit ();
 	    return -EIO;
 	  }
 	}
-	rio_dprint(RIO_DEBUG_TTY, ("RTA has been booted\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "RTA has been booted\n");
 #endif
 #if 0
 	tp =  PortP->TtyP;		/* get tty struct */
@@ -304,9 +313,9 @@
 	** for it to finish, so that it doesn't close us!
 	*/
 	while ( (PortP->State & RIO_CLOSING) && !p->RIOHalted ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Waiting for RIO_CLOSING to go away\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n");
 		if (repeat_this -- <= 0) {
-			rio_dprint(RIO_DEBUG_TTY, ("Waiting for not idle closed broken by signal\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
 			RIOPreemptiveCmd(p, PortP, FCLOSE ); 
 			retval = -EINTR;
 			goto bombout;
@@ -321,7 +330,7 @@
 	}
 
 	if ( !PortP->Mapped ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Port unmapped while closing!\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Port unmapped while closing!\n");
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 		retval = -ENXIO;
 		func_exit ();
@@ -344,8 +353,8 @@
 	}
 
 	if (!(PortP->firstOpen)) {	/* First time ? */
-		rio_dprint(RIO_DEBUG_TTY, ("First open for this port\n"));
-		rio_inc_mod_count ();
+		rio_dprintk (RIO_DEBUG_TTY, "First open for this port\n");
+	
 
 		PortP->firstOpen++;
 		PortP->CookMode = 0; /* XXX RIOCookMode(tp); */
@@ -375,7 +384,7 @@
 		** wait for the port to be not closed.
 		*/
 		while ( !(PortP->PortState & PORT_ISOPEN) && !p->RIOHalted ) {
-			rio_dprint(RIO_DEBUG_TTY, ("Waiting for PORT_ISOPEN-currently %x\n",PortP->PortState));
+			rio_dprintk (RIO_DEBUG_TTY, "Waiting for PORT_ISOPEN-currently %x\n",PortP->PortState);
 /*
 ** 15.10.1998 ARG - ESIL 0759
 ** (Part) fix for port being trashed when opened whilst RTA "disconnected"
@@ -392,7 +401,7 @@
 */
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
-				rio_dprint(RIO_DEBUG_TTY, ("Waiting for open to finish broken by signal\n"));
+				rio_dprintk (RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n");
 				RIOPreemptiveCmd(p, PortP, FCLOSE );
 				func_exit ();
 				return -EINTR;
@@ -407,52 +416,67 @@
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return retval;
 		}
-		rio_dprint(RIO_DEBUG_TTY, ("PORT_ISOPEN found\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "PORT_ISOPEN found\n");
 	}
 
 #ifdef MODEM_SUPPORT 
 	if (Modem) {
-		rio_dprint(RIO_DEBUG_TTY, ("Modem - test for carrier\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Modem - test for carrier\n");
 		/*
 		** ACTION
 		** insert test for carrier here. -- ???
 		** I already see that test here. What's the deal? -- REW
 		*/
-		if ((tp->tm.c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD))
+		if ((PortP->gs.tty->termios->c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD))
 		{
-			rio_dprint(RIO_DEBUG_TTY, (PortP,DBG_OPEN,"open(%d) Modem carr on\n",SysPort));
+			rio_dprintk (RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort);
+			/*
 			tp->tm.c_state |= CARR_ON;
 			wakeup((caddr_t) &tp->tm.c_canq);
+			*/
+			PortP->State |= RIO_CARR_ON;
+			wake_up_interruptible (&PortP->gs.open_wait);
 		}
 		else /* no carrier - wait for DCD */
 		{
-			while (!(tp->tm.c_state&CARR_ON) && 
-			       !(filp->f_flags&O_NONBLOCK) && !p->RIOHalted )
-			{
-				rio_dprint(RIO_DEBUG_TTY, (PortP,DBG_OPEN,"open(%d) sleeping for carr on\n",SysPort));
-				tp->tm.c_state |= WOPEN;
+		  /*
+			while (!(PortP->gs.tty->termios->c_state & CARR_ON) && 
+			       !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted )
+		  */
+			while (!(PortP->State & RIO_CARR_ON) && 
+			       !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted ) {
+
+				rio_dprintk (RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n",SysPort);
+				/*
+				PortP->gs.tty->termios->c_state |= WOPEN;
+				*/
 				PortP->State |= RIO_WOPEN;
-				if ( sleep((caddr_t)&tp->tm.c_canq, TTIPRI|PCATCH))
+#if 0
+				if ( sleep((caddr_t)&tp->tm.c_canqo, TTIPRI|PCATCH))
 				{
 					/*
 					** ACTION: verify that this is a good thing
 					** to do here. -- ???
 					** I think it's OK. -- REW
 					*/
-					rio_dprint(RIO_DEBUG_TTY, ("open(%d) sleeping for carr broken by signal\n",
-					       SysPort));
+					rio_dprintk (RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n",
+					       SysPort);
 					RIOPreemptiveCmd( p, PortP, FCLOSE );
+					/*
 					tp->tm.c_state &= ~WOPEN;
+					*/
 					PortP->State &= ~RIO_WOPEN;
 					rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 					func_exit ();
 					return -EINTR;
 				}
+#endif
 			}
 			PortP->State &= ~RIO_WOPEN;
 		}
-		if ( RIOHalted )
+		if ( p->RIOHalted )
 			goto bombout;
+		rio_dprintk (RIO_DEBUG_TTY, "Setting RIO_MOPEN\n");
 		PortP->State |= RIO_MOPEN;
 	}
 	else
@@ -470,7 +494,7 @@
 		goto bombout;
 	}
 
-	rio_dprint(RIO_DEBUG_TTY, ("high level open done\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "high level open done\n");
 
 #ifdef STATS
 	PortP->Stat.OpenCnt++;
@@ -482,7 +506,7 @@
 		PortP->opens++;
 
 	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
-	rio_dprint(RIO_DEBUG_TTY, ("Returning from open\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "Returning from open\n");
 	func_exit ();
 	return 0;
 }
@@ -509,13 +533,13 @@
 	int Modem;
 	int rv =0;
 	
-	rio_dprint(RIO_DEBUG_TTY, ("port close SysPort %d\n",PortP->PortNum));
+	rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum);
 
 	/* PortP = p->RIOPortp[SysPort]; */
-	rio_dprint(RIO_DEBUG_TTY, ("Port is at address 0x%x\n",(int)PortP));
+	rio_dprintk (RIO_DEBUG_TTY, "Port is at address 0x%x\n",(int)PortP);
 	/* tp = PortP->TtyP;*/			/* Get tty */
 	tty = PortP->gs.tty;
-	rio_dprint(RIO_DEBUG_TTY, ("TTY is at address 0x%x\n",(int)tty));
+	rio_dprintk (RIO_DEBUG_TTY, "TTY is at address 0x%x\n",(int)tty);
 	Modem = rio_ismodem(tty->device);
 #if 0
 	/* What F.CKING cache? Even then, a higly idle multiprocessor,
@@ -533,7 +557,7 @@
 	PortP->State |= RIO_CLOSING;
 
 	if ( (PortP->State & RIO_DELETED) ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Close on deleted RTA\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Close on deleted RTA\n");
 		deleted = 1;
 	}
 	
@@ -543,7 +567,7 @@
 		goto close_end;
 	}
 
-	rio_dprint(RIO_DEBUG_TTY, ("Clear bits\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "Clear bits\n");
 	/*
 	** clear the open bits for this device
 	*/
@@ -561,7 +585,7 @@
 		** The port is still open for the other task -
 		** return, pretending that we are still active.
 		*/
-		rio_dprint(RIO_DEBUG_TTY, ("Channel %d still open !\n",PortP->PortNum));
+		rio_dprintk (RIO_DEBUG_TTY, "Channel %d still open !\n",PortP->PortNum);
 		PortP->State &= ~RIO_CLOSING;
 		if (PortP->firstOpen)
 			PortP->firstOpen--;
@@ -569,7 +593,7 @@
 		return -EIO;
 	}
 
-	rio_dprint(RIO_DEBUG_TTY, ("Closing down - everything must go!\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "Closing down - everything must go!\n");
 
 	PortP->State &= ~RIO_DYNOROD;
 
@@ -578,7 +602,7 @@
 	** to drain down before closing. Bye-bye....
 	** (We never meant to do this)
 	*/
-	rio_dprint(RIO_DEBUG_TTY, ("Timeout 1 starts\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "Timeout 1 starts\n");
 
 #if 0
 	if (!deleted)
@@ -587,14 +611,14 @@
 		cprintf("Need to flush the ttyport\n");
 		if (repeat_this -- <= 0) {
 			rv = -EINTR;
-			rio_dprint(RIO_DEBUG_TTY, ("Waiting for not idle closed broken by signal\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
 			RIOPreemptiveCmd(p, PortP, FCLOSE ); 
 			goto close_end;
 		}
-		rio_dprint(RIO_DEBUG_TTY, ("Calling timeout to flush in closing\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n");
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 		if (RIODelay_ni(PortP, HUNDRED_MS*10) == RIO_FAIL) {
-			rio_dprint(RIO_DEBUG_TTY, ("RTA EINTR in delay \n"));
+			rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");
 			rv = -EINTR;
 			rio_spin_lock_irqsave(&PortP->portSem, flags);
 			goto close_end;
@@ -611,7 +635,7 @@
 		** The port has been re-opened for the other task -
 		** return, pretending that we are still active.
 		*/
-		rio_dprint(RIO_DEBUG_TTY, ("Channel %d re-open!\n", PortP->PortNum));
+		rio_dprintk (RIO_DEBUG_TTY, "Channel %d re-open!\n", PortP->PortNum);
 		PortP->State &= ~RIO_CLOSING;
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 		if (PortP->firstOpen)
@@ -638,12 +662,12 @@
 	  while (try && (PortP->PortState & PORT_ISOPEN)) {
 	        try--;
 		if (try == 0) {
-		  rio_dprint(RIO_DEBUG_TTY, ("Run out of tries - force the bugger shut!\n" ));
+		  rio_dprintk (RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n" );
 		  RIOPreemptiveCmd(p, PortP,FCLOSE);
 		  break;
 		}
-		rio_dprint(RIO_DEBUG_TTY, ("Close: PortState:ISOPEN is %d\n", 
-					   PortP->PortState & PORT_ISOPEN));
+		rio_dprintk (RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n", 
+					   PortP->PortState & PORT_ISOPEN);
 
 		if ( p->RIOHalted ) {
 			RIOClearUp( PortP );
@@ -652,7 +676,7 @@
 		RIODelay_ni(PortP, HUNDRED_MS);
 	}
 	rio_spin_lock_irqsave(&PortP->portSem, flags);
-	rio_dprint(RIO_DEBUG_TTY, ("Close: try was %d on completion\n", try ));
+	rio_dprintk (RIO_DEBUG_TTY, "Close: try was %d on completion\n", try );
  
 	/* RIOPreemptiveCmd(p, PortP, FCLOSE); */
 
@@ -682,7 +706,7 @@
 	if (PortP->firstOpen)
 		PortP->firstOpen--;
 	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
-	rio_dprint(RIO_DEBUG_TTY, ("Return from close\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "Return from close\n");
 	return rv;
 }
 
@@ -731,7 +755,7 @@
 RIOClearUp(PortP)
 struct Port *PortP;
 {
-	rio_dprint(RIO_DEBUG_TTY, ("RIOHalted set\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "RIOHalted set\n");
 	PortP->Config = 0;	  /* Direct semaphore */
 	PortP->PortState = 0;
 	PortP->firstOpen = 0;
@@ -761,7 +785,7 @@
 	int		retries = 20; /* at 10 per second -> 2 seconds */
 	unsigned long flags;
 
-	rio_dprint(RIO_DEBUG_TTY, ("entering shortcommand.\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "entering shortcommand.\n");
 #ifdef CHECK
 	CheckPortP( PortP );
 	if ( len < 1 || len > 2 )
@@ -769,7 +793,7 @@
 #endif
 
 	if ( PortP->State & RIO_DELETED ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Short command to deleted RTA ignored\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
 		return RIO_FAIL;
 	}
 	rio_spin_lock_irqsave(&PortP->portSem, flags);
@@ -779,8 +803,8 @@
 	** be free again.
 	*/
 	while ( (PortP->InUse != NOT_INUSE) && !p->RIOHalted ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Waiting for not in use (%d)\n", 
-					   retries));
+		rio_dprintk (RIO_DEBUG_TTY, "Waiting for not in use (%d)\n", 
+					   retries);
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 		if (retries-- <= 0) {
 			return RIO_FAIL;
@@ -791,16 +815,16 @@
 		rio_spin_lock_irqsave(&PortP->portSem, flags);
 	}
 	if ( PortP->State & RIO_DELETED ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Short command to deleted RTA ignored\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 		return RIO_FAIL;
 	}
 
 	while ( !can_add_transmit(&PacketP,PortP) && !p->RIOHalted ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Waiting to add short command to queue (%d)\n", retries));
+		rio_dprintk (RIO_DEBUG_TTY, "Waiting to add short command to queue (%d)\n", retries);
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 		if (retries-- <= 0) {
-		  rio_dprint(RIO_DEBUG_TTY, ("out of tries. Failing\n"));
+		  rio_dprintk (RIO_DEBUG_TTY, "out of tries. Failing\n");
 			return RIO_FAIL;
 		}
 		if ( RIODelay_ni(PortP, HUNDRED_MS)==RIO_FAIL ) {
@@ -865,11 +889,11 @@
 	int					Modem = rio_ismodem(dev);
 	int					ioctl_processed;
 
-	rio_dprint(RIO_DEBUG_TTY, ("port ioctl SysPort %d command 0x%x argument 0x%x %s\n",
-			SysPort,cmd,arg,Modem?"Modem":"tty"));
+	rio_dprintk (RIO_DEBUG_TTY, "port ioctl SysPort %d command 0x%x argument 0x%x %s\n",
+			SysPort, cmd, arg, Modem?"Modem":"tty") ;
 
 	if ( SysPort >= RIO_PORTS ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Bad port number %d\n",SysPort));
+		rio_dprintk (RIO_DEBUG_TTY, "Bad port number %d\n", SysPort);
 		return -ENXIO;
 	}
 
@@ -926,22 +950,22 @@
 			return 0;
 
 		case TCRIOTSTATE:
-			rio_dprint(RIO_DEBUG_TTY, ("tbusy/tstop monitoring %sabled\n",
-		 		arg ? "en" : "dis"));
+			rio_dprintk (RIO_DEBUG_TTY, "tbusy/tstop monitoring %sabled\n",
+		 		arg ? "en" : "dis");
 			/* MonitorTstate = 0 ;*/
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			RIOParam(PortP, CONFIG, Modem, OK_TO_SLEEP);
 			return 0;
 
 		case TCRIOSTATE: /* current state of Modem input pins */
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOSTATE\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOSTATE\n");
 			if (RIOPreemptiveCmd(p, PortP, MGET) == RIO_FAIL)
-				rio_dprint(RIO_DEBUG_TTY, ("TCRIOSTATE command failed\n"));
+				rio_dprintk (RIO_DEBUG_TTY, "TCRIOSTATE command failed\n");
 			PortP->State |= RIO_BUSY;
 			current = PortP->ModemState;
 			if ( copyout((caddr_t)&current, (int)arg,
 							sizeof(current))==COPYFAIL ) {
-				rio_dprint(RIO_DEBUG_TTY, ("Copyout failed\n"));
+				rio_dprintk (RIO_DEBUG_TTY, "Copyout failed\n");
 				rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 				pseterr(EFAULT);
 			}
@@ -950,15 +974,15 @@
 
 		case TCRIOMBIS:		/* Set modem lines */
 		case TCRIOMBIC:		/* Clear modem lines */
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOMBIS/TCRIOMBIC\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOMBIS/TCRIOMBIC\n");
 			if (cmd == TCRIOMBIS) {
 				uint		state;
 				state = (uint)arg;
 				PortP->ModemState |= (ushort)state;
 				PortP->ModemLines = (ulong) arg;
 				if (RIOPreemptiveCmd(p, PortP, MBIS) == RIO_FAIL)
-					rio_dprint(RIO_DEBUG_TTY, (
-					 "TCRIOMBIS command failed\n"));
+					rio_dprintk (RIO_DEBUG_TTY, 
+					 "TCRIOMBIS command failed\n");
 			}
 			else {
 				uint		state;
@@ -967,17 +991,17 @@
 				PortP->ModemState &= ~(ushort)state;
 				PortP->ModemLines = (ulong) arg;
 				if (RIOPreemptiveCmd(p, PortP, MBIC) == RIO_FAIL)
-					rio_dprint(RIO_DEBUG_TTY, ("TCRIOMBIC command failed\n"));
+					rio_dprintk (RIO_DEBUG_TTY, "TCRIOMBIC command failed\n");
 			}
 			PortP->State |= RIO_BUSY;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return 0;
 
 		case TCRIOXPON: /* set Xprint ON string */
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOXPON\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPON\n");
 			if ( copyin((int)arg, (caddr_t)PortP->Xprint.XpOn,
 						MAX_XP_CTRL_LEN)==COPYFAIL ) {
-				rio_dprint(RIO_DEBUG_TTY, ("Copyin failed\n"));
+				rio_dprintk (RIO_DEBUG_TTY, "Copyin failed\n");
 				PortP->Xprint.XpOn[0] = '\0';
 				rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 				pseterr(EFAULT);
@@ -989,10 +1013,10 @@
 			return 0;
 
 		case TCRIOXPOFF: /* set Xprint OFF string */
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOXPOFF\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPOFF\n");
 			if ( copyin( (int)arg, (caddr_t)PortP->Xprint.XpOff,
 						MAX_XP_CTRL_LEN)==COPYFAIL ) {
-				rio_dprint(RIO_DEBUG_TTY, ("Copyin failed\n"));
+				rio_dprintk (RIO_DEBUG_TTY, "Copyin failed\n");
 				PortP->Xprint.XpOff[0] = '\0';
 				rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 				pseterr(EFAULT);
@@ -1004,10 +1028,10 @@
 			return 0;
 
 		case TCRIOXPCPS: /* set Xprint CPS string */
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOXPCPS\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPCPS\n");
 			if ( (uint)arg > p->RIOConf.MaxXpCps || 
 					(uint)arg < p->RIOConf.MinXpCps ) {
-				rio_dprint(RIO_DEBUG_TTY, ("%d CPS out of range\n",arg));
+				rio_dprintk (RIO_DEBUG_TTY, "%d CPS out of range\n",arg);
 				rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 				pseterr(EINVAL);
 				return 0;
@@ -1017,7 +1041,7 @@
 			return 0;
 
 		case TCRIOXPRINT:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOXPRINT\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPRINT\n");
 			if ( copyout((caddr_t)&PortP->Xprint, (int)arg,
 					sizeof(struct Xprint))==COPYFAIL ) {
 			        rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -1027,25 +1051,25 @@
 			return 0;
 
 		case TCRIOIXANYON:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOIXANYON\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXANYON\n");
 			PortP->Config |= RIO_IXANY;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return 0;
 
 		case TCRIOIXANYOFF:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOIXANYOFF\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXANYOFF\n");
 			PortP->Config &= ~RIO_IXANY;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return 0;
 
 		case TCRIOIXONON:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOIXONON\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXONON\n");
 			PortP->Config |= RIO_IXON;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return 0;
 
 		case TCRIOIXONOFF:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOIXONOFF\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXONOFF\n");
 			PortP->Config &= ~RIO_IXON;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return 0;
@@ -1055,28 +1079,28 @@
 ** Added support for CTS and RTS flow control ioctls :
 */
 		case TCRIOCTSFLOWEN:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOCTSFLOWEN\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOCTSFLOWEN\n");
 			PortP->Config |= RIO_CTSFLOW;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);	
 			return 0;
 
 		case TCRIOCTSFLOWDIS:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOCTSFLOWDIS\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOCTSFLOWDIS\n");
 			PortP->Config &= ~RIO_CTSFLOW;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);	
 			return 0;
 
 		case TCRIORTSFLOWEN:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIORTSFLOWEN\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIORTSFLOWEN\n");
 			PortP->Config |= RIO_RTSFLOW;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);	
 			return 0;
 
 		case TCRIORTSFLOWDIS:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIORTSFLOWDIS\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIORTSFLOWDIS\n");
 			PortP->Config &= ~RIO_RTSFLOW;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);	
@@ -1100,13 +1124,13 @@
 		case TCSETAW:
 		case TCSETAF:
 			ioctl_processed++;
-			rio_dprint(RIO_DEBUG_TTY, ("NON POSIX ioctl\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "NON POSIX ioctl\n");
 			ttyseth_pv(PortP, tp, (struct termios *)arg, 0);
 			break;
 		case TCSETAP:	/* posix tcsetattr() */
 		case TCSETAWP:	/* posix tcsetattr() */
 		case TCSETAFP:	/* posix tcsetattr() */
-			rio_dprint(RIO_DEBUG_TTY, ("NON POSIX SYSV ioctl\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "NON POSIX SYSV ioctl\n");
 			ttyseth_pv(PortP, tp, (struct termios *)arg, 1);
 			ioctl_processed++;
 			break;
@@ -1141,7 +1165,7 @@
 #endif
 		case TIOCSETD:
 		case TIOCSETN:
-			rio_dprint(RIO_DEBUG_TTY, ("wait for non-BUSY, semaphore set\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "wait for non-BUSY, semaphore set\n");
 			/*
 			** Wait for drain here, at least as far as the double buffer
 			** being empty.
@@ -1208,8 +1232,8 @@
 
 	PortP->CookMode = RIOCookMode(tp);	/* Set new cooking mode */
 
-	rio_dprint(RIO_DEBUG_TTY, ("RIOIoctl changed %d newcook %d oldcook %d\n",
-			changed,PortP->CookMode,oldcook));
+	rio_dprintk (RIO_DEBUG_TTY, "RIOIoctl changed %d newcook %d oldcook %d\n",
+			changed,PortP->CookMode,oldcook);
 
 #ifdef MODEM_SUPPORT
 	/*
@@ -1232,7 +1256,7 @@
 	*/
 	if (changed || oldcook != PortP->CookMode || (ioctl_processed)) {
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
-		rio_dprint(RIO_DEBUG_TTY, ("Ioctl changing the PORT settings\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Ioctl changing the PORT settings\n");
 		RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);	
 		rio_spin_lock_irqsave(&PortP->portSem, flags);
 	}
diff -urN linux-2.2.17-pre15/drivers/macintosh/via-pmu.c linux/drivers/macintosh/via-pmu.c
--- linux-2.2.17-pre15/drivers/macintosh/via-pmu.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/macintosh/via-pmu.c	Mon Dec  3 22:10:50 2001
@@ -1,4 +1,3 @@
-
 /*
  * Device driver for the via-pmu on Apple Powermacs.
  *
@@ -107,7 +106,6 @@
 static int pmu_has_adb, pmu_has_backlight;
 static unsigned char *gpio_reg = NULL;
 static int gpio_irq = -1;
-static int irq_flag = 0;
 
 int asleep;
 
@@ -345,6 +343,13 @@
 		udelay(10);
 	}
 
+	/* Tell PMU we are ready. Which PMU support this ? */
+	if (pmu_kind == PMU_KEYLARGO_BASED) {
+		pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
+		while (!req.complete)
+			pmu_poll();
+	}
+
 	return 1;
 }
 
@@ -564,6 +569,19 @@
 	return 0;
 }
 
+static void __openfirmware
+wait_for_ack(void)
+{
+	int timeout = 3200;
+	while ((in_8(&via[B]) & TACK) == 0) {
+		if (--timeout < 0) {
+			printk(KERN_ERR "PMU not responding (!ack)\n");
+			return;
+		}
+		udelay(10);
+	}
+}
+
 /* New PMU seems to be very sensitive to those timings, so we make sure
  * PCI is flushed immediately */
 static void __openfirmware
@@ -610,6 +628,7 @@
 
 	/* set the shift register to shift out and send a byte */
 	++disable_poll;
+	wait_for_ack();
 	send_byte(req->data[0]);
 	--disable_poll;
 
@@ -631,6 +650,26 @@
 	_enable_interrupts(ie);
 }
 
+/* This function loops until the PMU is idle, to avoid spurrious shutdowns
+ * when prom.c scrollscreen or xmon spends too much time without interupts
+ * while some PMU communication is going on
+ */
+void __openfirmware
+pmu_safe_poll(void)
+{
+	int ie;
+
+	if (!via || disable_poll)
+		return;
+	do {
+		ie = _disable_interrupts();
+		if ((via[IFR] & (SR_INT | CB1_INT)) ||
+			(gpio_reg && (in_8(gpio_reg + 0x9) & 0x02) == 0))
+			via_pmu_interrupt(0, 0, 0);
+		_enable_interrupts(ie);
+	} while (adb_int_pending || pmu_state != idle);
+}
+
 static void __openfirmware
 via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
 {
@@ -638,47 +677,43 @@
 	int nloop = 0;
 	unsigned long flags;
 
-	/* This is my 2 cents brain dead synchronisation mecanism */
-	if (test_and_set_bit(0, &irq_flag))
-		return;
-
-	while(test_and_clear_bit(0, &irq_flag)) {
-		++disable_poll;
-		while ((intr = in_8(&via[IFR])) != 0) {
-			if (++nloop > 1000) {
-				printk(KERN_DEBUG "PMU: stuck in intr loop, "
-				       "intr=%x pmu_state=%d\n", intr, pmu_state);
-				break;
-			}
-			if (intr & SR_INT)
-				pmu_sr_intr(regs);
-			else if (intr & CB1_INT) {
-				adb_int_pending = 1;
-				out_8(&via[IFR], CB1_INT);
-			}
-			intr &= ~(SR_INT | CB1_INT);
-			if (intr != 0) {
-				out_8(&via[IFR], intr);
-			}
+	/* Currently, we use brute-force cli() for syncing with GPIO
+	 * interrupt. I'll make this smarter later, along with some
+	 * spinlocks for SMP */
+	save_flags(flags);cli();
+	++disable_poll;
+	while ((intr = in_8(&via[IFR])) != 0) {
+		if (++nloop > 1000) {
+			printk(KERN_DEBUG "PMU: stuck in intr loop, "
+			       "intr=%x pmu_state=%d\n", intr, pmu_state);
+			break;
 		}
-		if (gpio_reg && (in_8(gpio_reg + 0x9) & 0x02) == 0)
+		if (intr & SR_INT)
+			pmu_sr_intr(regs);
+		else if (intr & CB1_INT) {
 			adb_int_pending = 1;
-
-		/* A spinlock would be nicer ... */
-		save_flags(flags);
-		cli();
-		if (pmu_state == idle) {
-			if (adb_int_pending) {
-				pmu_state = intack;
-				send_byte(PMU_INT_ACK);
-				adb_int_pending = 0;
-			} else if (current_req) {
-				pmu_start();
-			}
+			out_8(&via[IFR], CB1_INT);
+		}
+		intr &= ~(SR_INT | CB1_INT);
+		if (intr != 0) {
+			out_8(&via[IFR], intr);
+		}
+	}
+	if (gpio_reg && (in_8(gpio_reg + 0x9) & 0x02) == 0)
+		adb_int_pending = 1;
+
+	if (pmu_state == idle) {
+		if (adb_int_pending) {
+			pmu_state = intack;
+			wait_for_ack();
+			send_byte(PMU_INT_ACK);
+			adb_int_pending = 0;
+		} else if (current_req) {
+			pmu_start();
 		}
-		restore_flags(flags);
-		--disable_poll;
 	}
+	--disable_poll;
+	restore_flags(flags);
 }
 
 
@@ -686,13 +721,13 @@
 gpio1_interrupt(int irq, void *arg, struct pt_regs *regs)
 {
 	via_pmu_interrupt(0, 0, 0);
- }
- 
+}
+
 static void __openfirmware
 pmu_sr_intr(struct pt_regs *regs)
 {
 	struct adb_request *req;
-	int bite, timeout;
+	int bite;
 
 	if (via[B] & TREQ) {
 		printk(KERN_ERR "PMU: spurious SR intr (%x)\n", via[B]);
@@ -705,26 +740,16 @@
 	if (via[B] & TACK) {
 		while ((in_8(&via[B]) & TACK) != 0)
 			;
-#if 0
-		printk(KERN_ERR "PMU: sr_intr but ack still high! (%x)\n",
-		       via[B]);
-#endif
 	}
 
 	/* reset TREQ and wait for TACK to go high */
 	out_8(&via[B], in_8(&via[B]) | TREQ);
-	timeout = 3200;
-	while ((in_8(&via[B]) & TACK) == 0) {
-		if (--timeout < 0) {
-			printk(KERN_ERR "PMU not responding (!ack)\n");
-			return;
-		}
-		udelay(10);
-	}
+	wait_for_ack();
 
 	/* if reading grab the byte, and reset the interrupt */
 	if (pmu_state == reading || pmu_state == reading_intr)
 		bite = in_8(&via[SR]);
+
 	out_8(&via[IFR], SR_INT);
 
 	switch (pmu_state) {
@@ -951,6 +976,8 @@
 	struct adb_request req;
 
 	if (vias == NULL)
+		return ;
+	if (pmu_kind == PMU_KEYLARGO_BASED)
 		return ;
 
 	pmu_request(&req, NULL, 2, PMU_POWER_CTRL, PMU_POW_IRLED |
diff -urN linux-2.2.17-pre15/drivers/net/3c59x.c linux/drivers/net/3c59x.c
--- linux-2.2.17-pre15/drivers/net/3c59x.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/net/3c59x.c	Mon Dec  3 22:10:50 2001
@@ -51,11 +51,14 @@
     - Fixed crash under OOM during vortex_open() (Mark Hemment)
     - Fix Rx cessation problem during OOM (help from Mark Hemment)
 
+    01Aug00 <2.2.17-pre14> andrewm
+    - Added 3c556 support (Fred Maciel)
+
     - See http://www.uow.edu.au/~andrewm/linux/#3c59x-2.2 for more details.
 */
 
 static char *version =
-"3c59x.c:v0.99H 24Jun00 Donald Becker and others http://www.scyld.com/network/vortex.html\n";
+"3c59x.c:v0.99H 01Aug00 Donald Becker and others http://www.scyld.com/network/vortex.html\n";
 
 /* "Knobs" that adjust features and parameters. */
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
@@ -325,6 +328,8 @@
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1},
 	{"3c555 Laptop Hurricane",	0x10B7, 0x5055, 0xffff,
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1},
+	{"3c556 10/100 Mini PCI Adapter",	0x10B7, 0x6055, 0xffff,
+	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_CB_FNS, 128, vortex_probe1},
 	{"3c575 Boomerang CardBus",		0x10B7, 0x5057, 0xffff,
 	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, vortex_probe1},
 	{"3CCFE575 Cyclone CardBus",	0x10B7, 0x5157, 0xffff,
@@ -915,7 +920,11 @@
 #ifdef CARDBUS
 		outw(0x230 + i, ioaddr + Wn0EepromCmd);
 #else
-		outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd);
+		if (pci_tbl[chip_idx].device_id == 0x6055) {
+			outw(0x230 + i, ioaddr + Wn0EepromCmd);
+		} else {
+			outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd);
+		}
 #endif
 		/* Pause for at least 162 us. for the read to take place. */
 		for (timer = 10; timer >= 0; timer--) {
@@ -959,7 +968,11 @@
 		printk("%s: CardBus functions mapped %8.8x->%p (PCMCIA committee"
 			   " brain-damage).\n", dev->name, fn_st_addr, vp->cb_fn_base);
 		EL3WINDOW(2);
-		outw(0x10 | inw(ioaddr + Wn2_ResetOptions), ioaddr + Wn2_ResetOptions);
+		if (pci_tbl[chip_idx].device_id == 0x6055) {
+			outw(0x4010 | inw(ioaddr + Wn2_ResetOptions), ioaddr + Wn2_ResetOptions);
+		} else {
+			outw(0x10 | inw(ioaddr + Wn2_ResetOptions), ioaddr + Wn2_ResetOptions);
+		}
 	}
 
 	/* Extract our information from the EEPROM data. */
diff -urN linux-2.2.17-pre15/drivers/net/at1700.c linux/drivers/net/at1700.c
--- linux-2.2.17-pre15/drivers/net/at1700.c	Tue Jan 19 10:51:24 1999
+++ linux/drivers/net/at1700.c	Mon Dec  3 22:10:50 2001
@@ -557,7 +557,8 @@
 		/* ToDo: We should try to restart the adaptor... */
 		outw(0xffff, ioaddr + 24);
 		outw(0xffff, ioaddr + TX_STATUS);
-		outw(0xe85a, ioaddr + CONFIG_0);
+		outw(0x5a, ioaddr + CONFIG_0);
+		outw(0xe8, ioaddr + CONFIG_1);
 		outw(0x8182, ioaddr + TX_INTR);
 		outb(0x00, ioaddr + TX_START);
 		outb(0x03, ioaddr + COL16CNTL);
diff -urN linux-2.2.17-pre15/drivers/net/bmac.c linux/drivers/net/bmac.c
--- linux-2.2.17-pre15/drivers/net/bmac.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/net/bmac.c	Mon Dec  3 22:10:50 2001
@@ -1628,9 +1628,9 @@
     bp = (struct bmac_data *) bmac_devs->priv;
     unregister_netdev(bmac_devs);
 
-    free_irq(bmac_devs->irq, dev);
-    free_irq(bp->tx_dma_intr, dev);
-    free_irq(bp->rx_dma_intr, dev);
+    free_irq(bmac_devs->irq, bmac_devs);
+    free_irq(bp->tx_dma_intr, bmac_devs);
+    free_irq(bp->rx_dma_intr, bmac_devs);
 
 #ifdef CONFIG_PMAC_PBOOK
     pmu_unregister_sleep_notifier(&bmac_sleep_notifier);
diff -urN linux-2.2.17-pre15/drivers/net/eepro100.c linux/drivers/net/eepro100.c
--- linux-2.2.17-pre15/drivers/net/eepro100.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/net/eepro100.c	Mon Dec  3 22:10:50 2001
@@ -1,3 +1,5 @@
+#define USE_IO
+
 /* drivers/net/eepro100.c: An Intel i82557-559 Ethernet driver for Linux. */
 /*
    NOTICE: this version of the driver is supposed to work with 2.2 kernels.
diff -urN linux-2.2.17-pre15/drivers/net/mace.c linux/drivers/net/mace.c
--- linux-2.2.17-pre15/drivers/net/mace.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/net/mace.c	Mon Dec  3 22:10:50 2001
@@ -926,9 +926,9 @@
     struct mace_data *mp = (struct mace_data *) mace_devs->priv;
     unregister_netdev(mace_devs);
 
-    free_irq(mace_devs->irq, dev);
-    free_irq(mp->tx_dma_intr, dev);
-    free_irq(mp->rx_dma_intr, dev);
+    free_irq(mace_devs->irq, mace_devs);
+    free_irq(mp->tx_dma_intr, mace_devs);
+    free_irq(mp->rx_dma_intr, mace_devs);
 
     kfree(mace_devs);
     mace_devs = NULL;
diff -urN linux-2.2.17-pre15/drivers/pci/oldproc.c linux/drivers/pci/oldproc.c
--- linux-2.2.17-pre15/drivers/pci/oldproc.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/pci/oldproc.c	Mon Dec  3 22:10:50 2001
@@ -225,9 +225,11 @@
 	DEVICE( X,		X_AGX016,	"ITT AGX016"),
 	DEVICE( PICOP,		PICOP_PT86C52X,	"PT86C52x Vesuvius"),
 	DEVICE( PICOP,		PICOP_PT80C524,	"PT80C524 Nile"),
-	DEVICE( MYLEX,		MYLEX_DAC960P_V2,"DAC960P V2"),
-	DEVICE( MYLEX,		MYLEX_DAC960P_V3,"DAC960P V3"),
-	DEVICE( MYLEX,		MYLEX_DAC960P_V4,"DAC960P V4"),
+	DEVICE( MYLEX,		MYLEX_DAC960_P, "DAC960 P Series"),
+	DEVICE( MYLEX,		MYLEX_DAC960_PD,"DAC960 PD Series"),
+	DEVICE( MYLEX,		MYLEX_DAC960_PG,"DAC960 PG Series"),
+	DEVICE( MYLEX,		MYLEX_DAC960_LP,"DAC960 LP Series"),
+	DEVICE( MYLEX,		MYLEX_DAC960_BA,"DAC960 BA Series"),
 	DEVICE( APPLE,		APPLE_BANDIT,	"Bandit"),
 	DEVICE( APPLE,		APPLE_GC,	"Grand Central"),
 	DEVICE( APPLE,		APPLE_HYDRA,	"Hydra"),
@@ -528,6 +530,7 @@
 	DEVICE( INTEL,		INTEL_82430,	"82430ZX Aries"),
 	DEVICE( INTEL,		INTEL_82434,	"82434LX Mercury/Neptune"),
 	DEVICE( INTEL,		INTEL_I960,	"i960"),
+	DEVICE( INTEL,		INTEL_I960RN,	"i960 RN"),
 	DEVICE( INTEL,		INTEL_82559ER,	"82559ER"),
 	DEVICE( INTEL,		INTEL_82092AA_0,"82092AA PCMCIA bridge"),
 	DEVICE( INTEL,		INTEL_82092AA_1,"82092AA EIDE"),
diff -urN linux-2.2.17-pre15/drivers/scsi/3w-xxxx.c linux/drivers/scsi/3w-xxxx.c
--- linux-2.2.17-pre15/drivers/scsi/3w-xxxx.c	Wed May  3 17:16:44 2000
+++ linux/drivers/scsi/3w-xxxx.c	Mon Dec  3 22:10:51 2001
@@ -2,6 +2,8 @@
    3w-xxxx.c -- 3ware Storage Controller device driver for Linux.
 
    Written By: Adam Radford <linux@3ware.com>
+   Modifications By: Joel Jacobson <linux@3ware.com>
+
    Copyright (C) 1999-2000 3ware Inc.
 
    Kernel compatablity By: 	Andre Hedrick <andre@suse.com>
@@ -47,6 +49,21 @@
 
    For more information, goto:
    http://www.3ware.com
+
+   History
+   -------
+   0.1.000 -     Initial release.
+   0.4.000 -     Added support for Asynchronous Event Notification through
+                 ioctls for 3DM.
+   1.0.000 -     Added DPO & FUA bit support for WRITE_10 & WRITE_6 cdb
+                 to disable drive write-cache before writes.
+   1.1.000 -     Fixed performance bug with DPO & FUA not existing for WRITE_6.
+   1.2.000 -     Added support for clean shutdown notification/feature table.
+   1.02.00.001 - Added support for full command packet posts through ioctls
+                 for 3DM.
+                 Bug fix so hot spare drives don't show up.
+   1.02.00.002 - Fix bug with tw_setfeature() call that caused oops on some
+                 systems.
 */
 
 #include <linux/module.h>
@@ -65,6 +82,7 @@
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/smp.h>
+#include <linux/reboot.h>
 
 #include <asm/spinlock.h>
 #include <asm/errno.h>
@@ -83,6 +101,12 @@
 static int tw_copy_info(TW_Info *info, char *fmt, ...);
 static void tw_copy_mem_info(TW_Info *info, char *data, int len);
 static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static int tw_halt(struct notifier_block *nb, ulong event, void *buf);
+
+/* Notifier block to get a notify on system shutdown/halt/reboot */
+static struct notifier_block tw_notifier = {
+  tw_halt, NULL, 0
+};
 
 struct proc_dir_entry tw_scsi_proc_entry = {
 	PROC_SCSI_3W_XXXX,
@@ -91,7 +115,7 @@
 };
 
 /* Globals */
-char *tw_driver_version="1.1.000";
+char *tw_driver_version="1.02.00.002";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
 
@@ -230,7 +254,7 @@
 				if (command_packet->status != 0) {
 					if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
 						/* Bad response */
-						printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, flags = 0x%x.\n", command_packet->flags);
+						printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
 						return 1;
 					} else {
 						/* We know this is a 3w-1x00, and doesn't support aen's */
@@ -568,6 +592,7 @@
 	TW_Device_Extension *tw_dev2;
 	struct pci_dev *tw_pci_dev = pci_devices;
 	u32 status_reg_value;
+	unsigned char c = 1;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n");
 	while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, TW_DEVICE_ID, tw_pci_dev))) {
@@ -666,7 +691,7 @@
 			continue;
 		}
 
-		error = tw_initconnection(tw_dev);
+		error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
 		if (error) {
 			printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initconnection for card %d.\n", numcards);
 			release_region((tw_dev->tw_pci_dev->base_address[0]), TW_IO_ADDRESS_RANGE);
@@ -726,10 +751,14 @@
 		/* Free the temporary device extension */
 		if (tw_dev)
 			kfree(tw_dev);
+		/* Tell the firmware we support shutdown notification*/
+		tw_setfeature(tw_dev2, 2, 1, &c);
 	}
 
 	if (numcards == 0) 
 		printk(KERN_WARNING "3w-xxxx: tw_findcards(): No cards found.\n");
+	else
+	  register_reboot_notifier(&tw_notifier);
 
 	return numcards;
 } /* End tw_findcards() */
@@ -751,8 +780,22 @@
 	}
 } /* End tw_free_device_extension() */
 
+/* Clean shutdown routine */
+static int tw_halt(struct notifier_block *nb, ulong event, void *buf)
+{
+	int i;
+	
+	for (i=0;i<tw_device_extension_count;i++) {
+		printk(KERN_NOTICE "3w-xxxx: Notifying card #%d\n", i);
+		tw_shutdown_device(tw_device_extension_list[i]);
+	}
+	unregister_reboot_notifier(&tw_notifier);
+	
+	return NOTIFY_OK;
+} /* End tw_halt() */
+
 /* This function will send an initconnection command to controller */
-int tw_initconnection(TW_Device_Extension *tw_dev) 
+int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits) 
 {
 	u32 command_que_addr, command_que_value;
 	u32 status_reg_addr, status_reg_value;
@@ -784,7 +827,7 @@
 	command_packet->byte3.host_id = 0x0;
 	command_packet->status = 0x0;
 	command_packet->flags = 0x0;
-	command_packet->byte6.message_credits = TW_INIT_MESSAGE_CREDITS; 
+	command_packet->byte6.message_credits = message_credits; 
 	command_packet->byte8.init_connection.response_queue_pointer = 0x0;
 	command_que_value = tw_dev->command_packet_physical_address[request_id];
 
@@ -815,7 +858,7 @@
 			}
 			if (command_packet->status != 0) {
 				/* bad response */
-				printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, flags = 0x%x.\n", command_packet->flags);
+				printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
 				return 1;
 			}
 			break;	/* Response was okay, so we exit */
@@ -962,7 +1005,7 @@
 			}
 			if (command_packet->status != 0) {
 				/* bad response */
-				printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, flags = 0x%x.\n", command_packet->flags);
+				printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
 				return 1;
 			}
 			found = 1;
@@ -984,9 +1027,11 @@
 		if (is_unit_present[i] == 0) {
 			tw_dev->is_unit_present[i] = FALSE;
 		} else {
+		  if (is_unit_present[i] & TW_UNIT_ONLINE) {
 			dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): Unit %d found.\n", i);
 			tw_dev->is_unit_present[i] = TRUE;
 			num_units++;
+		  }
 		}
 	}
 	tw_dev->num_units = num_units;
@@ -1090,7 +1135,7 @@
 				request_id = response_que.u.response_id;
 				command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
 				if (command_packet->status != 0) {
-					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, flags = 0x%x.\n", command_packet->flags);
+					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
 				}
 				if (tw_dev->state[request_id] != TW_S_POSTED) {
 					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", request_id, command_packet->byte0.opcode);
@@ -1186,7 +1231,7 @@
 	/* Initialize command packet */
 	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
 	if (command_packet == NULL) {
-		printk(KERN_WARNING "3w-xxxx: twioctl(): Bad command packet virtual address.\n");
+		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad command packet virtual address.\n");
 		tw_dev->state[request_id] = TW_S_COMPLETED;
 		tw_state_request_finish(tw_dev, request_id);
 		tw_dev->srb[request_id]->result = (DID_OK << 16);
@@ -1256,6 +1301,12 @@
 			tw_dev->srb[request_id]->result = (DID_OK << 16);
 			tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
 			return 0;
+		case TW_CMD_PACKET:
+		  memcpy(command_packet, ioctl->data, sizeof(TW_Command));
+		  command_packet->request_id = request_id;
+		  tw_post_command_packet(tw_dev, request_id);
+		
+		  return 0;
 		default:
 			printk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
 			tw_dev->state[request_id] = TW_S_COMPLETED;
@@ -1480,7 +1531,7 @@
 		return 1;
 	}
 
-	error = tw_initconnection(tw_dev);
+	error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
 	if (error) {
 		printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no);
 		return 1;
@@ -1804,6 +1855,11 @@
 	/* Tell kernel scsi-layer we are gone */
 	scsi_unregister(tw_host);
 
+	/* Fake like we just shut down, so notify the card that
+	 * we "shut down cleanly".
+	 */
+	tw_halt(0, 0, 0);  // parameters aren't actually used
+
 	return 0;
 } /* End tw_scsi_release() */
 
@@ -1901,8 +1957,10 @@
 		if (is_unit_present[i] == 0) {
 			tw_dev->is_unit_present[i] = FALSE;
 		} else {
+		  if (is_unit_present[i] & TW_UNIT_ONLINE) {
 			tw_dev->is_unit_present[i] = TRUE;
 			dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete: Unit %d found.\n", i);
+		  }
 		}
 	}
 
@@ -2125,6 +2183,92 @@
 	return 0;
 } /* End tw_scsiop_test_unit_ready() */
 
+/* Set a value in the features table */
+int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
+                  unsigned char *val)
+{
+	TW_Param *param;
+	TW_Command  *command_packet;
+	TW_Response_Queue response_queue;
+	int request_id = 0;
+	u32 command_que_value, command_que_addr;
+	u32 status_reg_addr, status_reg_value;
+	u32 response_que_addr;
+	u32 param_value;
+	int imax, i;
+
+	/* Initialize SetParam command packet */
+	if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
+		printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
+		return 1;
+	}
+	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+	memset(command_packet, 0, sizeof(TW_Sector));
+	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+
+	command_packet->byte0.opcode = TW_OP_SET_PARAM;
+	command_packet->byte0.sgl_offset  = 2;
+	param->table_id = 0x404;  /* Features table */
+	param->parameter_id = parm;
+	param->parameter_size_bytes = param_size;
+	memcpy(param->data, val, param_size);
+
+	param_value = tw_dev->alignment_physical_address[request_id];
+	if (param_value == 0) {
+		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
+		tw_dev->state[request_id] = TW_S_COMPLETED;
+		tw_state_request_finish(tw_dev, request_id);
+		tw_dev->srb[request_id]->result = (DID_OK << 16);
+		tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+	}
+	command_packet->byte8.param.sgl[0].address = param_value;
+	command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
+
+	command_packet->size = 4;
+	command_packet->request_id = request_id;
+	command_packet->byte6.parameter_count = 1;
+
+	command_que_value = tw_dev->command_packet_physical_address[request_id];
+	if (command_que_value == 0) {
+		printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
+		return 1;
+	}
+	command_que_addr = tw_dev->registers.command_que_addr;
+	status_reg_addr = tw_dev->registers.status_reg_addr;
+	response_que_addr = tw_dev->registers.response_que_addr;
+
+	/* Send command packet to the board */
+	outl(command_que_value, command_que_addr);
+
+	/* Poll for completion */
+	imax = TW_POLL_MAX_RETRIES;
+	for (i=0;i<imax;i++) {
+		mdelay(10);
+		status_reg_value = inl(status_reg_addr);
+		if (tw_check_bits(status_reg_value)) {
+			printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n");
+			return 1;
+		}
+		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
+			response_queue.value = inl(response_que_addr);
+			request_id = (unsigned char)response_queue.u.response_id;
+			if (request_id != 0) {
+				/* unexpected request id */
+				printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
+				return 1;
+			}
+			if (command_packet->status != 0) {
+				/* bad response */
+				printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
+				return 1;
+			}
+			break; /* Response was okay, so we exit */
+		}
+	}
+
+	return 0;
+} /* End tw_setfeature() */
+
 /* This function will setup the interrupt handler */
 int tw_setup_irq(TW_Device_Extension *tw_dev)
 {
@@ -2140,6 +2284,29 @@
 	}
 	return 0;
 } /* End tw_setup_irq() */
+
+/* This function will tell the controller we're shutting down by sending
+   initconnection with a 1 */
+int tw_shutdown_device(TW_Device_Extension *tw_dev)
+{
+	int error;
+
+	/* Disable interrupts */
+	tw_disable_interrupts(tw_dev);
+
+	/* poke the board */
+	error = tw_initconnection(tw_dev, 1);
+	if (error) {
+		printk(KERN_WARNING "3w-xxxx: tw_shutdown_device(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no);
+	} else {
+		printk(KERN_NOTICE "3w-xxxx shutdown succeeded\n");
+	}
+
+	/* Re-enable interrupts */
+	tw_enable_interrupts(tw_dev);
+
+	return 0;
+} /* End tw_shutdown_device() */
 
 /* This function will soft reset the controller */
 void tw_soft_reset(TW_Device_Extension *tw_dev) 
diff -urN linux-2.2.17-pre15/drivers/scsi/3w-xxxx.h linux/drivers/scsi/3w-xxxx.h
--- linux-2.2.17-pre15/drivers/scsi/3w-xxxx.h	Wed May  3 17:16:44 2000
+++ linux/drivers/scsi/3w-xxxx.h	Mon Dec  3 22:10:51 2001
@@ -2,7 +2,9 @@
    3w-xxxx.h -- 3ware Storage Controller device driver for Linux.
    
    Written By: Adam Radford <linux@3ware.com>
-   Copyright (C) 1999 3ware Inc.
+   Modifications By: Joel Jacobson <linux@3ware.com>
+
+   Copyright (C) 1999, 2000 3ware Inc.
 
    Kernel compatablity By:	Andre Hedrick <andre@suse.com>
    Non-Copyright (C) 2000	Andre Hedrick <andre@suse.com>
@@ -106,6 +108,7 @@
 #define TW_OP_SET_PARAM	      0x13
 #define TW_OP_SECTOR_INFO     0x1a
 #define TW_OP_AEN_LISTEN      0x1c
+#define TW_CMD_PACKET         0x1d
 
 /* Asynchronous Event Notification (AEN) Codes */
 #define TW_AEN_QUEUE_EMPTY       0x0000
@@ -135,7 +138,7 @@
 #define TW_BLOCK_SIZE			      0x200 /* 512-byte blocks */
 #define TW_IOCTL                              0x80
 #define TW_MAX_AEN_TRIES                      100
-
+#define TW_UNIT_ONLINE                        1
 #define TW_IN_INTR                            1
 
 /* Macros */
@@ -305,7 +308,7 @@
 void tw_enable_interrupts(TW_Device_Extension *tw_dev);
 int tw_findcards(Scsi_Host_Template *tw_host);
 void tw_free_device_extension(TW_Device_Extension *tw_dev);
-int tw_initconnection(TW_Device_Extension *tw_dev);
+int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits);
 int tw_initialize_device_extension(TW_Device_Extension *tw_dev);
 int tw_initialize_units(TW_Device_Extension *tw_dev);
 int tw_ioctl(TW_Device_Extension *tw_dev, int request_id);
@@ -328,7 +331,9 @@
 int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id);
+int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size, unsigned char *val);
 int tw_setup_irq(TW_Device_Extension *tw_dev);
+int tw_shutdown_device(TW_Device_Extension *tw_dev);
 void tw_soft_reset(TW_Device_Extension *tw_dev);
 int tw_state_request_finish(TW_Device_Extension *tw_dev,int request_id);
 int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id);
@@ -351,6 +356,8 @@
 	eh_strategy_handler : NULL,			\
 	eh_abort_handler : tw_scsi_eh_abort,		\
 	eh_device_reset_handler : NULL,			\
+        eh_bus_reset_handler : NULL,                    \
+        eh_host_reset_handler : tw_scsi_eh_reset,       \
 	abort : NULL,					\
 	reset : NULL,					\
 	slave_attach : NULL,				\
diff -urN linux-2.2.17-pre15/drivers/sound/ac97_codec.c linux/drivers/sound/ac97_codec.c
--- linux-2.2.17-pre15/drivers/sound/ac97_codec.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/sound/ac97_codec.c	Mon Dec  3 22:10:51 2001
@@ -62,6 +62,7 @@
 	{0x43525903, "Cirrus Logic CS4297"  ,	NULL},
 	{0x43525913, "Cirrus Logic CS4297A"   , NULL},
 	{0x43525923, "Cirrus Logic CS4298"    , NULL},
+	{0x4352592B, "Cirrus Logic CS4294"    , NULL},
 	{0x43525931, "Cirrus Logic CS4299"    , NULL},
 	{0x4e534331, "National Semiconductor LM4549" ,	NULL},
 	{0x53494c22, "Silicon Laboratory Si3036"     ,	NULL},
diff -urN linux-2.2.17-pre15/drivers/sound/cs46xx.c linux/drivers/sound/cs46xx.c
--- linux-2.2.17-pre15/drivers/sound/cs46xx.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/sound/cs46xx.c	Mon Dec  3 22:10:51 2001
@@ -65,7 +65,11 @@
 
 #define GOF_PER_SEC	200
 
-/* an instance of the 4610 channel */
+static int external_amp = 0;
+static int thinkpad = 0;
+
+
+/* An instance of the 4610 channel */
 
 struct cs_channel 
 {
@@ -74,7 +78,7 @@
 	void *state;
 };
 
-#define DRIVER_VERSION "0.01"
+#define DRIVER_VERSION "0.09"
 
 /* magic numbers to protect our data structures */
 #define CS_CARD_MAGIC		0x46524F4D /* "FROM" */
@@ -176,6 +180,12 @@
 
 	u16 ac97_features;
 	
+	int amplifier;			/* Amplifier control */
+	void (*amplifier_ctrl)(struct cs_card *, int);
+	
+	int active;			/* Active clocking */
+	void (*active_ctrl)(struct cs_card *, int);
+	
 	/* hardware resources */
 	unsigned long ba0_addr;
 	unsigned long ba1_addr;
@@ -471,7 +481,6 @@
 	if(!(dmabuf->fmt & CS_FMT_STEREO))
 	{
 		tmp|=0x00002000;
-		tmp|=0x00008000;	/* unsigned */
 	}
 	cs461x_poke(card, BA1_PFIE, tmp);
 
@@ -729,42 +738,8 @@
 	return 0;
 }
 
-/* we are doing quantum mechanics here, the buffer can only be empty, half or full filled i.e.
-   |------------|------------|   or   |xxxxxxxxxxxx|------------|   or   |xxxxxxxxxxxx|xxxxxxxxxxxx|
-   but we almost always get this
-   |xxxxxx------|------------|   or   |xxxxxxxxxxxx|xxxxx-------|
-   so we have to clear the tail space to "silence"
-   |xxxxxx000000|------------|   or   |xxxxxxxxxxxx|xxxxxx000000|
-*/
 static void cs_clear_tail(struct cs_state *state)
 {
-	struct dmabuf *dmabuf = &state->dmabuf;
-	unsigned swptr;
-	unsigned char silence = (dmabuf->fmt & CS_FMT_16BIT) ? 0 : 0x80;
-	unsigned int len;
-	unsigned long flags;
-
-	spin_lock_irqsave(&state->card->lock, flags);
-	swptr = dmabuf->swptr;
-	spin_unlock_irqrestore(&state->card->lock, flags);
-
-	if (swptr == 0 || swptr == dmabuf->dmasize / 2 || swptr == dmabuf->dmasize)
-		return;
-
-	if (swptr < dmabuf->dmasize/2)
-		len = dmabuf->dmasize/2 - swptr;
-	else
-		len = dmabuf->dmasize - swptr;
-
-	memset(dmabuf->rawbuf + swptr, silence, len);
-
-	spin_lock_irqsave(&state->card->lock, flags);
-	dmabuf->swptr += len;
-	dmabuf->count += len;
-	spin_unlock_irqrestore(&state->card->lock, flags);
-
-	/* restart the dma machine in case it is halted */
-	start_dac(state);
 }
 
 static int drain_dac(struct cs_state *state, int nonblock)
@@ -800,10 +775,12 @@
 			return -EBUSY;
 		}
 
-		tmo = (dmabuf->dmasize + 4096 * HZ) / dmabuf->rate;
+		tmo = (dmabuf->dmasize * HZ) / dmabuf->rate;
 		tmo >>= sample_shift[dmabuf->fmt];
+		tmo += (4096*HZ)/dmabuf->rate;
+		
 		if (!schedule_timeout(tmo ? tmo : 1) && tmo){
-			printk(KERN_ERR "cs461x: drain_dac, dma timeout?\n");
+			printk(KERN_ERR "cs461x: drain_dac, dma timeout? %d\n", count);
 			break;
 		}
 	}
@@ -1271,7 +1248,10 @@
 			stop_adc(state);
 			dmabuf->ready = 0;
 			if(val)
+			{
 				dmabuf->fmt |= CS_FMT_STEREO;
+				return put_user(1, (int *)arg);
+			}
 #if 0				
 			/* Needs extra work to support this */				
 			else
@@ -1490,6 +1470,106 @@
 	return -EINVAL;
 }
 
+
+/*
+ *	AMP control - null AMP
+ */
+ 
+static void amp_none(struct cs_card *card, int change)
+{	
+}
+
+/*
+ *	Crystal EAPD mode
+ */
+ 
+static void amp_voyetra(struct cs_card *card, int change)
+{
+	/* Manage the EAPD bit on the Crystal 4297 */
+	int old=card->amplifier;
+	
+	card->amplifier+=change;
+	if(card->amplifier && !old)
+	{
+		/* Turn the EAPD amp on */
+		cs_ac97_set(card->ac97_codec[0],  AC97_POWER_CONTROL, 
+			cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL) |
+				0x8000);
+	}
+	else if(old && !card->amplifier)
+	{
+		/* Turn the EAPD amp off */
+		cs_ac97_set(card->ac97_codec[0],  AC97_POWER_CONTROL, 
+			cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL) &
+				~0x8000);
+	}
+}
+
+
+
+/*
+ *	Untested
+ */
+ 
+static void amp_voyetra_4294(struct cs_card *card, int change)
+{
+	struct ac97_codec *c=card->ac97_codec[0];
+	int old = card->amplifier;
+	
+	card->amplifier+=change;
+
+	if(card->amplifier)
+	{
+		/* Switch the GPIO pins 7 and 8 to open drain */
+		cs_ac97_set(c, 0x4C, cs_ac97_get(c, 0x4C) & 0xFE7F);
+		cs_ac97_set(c, 0x4E, cs_ac97_get(c, 0x4E) | 0x0180);
+		/* Now wake the AMP (this might be backwards) */
+		cs_ac97_set(c, 0x54, cs_ac97_get(c, 0x54) & ~0x0180);
+	}
+	else
+	{
+		cs_ac97_set(c, 0x54, cs_ac97_get(c, 0x54) | 0x0180);
+	}
+}
+
+/*
+ *	Handle the CLKRUN on a thinkpad. We must disable CLKRUN support
+ *	whenever we need to beat on the chip.
+ *
+ *	The original idea and code for this hack comes from David Kaiser at
+ *	Linuxcare. Perhaps one day Crystal will document their chips well
+ *	enough to make them useful.
+ */
+ 
+static void clkrun_hack(struct cs_card *card, int change)
+{
+	struct pci_dev *acpi_dev;
+	u16 control;
+	u8 pp;
+	unsigned long port;
+	int old=card->amplifier;
+	
+	card->amplifier+=change;
+	
+	acpi_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
+	if(acpi_dev == NULL)
+		return;		/* Not a thinkpad thats for sure */
+
+	/* Find the control port */		
+	pci_read_config_byte(acpi_dev, 0x41, &pp);
+	port=pp<<8;
+
+	/* Read ACPI port */	
+	control=inw(port+0x10);
+
+	/* Flip CLKRUN off while running */
+	if(!card->amplifier && old)
+		outw(control|0x2000, port+0x10);
+	else if(card->amplifier && !old)
+		outw(control&~0x2000, port+0x10);
+}
+
+	
 static int cs_open(struct inode *inode, struct file *file)
 {
 	int i = 0;
@@ -1536,10 +1616,14 @@
 		return -ENODEV;
 	}
 
+	/* Now turn on external AMP if needed */
+	state->card = card;
+	state->card->active_ctrl(state->card,1);
+	state->card->amplifier_ctrl(state->card,1);
+	
 	dmabuf->channel->state = state;
 	/* initialize the virtual channel */
 	state->virt = i;
-	state->card = card;
 	state->magic = CS_STATE_MAGIC;
 	dmabuf->wait = NULL;
 	state->open_sem = MUTEX;
@@ -1572,6 +1656,7 @@
 
 	state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
 	up(&state->open_sem);
+	
 
 	MOD_INC_USE_COUNT;
 	return 0;
@@ -1603,14 +1688,17 @@
 	}
 
 	free_page((unsigned long)state->dmabuf.pbuf);
-	kfree(state->card->states[state->virt]);
 
 	/* we're covered by the open_sem */
 	up(&state->open_sem);
-
 	state->card->states[state->virt] = NULL;
 	state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
 
+	/* Now turn off external AMP if needed */
+	state->card->amplifier_ctrl(state->card, -1);
+	state->card->active_ctrl(state->card, -1);
+
+	kfree(state);
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
@@ -1793,12 +1881,27 @@
  match:
 	file->private_data = card->ac97_codec[i];
 
+	card->active_ctrl(card,1);
 	MOD_INC_USE_COUNT;
 	return 0;
 }
 
 static int cs_release_mixdev(struct inode *inode, struct file *file)
 {
+	int minor = MINOR(inode->i_rdev);
+	struct cs_card *card = devs;
+	int i;
+	
+	for (card = devs; card != NULL; card = card->next)
+		for (i = 0; i < NR_AC97; i++)
+			if (card->ac97_codec[i] != NULL &&
+			    card->ac97_codec[i]->dev_mixer == minor)
+				goto match;
+
+	if (!card)
+		return -ENODEV;
+match:
+	card->active_ctrl(card, -1);
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
@@ -2222,7 +2325,7 @@
 			break;
 		current->state = TASK_UNINTERRUPTIBLE;
 		schedule_timeout(1);
-	} while (time_before(end_time, jiffies));
+	} while (time_before(jiffies, end_time));
 
 	/*
 	 *  Make sure CODEC is READY.
@@ -2253,7 +2356,7 @@
 			break;
 		current->state = TASK_UNINTERRUPTIBLE;
 		schedule_timeout(1);
-	} while (time_before(end_time, jiffies));
+	} while (time_before(jiffies, end_time));
 
 	/*
 	 *  Make sure input slots 3 and 4 are valid.  If not, then return
@@ -2338,9 +2441,39 @@
 /* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered 
    untill "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */
    
+   
+/*
+ *	Card subid table
+ */
+ 
+struct cs_card_type
+{
+	u16 vendor;
+	u16 id;
+	char *name;
+	void (*amp)(struct cs_card *, int);
+	void (*active)(struct cs_card *, int);
+};
+
+static struct cs_card_type __init cards[]={
+	{0x1489, 0x7001, "Genius Soundmaker 128 value", amp_none, NULL},
+	{0x5053, 0x3357, "Voyetra", amp_voyetra, NULL},
+	/* Not sure if the 570 needs the clkrun hack */
+	{PCI_VENDOR_ID_IBM, 0x0132, "Thinkpad 570", amp_none, clkrun_hack},
+	{PCI_VENDOR_ID_IBM, 0x0153, "Thinkpad 600X/A20/T20", amp_none, clkrun_hack},
+	{PCI_VENDOR_ID_IBM, 0x1010, "Thinkpad 600E (unsupported)", NULL, NULL},
+	{0, 0, NULL, NULL}
+};
+
 static int __init cs_install(struct pci_dev *pci_dev)
 {
 	struct cs_card *card;
+	struct cs_card_type *cp = &cards[0];
+	u16 ss_card, ss_vendor;
+	
+	
+	pci_read_config_word(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor);
+	pci_read_config_word(pci_dev, PCI_SUBSYSTEM_ID, &ss_card);
 
 	if ((card = kmalloc(sizeof(struct cs_card), GFP_KERNEL)) == NULL) {
 		printk(KERN_ERR "cs461x: out of memory\n");
@@ -2357,13 +2490,58 @@
 
 	pci_set_master(pci_dev);
 
-	printk(KERN_INFO "cs461x: Card found at  0x%08lx and 0x%08lx, IRQ %d\n",
+	printk(KERN_INFO "cs461x: Card found at 0x%08lx and 0x%08lx, IRQ %d\n",
 	       card->ba0_addr, card->ba1_addr, card->irq);
 
 	card->alloc_pcm_channel = cs_alloc_pcm_channel;
 	card->alloc_rec_pcm_channel = cs_alloc_rec_pcm_channel;
 	card->free_pcm_channel = cs_free_pcm_channel;
+	card->amplifier_ctrl = amp_none;
+	card->active_ctrl = amp_none;
+	
+	while(cp->name)
+	{
+		if(cp->vendor == ss_vendor && cp->id == ss_card)
+		{
+			card->amplifier_ctrl = cp->amp;
+			if(cp->active)
+				card->active_ctrl = cp->active;
+			break;
+		}
+		cp++;
+	}
+	if(cp->name==NULL)
+	{
+		printk(KERN_INFO "cs461x: Unknown card (%04X:%04X) at 0x%08lx/0x%08lx, IRQ %d\n",
+			ss_vendor, ss_card, card->ba0_addr, card->ba1_addr,  card->irq);
+	}
+	else
+	{
+		printk(KERN_INFO "cs461x: %s at 0x%08lx/0x%08lx, IRQ %d\n",
+			cp->name, card->ba0_addr, card->ba1_addr, card->irq);
+	}
+	
+	if(card->amplifier_ctrl==NULL)
+	{
+		printk(KERN_ERR "cs461x: Unsupported configuration due to lack of documentation.\n");
+		kfree(card);
+		return -EINVAL;
+	}		
+		       
+	if(external_amp == 1)
+	{
+		printk(KERN_INFO "cs461x: Crystal EAPD support forced on.\n");
+		card->amplifier_ctrl = amp_voyetra;
+	}
 
+	if(thinkpad == 1)
+	{
+		card->active_ctrl = clkrun_hack;
+		printk(KERN_INFO "cs461x: Activating CLKRUN hack for Thinkpad.\n");
+	}
+	
+	card->active_ctrl(card, 1);
+	
 	/* claim our iospace and irq */
 	
 	card->ba0 = ioremap(card->ba0_addr, CS461X_BA0_SIZE);
@@ -2395,6 +2573,7 @@
 	card->next = devs;
 	devs = card;
 	
+	card->active_ctrl(card, -1);
 	return 0;
 	
 fail:
@@ -2420,6 +2599,8 @@
 	int i;
 	unsigned int tmp;
 	
+	card->active_ctrl(card,1);
+	
 	tmp = cs461x_peek(card, BA1_PFIE);
 	tmp &= ~0x0000f03f;
 	tmp |=  0x00000010;
@@ -2467,6 +2648,7 @@
 	tmp = cs461x_peekBA0(card, BA0_CLKCR1) & ~CLKCR1_SWCE;
 	cs461x_pokeBA0(card, BA0_CLKCR1, tmp);
 
+	card->active_ctrl(card,-1);
 
 	/* free hardware resources */
 	free_irq(card->irq, card);
@@ -2537,5 +2719,8 @@
 		devs=next;
 	}
 }
+
+MODULE_PARM(external_amp, "i");
+MODULE_PARM(thinkpad, "i");
 
 #endif
diff -urN linux-2.2.17-pre15/drivers/sound/i810_audio.c linux/drivers/sound/i810_audio.c
--- linux-2.2.17-pre15/drivers/sound/i810_audio.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/sound/i810_audio.c	Mon Dec  3 22:10:51 2001
@@ -181,7 +181,7 @@
 #define INT_MASK (INT_SEC|INT_PRI|INT_MC|INT_PO|INT_PI|INT_MO|INT_NI|INT_GPI)
 
 
-#define DRIVER_VERSION "0.02"
+#define DRIVER_VERSION "0.17"
 
 /* magic numbers to protect our data structures */
 #define I810_CARD_MAGIC		0x5072696E /* "Prin" */
@@ -744,44 +744,6 @@
 	return 0;
 }
 
-/* we are doing quantum mechanics here, the buffer can only be empty, half or full filled i.e.
-   |------------|------------|   or   |xxxxxxxxxxxx|------------|   or   |xxxxxxxxxxxx|xxxxxxxxxxxx|
-   but we almost always get this
-   |xxxxxx------|------------|   or   |xxxxxxxxxxxx|xxxxx-------|
-   so we have to clear the tail space to "silence"
-   |xxxxxx000000|------------|   or   |xxxxxxxxxxxx|xxxxxx000000|
-*/
-static void i810_clear_tail(struct i810_state *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	unsigned swptr;
-	unsigned char silence = (dmabuf->fmt & I810_FMT_16BIT) ? 0 : 0x80;
-	unsigned int len;
-	unsigned long flags;
-
-	spin_lock_irqsave(&state->card->lock, flags);
-	swptr = dmabuf->swptr;
-	spin_unlock_irqrestore(&state->card->lock, flags);
-
-	if (swptr == 0 || swptr == dmabuf->dmasize / 2 || swptr == dmabuf->dmasize)
-		return;
-
-	if (swptr < dmabuf->dmasize/2)
-		len = dmabuf->dmasize/2 - swptr;
-	else
-		len = dmabuf->dmasize - swptr;
-
-	memset(dmabuf->rawbuf + swptr, silence, len);
-
-	spin_lock_irqsave(&state->card->lock, flags);
-	dmabuf->swptr += len;
-	dmabuf->count += len;
-	spin_unlock_irqrestore(&state->card->lock, flags);
-
-	/* restart the dma machine in case it is halted */
-	start_dac(state);
-}
-
 static int drain_dac(struct i810_state *state, int nonblock)
 {
 	struct wait_queue wait = {current, NULL};
@@ -1299,8 +1261,6 @@
 
 	case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
 		get_user_ret(val, (int *)arg, -EFAULT);
-		if(val==0)
-			return -EINVAL;
 		if (file->f_mode & FMODE_WRITE) {
 			stop_dac(state);
 			dmabuf->ready = 0;
@@ -1311,6 +1271,7 @@
 			dmabuf->ready = 0;
 			dmabuf->fmt = I810_FMT_STEREO;
 		}
+		put_user(1, (int *)arg);
 		return 0;
 
 	case SNDCTL_DSP_GETBLKSIZE:
@@ -1588,12 +1549,6 @@
 	struct i810_state *state = (struct i810_state *)file->private_data;
 	struct dmabuf *dmabuf = &state->dmabuf;
 
-	if (file->f_mode & FMODE_WRITE) {
-		/* FIXME :.. */
-		i810_clear_tail(state);
-		drain_dac(state, file->f_flags & O_NONBLOCK);
-	}
-
 	/* stop DMA state machine and free DMA buffers/channels */
 	down(&state->open_sem);
 
@@ -1737,8 +1692,9 @@
 		return 0;
 	}
 	
-	udelay(500);
-	
+	current->state = TASK_UNINTERRUPTIBLE;
+	schedule_timeout(HZ/5);
+		
 	inw(card->ac97base);
 
 	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
diff -urN linux-2.2.17-pre15/drivers/sound/sb_ess.c linux/drivers/sound/sb_ess.c
--- linux-2.2.17-pre15/drivers/sound/sb_ess.c	Tue Jan  4 10:12:22 2000
+++ linux/drivers/sound/sb_ess.c	Mon Dec  3 22:10:51 2001
@@ -1215,6 +1215,12 @@
 	/* FKS: sb_dsp_reset to enable extended mode???? */
 	sb_dsp_reset(devc); /* Turn on extended mode */
 
+	/* Disable audio 2 data if boot from another OS w/o HW reset */
+	if (devc->submodel == SUBMDL_ES1879)
+	{
+		ess_setmixer(devc, 0x71, 0x00);
+	}   
+                       
 	/*
 	 *  Enable joystick and OPL3
 	 */
diff -urN linux-2.2.17-pre15/drivers/video/aty.h linux/drivers/video/aty.h
--- linux-2.2.17-pre15/drivers/video/aty.h	Mon Dec  3 22:10:44 2001
+++ linux/drivers/video/aty.h	Mon Dec  3 22:10:51 2001
@@ -459,6 +459,7 @@
 #define VERTEX_2_SECONDARY_T	0x0738	/* Dword offset 1_CE */
 #define VERTEX_2_SECONDARY_W	0x073C	/* Dword offset 1_CF */
 
+#define GTC_3D_RESET_DELAY	3	/* 3D engine reset delay in ms */
 
 /* CRTC control values (mostly CRTC_GEN_CNTL) */
 
@@ -997,5 +998,12 @@
 #define LCD_LT_GIO		0x07
 #define LCD_POWER_MANAGEMENT	0x08
 #define LCD_ZVGPIO		0x09
+#define LCD_MISC_CNTL		0x14
+
+/* Values in LCD_MISC_CNTL */
+#define BIAS_MOD_LEVEL_MASK	0x0000ff00
+#define BIAS_MOD_LEVEL_SHIFT	8
+#define BLMOD_EN		0x00010000
+#define BIASMOD_EN		0x00020000
 
 #endif /* REGMACH64_H */
diff -urN linux-2.2.17-pre15/drivers/video/atyfb.c linux/drivers/video/atyfb.c
--- linux-2.2.17-pre15/drivers/video/atyfb.c	Mon Dec  3 22:10:44 2001
+++ linux/drivers/video/atyfb.c	Mon Dec  3 22:10:51 2001
@@ -20,6 +20,8 @@
  *  This file is subject to the terms and conditions of the GNU General Public
  *  License. See the file COPYING in the main directory of this archive for
  *  more details.
+ *
+ *  Many thanks to Nitya from ATI devrel for support and patience !
  */
 
 /******************************************************************************
@@ -479,12 +481,16 @@
 };
 
 
-static inline u32 aty_ld_le32(volatile unsigned int regindex,
+static inline u32 aty_ld_le32(volatile int regindex,
 			      const struct fb_info_aty *info)
 {
     unsigned long temp;
     u32 val;
 
+    /* Hack for bloc 1, should be cleanly optimized by compiler */
+    if (regindex >= 0x400)
+    	regindex -= 0x800;
+
 #if defined(__powerpc__)
     temp = info->ati_regbase;
      __asm__ __volatile__("lwbrx %0,%1,%2;eieio" : "=r"(val) : "b" (regindex), "r" (temp));
@@ -498,11 +504,15 @@
     return val;
 }
 
-static inline void aty_st_le32(volatile unsigned int regindex, u32 val,
+static inline void aty_st_le32(volatile int regindex, u32 val,
 			       const struct fb_info_aty *info)
 {
     unsigned long temp;
 
+    /* Hack for bloc 1, should be cleanly optimized by compiler */
+    if (regindex >= 0x400)
+    	regindex -= 0x800;
+
 #if defined(__powerpc__)
     temp = info->ati_regbase;
      __asm__ __volatile__("stwbrx %0,%1,%2;eieio" : : "r" (val), "b" (regindex), "r" (temp) :
@@ -516,19 +526,29 @@
 #endif
 }
 
-static inline u8 aty_ld_8(volatile unsigned int regindex,
+static inline u8 aty_ld_8(volatile int regindex,
 			  const struct fb_info_aty *info)
 {
-    u8 val = *(volatile u8 *)(info->ati_regbase+regindex);
+    u8 val;
+
+    /* Hack for bloc 1, should be cleanly optimized by compiler */
+    if (regindex >= 0x400)
+    	regindex -= 0x800;
+
+    val = *(volatile u8 *)(info->ati_regbase+regindex);
 #if defined(__powerpc__)
     eieio();
 #endif
     return val;
 }
 
-static inline void aty_st_8(volatile unsigned int regindex, u8 val,
+static inline void aty_st_8(volatile int regindex, u8 val,
 			    const struct fb_info_aty *info)
 {
+    /* Hack for bloc 1, should be cleanly optimized by compiler */
+    if (regindex >= 0x400)
+    	regindex -= 0x800;
+
     *(volatile u8 *)(info->ati_regbase+regindex) = val;
 #if defined(__powerpc__)
     eieio();
@@ -596,6 +616,16 @@
 			  BUS_FIFO_ERR_ACK, info);
 }
 
+static void reset_GTC_3D_engine(const struct fb_info_aty *info)
+{
+	aty_st_le32(SCALE_3D_CNTL, 0xc0, info);
+	mdelay(GTC_3D_RESET_DELAY);
+	aty_st_le32(SETUP_CNTL, 0x00, info);
+	mdelay(GTC_3D_RESET_DELAY);
+	aty_st_le32(SCALE_3D_CNTL, 0x00, info);
+	mdelay(GTC_3D_RESET_DELAY);
+}
+
 static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info)
 {
     u32 pitch_value;
@@ -609,8 +639,16 @@
 	pitch_value = pitch_value * 3;
     }
 
+    /* On GTC (RagePro), we need to reset the 3D engine first */
+    if (Gx == LB_CHIP_ID || Gx == LD_CHIP_ID || Gx == LI_CHIP_ID ||
+    	Gx == LP_CHIP_ID || Gx == GB_CHIP_ID || Gx == GD_CHIP_ID ||
+    	Gx == GI_CHIP_ID || Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID ||
+    	Gx == LM_CHIP_ID || Gx == LN_CHIP_ID)
+    	reset_GTC_3D_engine(info);
+
     /* Reset engine, enable, and clear any engine errors */
     reset_engine(info);
+
     /* Ensure that vga page pointers are set to zero - the upper */
     /* page pointers are set to 1 to handle overflows in the */
     /* lower page */
diff -urN linux-2.2.17-pre15/fs/coda/cache.c linux/fs/coda/cache.c
--- linux-2.2.17-pre15/fs/coda/cache.c	Mon Aug  9 12:05:10 1999
+++ linux/fs/coda/cache.c	Mon Dec  3 22:10:51 2001
@@ -24,82 +24,49 @@
 #include <linux/coda_fs_i.h>
 #include <linux/coda_cache.h>
 
-static void coda_ccinsert(struct coda_cache *el, struct super_block *sb);
-static void coda_cninsert(struct coda_cache *el, struct coda_inode_info *cii);
-static void coda_ccremove(struct coda_cache *el);
-static void coda_cnremove(struct coda_cache *el);
-static void coda_cache_create(struct inode *inode, int mask);
-static struct coda_cache * coda_cache_find(struct inode *inode);
-
-
-/* insert a acl-cache entry in sb list */
-static void coda_ccinsert(struct coda_cache *el, struct super_block *sb)
+/* create a new acl cache entry and enlist it */
+static struct coda_cache *coda_cache_create(struct inode *inode)
 {
-	struct coda_sb_info *sbi = coda_sbp(sb);
+	struct coda_inode_info *cii = ITOC(inode);
+	struct coda_sb_info *sbi = coda_sbp(inode->i_sb);
+	struct coda_cache *cc = NULL;
 	ENTRY;
-	/* third test verifies cc was initialized before adding it 
-	   to the sblist. Probably superfluous */
-	if ( !sbi || !el || !list_empty(&el->cc_cclist) ) {
-		printk("coda_ccinsert: NULL sbi or el->cc_cclist not empty!\n");
-		return ;
-	}
 
-	list_add(&el->cc_cclist, &sbi->sbi_cchead);
-}
+	if ( !sbi || !cii ) {
+		printk("coda_cache_create: NULL sbi or cii!\n");
+		return NULL;
+	}
 
-/* insert a acl-cache entry in the inode list */
-static void coda_cninsert(struct coda_cache *el, struct coda_inode_info *cii)
-{
-	ENTRY;
-	if ( !cii ||  !el || ! list_empty(&el->cc_cnlist)) {
-		printk("coda_cninsert: NULL cii or el->cc_cnlist not empty!\n");
-		return ;
+	CODA_ALLOC(cc, struct coda_cache *, sizeof(struct coda_cache));
+	if ( !cc ) {
+		printk("Out of memory in coda_cache_create!\n");
+		return NULL;
 	}
-	list_add(&el->cc_cnlist, &cii->c_cnhead);
-}
 
-/* remove a cache entry from the superblock list */
-static void coda_ccremove(struct coda_cache *el)
-{
-	ENTRY;
-        if ( ! list_empty(&el->cc_cclist) )
-	        list_del(&el->cc_cclist);
-	else
-		printk("coda_ccremove: loose cc entry!");
-}
+	coda_load_creds(&cc->cc_cred);
+	cc->cc_mask = 0;
 
-/* remove a cache entry from the inode's list */
-static void coda_cnremove(struct coda_cache *el)
-{
-	ENTRY;
-	if ( ! list_empty(&el->cc_cnlist) )
-		list_del(&el->cc_cnlist);
-	else
-		printk("coda_cnremove: loose cn entry!");
+	INIT_LIST_HEAD(&cc->cc_cclist);
+	INIT_LIST_HEAD(&cc->cc_cnlist);
+	list_add(&cc->cc_cclist, &sbi->sbi_cchead);
+	list_add(&cc->cc_cnlist, &cii->c_cnhead);
+
+	return cc;
 }
 
-/* create a new cache entry and enlist it */
-static void coda_cache_create(struct inode *inode, int mask)
+/* destroy an acl cache entry */
+static void coda_cache_destroy(struct coda_cache *el)
 {
-	struct coda_inode_info *cii = ITOC(inode);
-	struct super_block *sb = inode->i_sb;
-	struct coda_cache *cc = NULL;
 	ENTRY;
 
-	CODA_ALLOC(cc, struct coda_cache *, sizeof(*cc));
-
-	if ( !cc ) {
-		printk("Out of memory in coda_cache_enter!\n");
+	if (list_empty(&el->cc_cclist) || list_empty(&el->cc_cnlist)) {
+		printk("coda_cache_destroy: loose entry!");
 		return;
 	}
 
-	INIT_LIST_HEAD(&cc->cc_cclist);
-	INIT_LIST_HEAD(&cc->cc_cnlist);
-
-	coda_load_creds(&cc->cc_cred);
-	cc->cc_mask = mask;
-	coda_cninsert(cc, cii);
-	coda_ccinsert(cc, sb);
+	list_del(&el->cc_cclist);
+	list_del(&el->cc_cnlist);
+	CODA_FREE(el, sizeof(struct coda_cache));
 }
 
 /* see if there is a match for the current 
@@ -107,11 +74,11 @@
 static struct coda_cache * coda_cache_find(struct inode *inode)
 {
 	struct coda_inode_info *cii = ITOC(inode);
-	struct list_head *lh, *le;
+	struct list_head *le;
 	struct coda_cache *cc = NULL;
 	
-	le = lh = &cii->c_cnhead;
-	while( (le = le->next ) != lh )  {
+	for(le = cii->c_cnhead.next; le != &cii->c_cnhead; le = le->next)
+	{
 		/* compare name and creds */
 		cc = list_entry(le, struct coda_cache, cc_cnlist);
 		if ( !coda_cred_ok(&cc->cc_cred) )
@@ -119,7 +86,7 @@
 		CDEBUG(D_CACHE, "HIT for ino %ld\n", inode->i_ino );
 		return cc; /* cache hit */
 	}
-		return NULL;
+	return NULL;
 }
 
 /* create or extend an acl cache hit */
@@ -129,11 +96,11 @@
 
 	cc = coda_cache_find(inode);
 
-	if ( cc ) {
+	if (!cc)
+		coda_cache_create(inode);
+
+	if (cc)
 		cc->cc_mask |= mask;
-	} else {
-		coda_cache_create(inode, mask);
-	}
 }
 
 /* remove all cached acl matches from an inode */
@@ -154,9 +121,7 @@
 	while ( le != &cii->c_cnhead ) {
 		cc = list_entry(le, struct coda_cache, cc_cnlist);
 		le = le->next;
-		coda_cnremove(cc);
-		coda_ccremove(cc);
-		CODA_FREE(cc, sizeof(*cc));
+		coda_cache_destroy(cc);
 	}
 }
 
@@ -172,16 +137,11 @@
 		return;
 	}
 	
-	if ( list_empty(&sbi->sbi_cchead) )
-		return;
-
 	le = sbi->sbi_cchead.next;
 	while ( le != &sbi->sbi_cchead ) {
 		cc = list_entry(le, struct coda_cache, cc_cclist);
 		le = le->next;
-		coda_cnremove(cc);
-		coda_ccremove(cc);
-		CODA_FREE(cc, sizeof(*cc));
+		coda_cache_destroy(cc);
 	}
 }
 
@@ -197,18 +157,12 @@
 		return;
 	}
 	
-	if (list_empty(&sbi->sbi_cchead))
-		return;
-
 	le = sbi->sbi_cchead.next;
 	while ( le != &sbi->sbi_cchead ) {
 		cc = list_entry(le, struct coda_cache, cc_cclist);
 		le = le->next;
-		if ( coda_cred_eq(&cc->cc_cred, cred)) {
-			coda_cnremove(cc);
-			coda_ccremove(cc);
-			CODA_FREE(cc, sizeof(*cc));
-		}
+		if (coda_cred_eq(&cc->cc_cred, cred))
+			coda_cache_destroy(cc);
 	}
 }
 
@@ -218,11 +172,11 @@
 int coda_cache_check(struct inode *inode, int mask)
 {
 	struct coda_inode_info *cii = ITOC(inode);
-	struct list_head *lh, *le;
+	struct list_head *le;
 	struct coda_cache *cc = NULL;
 	
-	le = lh = &cii->c_cnhead;
-	while( (le = le->next ) != lh )  {
+	for(le = cii->c_cnhead.next; le != &cii->c_cnhead; le = le->next)
+	{
 		/* compare name and creds */
 		cc = list_entry(le, struct coda_cache, cc_cnlist);
 		if ( (cc->cc_mask & mask) != mask ) 
@@ -232,8 +186,8 @@
 		CDEBUG(D_CACHE, "HIT for ino %ld\n", inode->i_ino );
 		return 1; /* cache hit */
 	}
-		CDEBUG(D_CACHE, "MISS for ino %ld\n", inode->i_ino );
-		return 0;
+	CDEBUG(D_CACHE, "MISS for ino %ld\n", inode->i_ino );
+	return 0;
 }
 
 
@@ -294,10 +248,10 @@
 	struct list_head *child;
 	struct dentry *de;
 
-	child = parent->d_subdirs.next;
-	while ( child != &parent->d_subdirs ) {
+	for(child = parent->d_subdirs.next; child != &parent->d_subdirs;
+	    child = child->next)
+	{
 		de = list_entry(child, struct dentry, d_child);
-		child = child->next;
 		/* don't know what to do with negative dentries */
 		if ( ! de->d_inode ) 
 			continue;
@@ -315,7 +269,7 @@
 	struct dentry *alias_de;
 
 	ENTRY;
-	if ( !inode ) 
+	if ( !inode || !S_ISDIR(inode->i_mode)) 
 		return; 
 
 	if (list_empty(&inode->i_dentry))
@@ -338,14 +292,7 @@
 /* this will not zap the inode away */
 void coda_flag_inode(struct inode *inode, int flag)
 {
-	struct coda_inode_info *cii;
-
-	if ( !inode ) {
-		CDEBUG(D_CACHE, " no inode!\n");
-		return;
-	}
-
-	cii = ITOC(inode);
+	struct coda_inode_info *cii = ITOC(inode);
 	cii->c_flags |= flag;
 }		
 
diff -urN linux-2.2.17-pre15/fs/coda/cnode.c linux/fs/coda/cnode.c
--- linux-2.2.17-pre15/fs/coda/cnode.c	Mon Aug  9 12:05:10 1999
+++ linux/fs/coda/cnode.c	Mon Dec  3 22:10:51 2001
@@ -3,6 +3,7 @@
    */
 
 #include <linux/types.h>
+#include <linux/string.h>
 #include <linux/time.h>
 
 #include <linux/coda.h>
@@ -96,6 +97,8 @@
 	cnp = ITOC(*inode);
 	/* see if we've got it already */
 	if  ( cnp->c_magic != 0 && coda_fideq(fid, &cnp->c_fid)) {
+		/* replace the attributes, type might have changed */
+		coda_fill_inode(*inode, &attr);
 		return 0;
 	}
 
@@ -117,19 +120,26 @@
        INIT_LIST_HEAD(&(cnp->c_volrootlist));
 
 	/* fill in the inode attributes */
-	if ( coda_f2i(fid) != ino ) {
-	        if ( !coda_fid_is_weird(fid) ) 
-		        printk("Coda: unknown weird fid: ino %ld, fid %s."
-			       "Tell Peter.\n", (long)ino, coda_f2s(&cnp->c_fid));
-		list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead);
-		CDEBUG(D_UPCALL, "Added %ld ,%s to volroothead\n",
-		       (long)ino, coda_f2s(&cnp->c_fid));
+        coda_fill_inode(*inode, &attr);
+
+	if ( coda_f2i(fid) == ino )
+		goto out;
+
+	/* check if we expected this weird fid */
+	if ( !coda_fid_is_weird(fid) ) {
+		printk("Coda: unknown weird fid: ino %ld, fid %s."
+				"Tell Peter.\n", (long)ino, coda_f2s(&cnp->c_fid));
+		goto out;
 	}
 
-        coda_fill_inode(*inode, &attr);
-	CDEBUG(D_DOWNCALL, "Done making inode: ino %ld,  count %d with %s\n",
-	        (*inode)->i_ino, (*inode)->i_count, 
-	       coda_f2s(&cnp->c_fid));
+	/* add the inode to a global list so we can find it back later */
+	list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead);
+	CDEBUG(D_UPCALL, "Added %ld ,%s to volroothead\n",
+	       (long)ino, coda_f2s(&cnp->c_fid));
+
+out:
+	CDEBUG(D_DOWNCALL, "Done making inode: ino %ld, count %d with %s\n",
+	        (*inode)->i_ino, (*inode)->i_count, coda_f2s(&cnp->c_fid));
 
         EXIT;
         return 0;
@@ -150,7 +160,8 @@
 	cnp->c_fid = *newfid;
 
 	list_del(&cnp->c_volrootlist);
-	if ( !coda_fid_is_weird(newfid) ) 
+	INIT_LIST_HEAD(&cnp->c_volrootlist);
+	if ( coda_fid_is_weird(newfid) ) 
 		list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead);
 
 	return;
diff -urN linux-2.2.17-pre15/fs/coda/dir.c linux/fs/coda/dir.c
--- linux-2.2.17-pre15/fs/coda/dir.c	Mon Aug  9 12:05:10 1999
+++ linux/fs/coda/dir.c	Mon Dec  3 22:10:51 2001
@@ -37,8 +37,8 @@
 			const char *symname);
 static int coda_mkdir(struct inode *dir_inode, struct dentry *entry, int mode);
 static int coda_rmdir(struct inode *dir_inode, struct dentry *entry);
-static int coda_rename(struct inode *old_inode, struct dentry *old_dentry, 
-                       struct inode *new_inode, struct dentry *new_dentry);
+static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, 
+                       struct inode *new_dir, struct dentry *new_dentry);
 
 /* dir file-ops */
 static int coda_readdir(struct file *file, void *dirent, filldir_t filldir);
@@ -52,7 +52,6 @@
 			      filldir_t filldir);
 int coda_fsync(struct file *, struct dentry *dentry);
 
-int coda_crossvol_rename = 0;
 int coda_hasmknod = 0;
 
 struct dentry_operations coda_dentry_operations =
@@ -111,9 +110,9 @@
 {
         struct coda_inode_info *dircnp;
 	struct inode *res_inode = NULL;
-	struct ViceFid resfid;
+	struct ViceFid resfid = {0,0,0};
 	int dropme = 0; /* to indicate entry should not be cached */
-	int type;
+	int type = 0;
 	int error = 0;
 	const char *name = entry->d_name.name;
 	size_t length = entry->d_name.len;
@@ -137,6 +136,7 @@
 		CDEBUG(D_SPECIAL, 
 		       "Lookup on CTL object; dir ino %ld, count %d\n", 
 		       dir->i_ino, dir->i_count);
+		dropme = 1;
                 goto exit;
         }
 
@@ -151,9 +151,14 @@
 			       coda_f2s(&resfid));
 			dropme = 1;
 		}
+
 	    	error = coda_cnode_make(&res_inode, &resfid, dir->i_sb);
-		if (error)
-			return ERR_PTR(error);
+		if (error) return ERR_PTR(error);
+
+		/* make sure we drop unexpected non-hashable fids */
+		if (coda_f2i(&resfid) != res_inode->i_ino &&
+		    !coda_fid_is_weird(&resfid))
+			dropme = 1;
 	} else if (error != -ENOENT) {
 	        CDEBUG(D_INODE, "error for %s(%*s)%d\n",
 		       coda_f2s(&dircnp->c_fid), (int)length, name, error);
@@ -168,7 +173,7 @@
 	d_add(entry, res_inode);
 	if ( dropme ) {
 		d_drop(entry);
-		ITOC(res_inode)->c_flags |= C_VATTR;
+		coda_flag_inode(res_inode, C_VATTR);
 	}
         EXIT;
         return NULL;
@@ -184,9 +189,8 @@
 	coda_vfs_stat.permission++;
 	coda_permission_stat.count++;
 
-        if ( mask == 0 ) {
+        if ( mask == 0 )
                 return 0;
-        }
 
 	if ( coda_access_cache == 1 ) {
 		if ( coda_cache_check(inode, mask) ) {
@@ -203,17 +207,29 @@
         CDEBUG(D_INODE, "fid: %s, ino: %ld (mask: %o) error: %d\n", 
 	       coda_f2s(&(cp->c_fid)), inode->i_ino, mask, error);
 
-	if ( error == 0 ) {
+	if (!error)
 		coda_cache_enter(inode, mask);
-	}
 
         return error; 
 }
 
-
+static inline void coda_dir_changed(struct inode *dir, int link)
+{
+#ifdef REQUERY_VENUS_FOR_MTIME
+	/* invalidate the directory cnode's attributes to refetch the
+	 * attributes from venus next time the inode is referenced */
+	coda_flag_inode(dir, C_VATTR);
+#else
+	/* optimistically we can also act as if our nose bleeds. The
+	 * granularity of the mtime is coarse anyways so we might actually be
+	 * right most of the time. Note: we only do this for directories. */
+	dir->i_mtime = CURRENT_TIME;
+#endif
+	if (link)
+		dir->i_nlink += link;
+}
 
 /* creation routines: create, mknod, mkdir, link, symlink */
-
 static int coda_create(struct inode *dir, struct dentry *de, int mode)
 {
         int error=0;
@@ -252,10 +268,10 @@
 	}
 
 	/* invalidate the directory cnode's attributes */
-	dircnp->c_flags |= C_VATTR;
+	coda_dir_changed(dir, 0);
 	d_instantiate(de, result);
         return 0;
-}			     
+}
 
 static int coda_mknod(struct inode *dir, struct dentry *de, int mode, int rdev)
 {
@@ -297,7 +313,7 @@
 	}
 
 	/* invalidate the directory cnode's attributes */
-	dircnp->c_flags |= C_VATTR;
+	coda_dir_changed(dir, 0);
 	d_instantiate(de, result);
         return 0;
 }			     
@@ -344,8 +360,7 @@
 	}
 	
 	/* invalidate the directory cnode's attributes */
-	dircnp->c_flags |= C_VATTR;
-	dir->i_nlink++;
+	coda_dir_changed(dir, 1);
 	d_instantiate(de, inode);
         return 0;
 }
@@ -375,16 +390,17 @@
         error = venus_link(dir_inode->i_sb,&(cnp->c_fid), &(dir_cnp->c_fid), 
 			   (const char *)name, len);
 
-	if (  ! error ) { 
-		dir_cnp->c_flags |= C_VATTR;
-		++inode->i_count;
-		d_instantiate(de, inode);
-		inode->i_nlink++;
-	} else  {
+	if (error) { 
 		d_drop(de);
-		return error;
+		goto out;	
 	}
 
+	coda_dir_changed(dir_inode, 0);
+	inode->i_count++;
+	d_instantiate(de, inode);
+	inode->i_nlink++;
+
+out:
         CDEBUG(D_INODE, "link result %d\n",error);
 	EXIT;
         return(error);
@@ -421,9 +437,8 @@
 			      symname, symlen);
 
 	/* mtime is no good anymore */
-	if ( !error ) {
-		dir_cnp->c_flags |= C_VATTR;
-	}
+	if ( !error )
+		coda_dir_changed(dir_inode, 0);
 
         CDEBUG(D_INODE, "in symlink result %d\n",error);
         EXIT;
@@ -451,7 +466,7 @@
         }
 
         /* cache management: mtime has changed, ask Venus */
-	dircnp->c_flags |= C_VATTR;
+	coda_dir_changed(dir, 0);
 	de->d_inode->i_nlink--;
 	d_delete(de);
 
@@ -479,8 +494,9 @@
                 return error;
         }
 
-	if (de->d_inode->i_nlink)
-		de->d_inode->i_nlink --;
+	coda_dir_changed(dir, -1);
+	de->d_inode->i_nlink--;
+	d_delete(de);
 
         return 0;
 }
@@ -493,7 +509,6 @@
         const char *new_name = new_dentry->d_name.name;
 	int old_length = old_dentry->d_name.len;
 	int new_length = new_dentry->d_name.len;
-	struct inode *new_inode = new_dentry->d_inode;
         struct coda_inode_info *new_cnp, *old_cnp;
         int error;
 
@@ -508,28 +523,29 @@
 	       old_name, old_length, (long)strlen(old_name), new_name, new_length, 
 	       (long)strlen(new_name),old_dentry->d_count, new_dentry->d_count);
 
-	/* the C library will do unlink/create etc */
-	if ( coda_crossvol_rename == 0 && 
-	     old_cnp->c_fid.Volume != new_cnp->c_fid.Volume )
-		return -EXDEV;
-
         error = venus_rename(old_dir->i_sb, &(old_cnp->c_fid), 
 			     &(new_cnp->c_fid), old_length, new_length, 
 			     (const char *) old_name, (const char *)new_name);
 
-        if ( error ) {
-                CDEBUG(D_INODE, "returned error %d\n", error);
-                return error;
+        if ( !error ) {
+		if ( new_dentry->d_inode ) {
+			if ( S_ISDIR(new_dentry->d_inode->i_mode) ) {
+				old_dir->i_nlink--;
+				new_dir->i_nlink++;
+			}
+			coda_flag_inode(new_dentry->d_inode, C_VATTR);
+		}
+
+		/* coda_flag_inode(old_dir, C_VATTR); */
+		/* coda_flag_inode(new_dir, C_VATTR); */
+		old_dir->i_mtime = new_dir->i_mtime = CURRENT_TIME;
         }
 
-	coda_flag_inode(new_inode, C_VATTR);
-	coda_flag_inode(old_dir, C_VATTR);
-	coda_flag_inode(new_dir, C_VATTR);
 
 	CDEBUG(D_INODE, "result %d\n", error); 
 
 	EXIT;
-	return 0;
+	return error;
 }
 
 
@@ -589,7 +605,6 @@
 
         cnp = ITOC(i);
 
-
 	error = venus_open(i->i_sb, &(cnp->c_fid), coda_flags, &ino, &dev); 
 	if (error) {
 	        CDEBUG(D_FILE, "venus: dev %d, inode %ld, out->result %d\n",
@@ -617,7 +632,7 @@
 		cnp->c_ovp = NULL;
 	}
 	cnp->c_ovp = cont_inode; 
-        cnp->c_ocount++;
+	cnp->c_contcount++;
 
         CDEBUG(D_FILE, "result %d, coda i->i_count is %d for ino %ld\n", 
 	       error, i->i_count, i->i_ino);
@@ -642,24 +657,16 @@
 	cred = (struct coda_cred *)f->private_data;
 
         cnp =ITOC(i);
-        CHECK_CNODE(cnp);
         CDEBUG(D_FILE,  
-	       "RELEASE coda (ino %ld, ct %d) cache (ino %ld, ct %d)\n",
-               i->i_ino, i->i_count, (cnp->c_ovp ? cnp->c_ovp->i_ino : 0),
+	       "RELEASE coda (ino %ld, ct %d, ref %d) cache (ino %ld, ct %d)\n",
+               i->i_ino, i->i_count, cnp->c_contcount,
+	       (cnp->c_ovp ? cnp->c_ovp->i_ino : 0),
                (cnp->c_ovp ? cnp->c_ovp->i_count : -99));
 
-
-        /* even when c_ocount=0 we cannot put c_ovp to
-         * NULL since the file may be mmapped.
-	 * See code in inode.c (coda_put_inode) for
-	 * further handling of close.
-	 */
-
-        --cnp->c_ocount;
-
-        if (flags & (O_WRONLY | O_RDWR)) {
-                --cnp->c_owrite;
-        }
+	if (--cnp->c_contcount == 0) {
+		iput(cnp->c_ovp);
+		cnp->c_ovp = NULL;
+	}
 
 	error = venus_release(i->i_sb, &(cnp->c_fid), cflags, cred);
 
@@ -780,7 +787,6 @@
 /* called when a cache lookup succeeds */
 static int coda_dentry_revalidate(struct dentry *de, int flags)
 {
-	int valid = 1;
 	struct inode *inode = de->d_inode;
 	struct coda_inode_info *cii;
 	ENTRY;
@@ -788,14 +794,14 @@
 	if (!inode)
 		return 1;
 
-	cii = ITOC(de->d_inode);
 	if (coda_isroot(inode))
 		return 1;
 	if (is_bad_inode(inode))
 		return 0;
 
+	cii = ITOC(de->d_inode);
 	if (! (cii->c_flags & (C_PURGE | C_FLUSH)) )
-		return valid;
+		return 1;
 
 	shrink_dcache_parent(de);
 
@@ -825,9 +831,9 @@
 	int flags;
 
 	if (!dentry->d_inode) 
-		return ;
+		return;
 
-	flags =  (ITOC(dentry->d_inode)->c_flags) & C_PURGE;
+	flags = (ITOC(dentry->d_inode)->c_flags) & C_PURGE;
 	if (is_bad_inode(dentry->d_inode) || flags) {
 		CDEBUG(D_DOWNCALL, "bad inode, unhashing %s/%s, %ld\n", 
 		       dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -862,19 +868,10 @@
 	if ( cii->c_flags == 0 )
 		return 0;
 
-	/* Venus closed the device .... */
-	if ( cii->c_flags & C_DYING ) { 
-		make_bad_inode(inode);
-		return -EIO;
-	}
-
-	
 	if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) {
 		error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
-		if ( error ) { 
-			make_bad_inode(inode);
+		if ( error )
 			return -EIO;
-		}
 
 		/* this inode may be lost if:
 		   - it's ino changed 
@@ -885,17 +882,15 @@
 		old_ino = inode->i_ino;
 		coda_vattr_to_iattr(inode, &attr);
 
-
 		if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) {
 			printk("Coda: inode %ld, fid %s changed type!\n",
 			       inode->i_ino, coda_f2s(&(cii->c_fid)));
 		}
 
 		/* the following can happen when a local fid is replaced 
-		   with a global one, here we lose and declar the inode bad */
+		   with a global one, here we lose and declare the inode bad */
 		if (inode->i_ino != old_ino) {
 			make_bad_inode(inode);
-			inode->i_mode = old_mode;
 			return -EIO;
 		}
 		
diff -urN linux-2.2.17-pre15/fs/coda/file.c linux/fs/coda/file.c
--- linux-2.2.17-pre15/fs/coda/file.c	Mon Aug  9 12:05:10 1999
+++ linux/fs/coda/file.c	Mon Dec  3 22:10:51 2001
@@ -115,7 +115,6 @@
 
         ENTRY;
 	cii = ITOC(file->f_dentry->d_inode);
-	cii->c_mmcount++;
   
 	res =generic_file_mmap(file, vma);
 	EXIT;
@@ -136,7 +135,6 @@
 	coda_vfs_stat.file_read++;
 
         cnp = ITOC(coda_inode);
-        CHECK_CNODE(cnp);
 	
         cont_inode = cnp->c_ovp;
         if ( cont_inode == NULL ) {
@@ -177,7 +175,6 @@
 	coda_vfs_stat.file_write++;
 
         cnp = ITOC(coda_inode);
-        CHECK_CNODE(cnp);
 
         cont_inode = cnp->c_ovp;
         if ( cont_inode == NULL ) {
@@ -221,7 +218,6 @@
 		return -EINVAL;
 
         cnp = ITOC(coda_inode);
-        CHECK_CNODE(cnp);
 
         cont_inode = cnp->c_ovp;
         if ( cont_inode == NULL ) {
diff -urN linux-2.2.17-pre15/fs/coda/inode.c linux/fs/coda/inode.c
--- linux-2.2.17-pre15/fs/coda/inode.c	Mon Aug  9 12:05:10 1999
+++ linux/fs/coda/inode.c	Mon Dec  3 22:10:51 2001
@@ -37,8 +37,7 @@
 static struct super_block *coda_read_super(struct super_block *, void *, int);
 static void coda_read_inode(struct inode *);
 static int  coda_notify_change(struct dentry *dentry, struct iattr *attr);
-static void coda_put_inode(struct inode *);
-static void coda_delete_inode(struct inode *);
+static void coda_clear_inode(struct inode *);
 static void coda_put_super(struct super_block *);
 static int coda_statfs(struct super_block *sb, struct statfs *buf, 
 		       int bufsiz);
@@ -48,13 +47,14 @@
 {
 	coda_read_inode,        /* read_inode */
 	NULL,                   /* write_inode */
-	coda_put_inode,	        /* put_inode */
-	coda_delete_inode,      /* delete_inode */
+	NULL,			/* put_inode */
+	NULL,			/* delete_inode */
 	coda_notify_change,	/* notify_change */
 	coda_put_super,	        /* put_super */
 	NULL,			/* write_super */
 	coda_statfs,   		/* statfs */
-	NULL			/* remount_fs */
+	NULL,			/* remount_fs */
+	coda_clear_inode	/* clear_inode */
 };
 
 static struct super_block * coda_read_super(struct super_block *sb, 
@@ -165,35 +165,22 @@
 	return;
 }
 
-static void coda_put_inode(struct inode *in) 
+static void coda_clear_inode(struct inode *inode) 
 {
-	ENTRY;
-
-        CDEBUG(D_INODE,"ino: %ld, count %d\n", in->i_ino, in->i_count);
-
-	if ( in->i_count == 1 ) 
-		in->i_nlink = 0;
-		
-}
-
-static void coda_delete_inode(struct inode *inode)
-{
-        struct coda_inode_info *cii;
+	struct coda_inode_info *cii = ITOC(inode);
         struct inode *open_inode;
 
         ENTRY;
         CDEBUG(D_SUPER, " inode->ino: %ld, count: %d\n", 
 	       inode->i_ino, inode->i_count);        
 
-        cii = ITOC(inode);
-	if ( inode->i_ino == CTL_INO || cii->c_magic != CODA_CNODE_MAGIC ) {
-	        clear_inode(inode);
-		return;
-	}
-
-
-	if ( ! list_empty(&cii->c_volrootlist) )
+	if ( inode->i_ino == CTL_INO || cii->c_magic != CODA_CNODE_MAGIC )
+		goto out;
+	
+	if ( !list_empty(&cii->c_volrootlist) ) {
 		list_del(&cii->c_volrootlist);
+		INIT_LIST_HEAD(&cii->c_volrootlist);
+	}
 
         open_inode = cii->c_ovp;
         if ( open_inode ) {
@@ -202,11 +189,12 @@
                 cii->c_ovp = NULL;
                 iput(open_inode);
         }
-	
+
 	coda_cache_clear_inode(inode);
+
 	CDEBUG(D_DOWNCALL, "clearing inode: %ld, %x\n", inode->i_ino, cii->c_flags);
+out:
 	inode->u.coda_i.c_magic = 0;
-        clear_inode(inode);
 	EXIT;
 }
 
@@ -220,7 +208,6 @@
 	ENTRY;
         memset(&vattr, 0, sizeof(vattr)); 
         cii = ITOC(inode);
-        CHECK_CNODE(cii);
 
         coda_iattr_to_vattr(iattr, &vattr);
         vattr.va_type = C_VNON; /* cannot set type */
diff -urN linux-2.2.17-pre15/fs/coda/pioctl.c linux/fs/coda/pioctl.c
--- linux-2.2.17-pre15/fs/coda/pioctl.c	Mon Aug 31 15:46:10 1998
+++ linux/fs/coda/pioctl.c	Mon Dec  3 22:10:51 2001
@@ -26,8 +26,6 @@
 
 /* pioctl ops */
 static int coda_ioctl_permission(struct inode *inode, int mask);
-static int coda_ioctl_open(struct inode *i, struct file *f);
-static int coda_ioctl_release(struct inode *i, struct file *f);
 static int coda_pioctl(struct inode * inode, struct file * filp, 
                        unsigned int cmd, unsigned long arg);
 
@@ -64,9 +62,9 @@
 	NULL,			/* select - default */
 	coda_pioctl,	        /* ioctl */
 	NULL,                   /* mmap */
-	coda_ioctl_open,        /* open */
+	NULL,			/* open */
 	NULL,
-	coda_ioctl_release,     /* release */
+	NULL,			/* release */
 	NULL,		        /* fsync */
 };
 
@@ -77,25 +75,6 @@
 
         return 0;
 }
-
-/* The pioctl file ops*/
-int coda_ioctl_open(struct inode *i, struct file *f)
-{
-
-        ENTRY;
-
-        CDEBUG(D_PIOCTL, "File inode number: %ld\n", 
-	       f->f_dentry->d_inode->i_ino);
-
-	EXIT;
-        return 0;
-}
-
-int coda_ioctl_release(struct inode *i, struct file *f) 
-{
-        return 0;
-}
-
 
 static int coda_pioctl(struct inode * inode, struct file * filp, 
 		       unsigned int cmd, unsigned long user_data)
diff -urN linux-2.2.17-pre15/fs/coda/psdev.c linux/fs/coda/psdev.c
--- linux-2.2.17-pre15/fs/coda/psdev.c	Mon Aug  9 12:05:10 1999
+++ linux/fs/coda/psdev.c	Mon Dec  3 22:10:51 2001
@@ -69,37 +69,52 @@
         struct venus_comm *vcp = &coda_upc_comm;
 	unsigned int mask = POLLOUT | POLLWRNORM;
 
-	poll_wait(file, &(vcp->vc_waitq), wait);
+	poll_wait(file, &vcp->vc_waitq, wait);
 	if (!list_empty(&vcp->vc_pending))
                 mask |= POLLIN | POLLRDNORM;
 
 	return mask;
 }
 
+static int coda_psdev_ioctl(struct inode * inode, struct file * filp,
+			    unsigned int cmd, unsigned long arg)
+{
+	unsigned int data;
+
+	switch(cmd) {
+	case CIOC_KERNEL_VERSION:
+		data = CODA_KERNEL_VERSION;
+		return put_user(data, (int *) arg);
+	default:
+		return -ENOTTY;
+	}
+
+	return 0;
+}
 
 /*
  *	Receive a message written by Venus to the psdev
  */
  
 static ssize_t coda_psdev_write(struct file *file, const char *buf, 
-				size_t count, loff_t *off)
+				size_t nbytes, loff_t *off)
 {
         struct venus_comm *vcp = &coda_upc_comm;
         struct upc_req *req = NULL;
         struct upc_req *tmp;
 	struct list_head *lh;
 	struct coda_in_hdr hdr;
+	ssize_t retval = 0, count = 0;
 	int error;
 
-
-	if ( !coda_upc_comm.vc_pid ) 
+	if ( !coda_upc_comm.vc_inuse ) 
 		return -EIO;
         /* Peek at the opcode, uniquefier */
 	if (copy_from_user(&hdr, buf, 2 * sizeof(u_long)))
 	        return -EFAULT;
 
 	CDEBUG(D_PSDEV, "(process,opc,uniq)=(%d,%ld,%ld), count %ld\n", 
-	       current->pid, hdr.opcode, hdr.unique, (long)count);
+	       current->pid, hdr.opcode, hdr.unique, (long)nbytes);
 
         if (DOWNCALL(hdr.opcode)) {
 		struct super_block *sb = NULL;
@@ -108,37 +123,42 @@
 
 		sb = coda_super_info.sbi_sb;
 		if ( !sb ) {
-			printk("coda_psdev_write: downcall, no SB!\n");
-			return count;
+			CDEBUG(D_PSDEV, "coda_psdev_write: downcall, no SB!\n");
+			count = nbytes;
+			goto out;
 		}
 		CDEBUG(D_PSDEV, "handling downcall\n");
 
-		if  ( count < sizeof(struct coda_out_hdr) ) {
+		if  ( nbytes < sizeof(struct coda_out_hdr) ) {
 		        printk("coda_downcall opc %ld uniq %ld, not enough!\n",
 			       hdr.opcode, hdr.unique);
-			return count;
+			count = nbytes;
+			goto out;
 		}
-		CODA_ALLOC(dcbuf, union outputArgs *, size);
-		if ( count > size ) {
+		if ( nbytes > size ) {
 		        printk("Coda: downcall opc %ld, uniq %ld, too much!",
 			       hdr.opcode, hdr.unique);
-		        count = size;
+		        nbytes = size;
+		}
+		CODA_ALLOC(dcbuf, union outputArgs *, nbytes);
+		if (copy_from_user(dcbuf, buf, nbytes)) {
+			CODA_FREE(dcbuf, nbytes);
+			retval = -EFAULT;
+			goto out;
 		}
-		if (copy_from_user(dcbuf, buf, count))
-		        return -EFAULT;
 
 		/* what downcall errors does Venus handle ? */
 		error = coda_downcall(hdr.opcode, dcbuf, sb);
 
+		CODA_FREE(dcbuf, nbytes);
 		if ( error) {
-		        printk("psdev_write: coda_downcall error: %d\n", 
-			       error);
-			return 0;
+		        printk("psdev_write: coda_downcall error: %d\n", error);
+			retval = error;
+			goto out;
 		}
-		CODA_FREE(dcbuf, size);
-		return count;
+		count = nbytes;
+		goto out;
         }
-
         
         /* Look for the message on the processing queue. */
 	lh  = &vcp->vc_processing;
@@ -155,28 +175,35 @@
         if (!req) {
 	        printk("psdev_write: msg (%ld, %ld) not found\n", 
 		       hdr.opcode, hdr.unique);
-		return(-ESRCH);
+		retval = -ESRCH;
+		goto out;
         }
 
         /* move data into response buffer. */
-        if (req->uc_outSize < count) {
+        if (req->uc_outSize < nbytes) {
                 printk("psdev_write: too much cnt: %d, cnt: %ld, opc: %ld, uniq: %ld.\n",
-		       req->uc_outSize, (long)count, hdr.opcode, hdr.unique);
-		count = req->uc_outSize; /* don't have more space! */
+		       req->uc_outSize, (long)nbytes, hdr.opcode, hdr.unique);
+		nbytes = req->uc_outSize; /* don't have more space! */
+	}
+        if (copy_from_user(req->uc_data, buf, nbytes)) {
+		req->uc_flags |= REQ_ABORT;
+		wake_up(&req->uc_sleep);
+	        retval = -EFAULT;
+		goto out;
 	}
-        if (copy_from_user(req->uc_data, buf, count))
-	        return -EFAULT;
 
 	/* adjust outsize. is this usefull ?? */
-        req->uc_outSize = count;	
+        req->uc_outSize = nbytes;	
         req->uc_flags |= REQ_WRITE;
+	count = nbytes;
 
 	CDEBUG(D_PSDEV, 
 	       "Found! Count %ld for (opc,uniq)=(%ld,%ld), upc_req at %p\n", 
 	        (long)count, hdr.opcode, hdr.unique, &req);
 
         wake_up(&req->uc_sleep);
-        return(count);  
+out:
+        return(count ? count : retval);  
 }
 
 /*
@@ -184,78 +211,85 @@
  */
 
 static ssize_t coda_psdev_read(struct file * file, char * buf, 
-			       size_t count, loff_t *off)
+			       size_t nbytes, loff_t *off)
 {
+	struct wait_queue wait = { current, NULL };
         struct venus_comm *vcp = &coda_upc_comm;
         struct upc_req *req;
-	int result = count ;
+	ssize_t retval = 0, count = 0;
 
-        CDEBUG(D_PSDEV, "count %ld\n", (long)count);
-        if (list_empty(&(vcp->vc_pending))) {
-              return -1;	
-        }
-    
-        req = list_entry((vcp->vc_pending.next), struct upc_req, uc_chain);
-        list_del(&(req->uc_chain));
+	if (nbytes == 0)
+		return 0;
+
+	add_wait_queue(&vcp->vc_waitq, &wait);
+	current->state = TASK_INTERRUPTIBLE;
+
+	while (list_empty(&vcp->vc_pending)) {
+		if (file->f_flags & O_NONBLOCK) {
+			retval = -EAGAIN;
+			break;
+		}
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+		schedule();
+	}
+
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&vcp->vc_waitq, &wait);
+
+	if (retval)
+		goto out;
+
+	req = list_entry(vcp->vc_pending.next, struct upc_req, uc_chain);
+	list_del(&req->uc_chain);
 
         /* Move the input args into userspace */
-        if (req->uc_inSize <= count)
-              result = req->uc_inSize;
+	count = req->uc_inSize;
+	if (nbytes < req->uc_inSize) {
+		printk ("psdev_read: Venus read %ld bytes of %d in message\n",
+			(long)nbytes, req->uc_inSize);
+		count = nbytes;
+	}
 
-        if (count < req->uc_inSize) {
-                printk ("psdev_read: Venus read %ld bytes of %d in message\n",
-			(long)count, req->uc_inSize);
-        }
+        if (copy_to_user(buf, req->uc_data, count)) {
+		retval = -EFAULT;
+		goto free_out;
+	}
 
-        if ( copy_to_user(buf, req->uc_data, result))
-	        return -EFAULT;
-        
-        /* If request was a signal, don't enqueue */
-        if (req->uc_opcode == CODA_SIGNAL) {
-                    CDEBUG(D_PSDEV, "vcread: signal msg (%d, %d)\n", 
-                              req->uc_opcode, req->uc_unique);
-              CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr));
-              CODA_FREE(req, sizeof(struct upc_req));
-              return count;
-        }
-    
-        req->uc_flags |= REQ_READ;
-        list_add(&(req->uc_chain), vcp->vc_processing.prev);
+        /* If request was not a signal, enqueue and don't free */
+	if (req->uc_opcode != CODA_SIGNAL) {
+		req->uc_flags |= REQ_READ;
+		list_add(&req->uc_chain, vcp->vc_processing.prev);
+		goto out;
+	}
 
-        return result;
-}
+	CDEBUG(D_PSDEV, "vcread: signal msg (%d, %d)\n", 
+			req->uc_opcode, req->uc_unique);
 
+free_out:
+	CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr));
+	CODA_FREE(req, sizeof(struct upc_req));
+out:
+	return (count ? count : retval);
+}
 
 static int coda_psdev_open(struct inode * inode, struct file * file)
 {
         struct venus_comm *vcp = &coda_upc_comm;
         ENTRY;
 	
-	/* first opener: must be lento. Initialize & take its pid */
-	if ( file->f_flags == O_RDWR ) {
-		if ( vcp->vc_pid ) {
-			printk("Venus pid already set to %d!!\n", vcp->vc_pid);
-			return -1;
-		}
-		if ( vcp->vc_inuse ) {
-			printk("psdev_open: Cannot O_RDWR while open.\n");
-			return -1;
-		}
-	}
-	
-	vcp->vc_inuse++;
 	MOD_INC_USE_COUNT;
 
-
-	if ( file->f_flags == O_RDWR ) {
-		vcp->vc_pid = current->pid;
-		vcp->vc_seq = 0;
+	/* first opener, initialize */
+	if (!vcp->vc_inuse++) {
 		INIT_LIST_HEAD(&vcp->vc_pending);
 		INIT_LIST_HEAD(&vcp->vc_processing);
+		vcp->vc_seq = 0;
 	}
 
-	CDEBUG(D_PSDEV, "inuse: %d, vc_pid %d, caller %d\n",
-	       vcp->vc_inuse, vcp->vc_pid, current->pid);
+	CDEBUG(D_PSDEV, "inuse: %d\n", vcp->vc_inuse);
 
 	EXIT;
         return 0;
@@ -275,16 +309,13 @@
 		return -1;
 	}
 
-	vcp->vc_inuse--;
 	MOD_DEC_USE_COUNT;
-	CDEBUG(D_PSDEV, "inuse: %d, vc_pid %d, caller %d\n",
-	       vcp->vc_inuse, vcp->vc_pid, current->pid);
 
-	if ( vcp->vc_pid != current->pid ) {
+	CDEBUG(D_PSDEV, "psdev_release: inuse %d\n", vcp->vc_inuse);
+	if (--vcp->vc_inuse) {
 		return 0;
 	}
-        
-	vcp->vc_pid = 0;
+
         /* Wakeup clients so they can return. */
 	CDEBUG(D_PSDEV, "wake up pending clients\n");
 	lh = vcp->vc_pending.next;
@@ -305,6 +336,7 @@
 	CDEBUG(D_PSDEV, "wake up processing clients\n");
 	while ( (lh = lh->next) != &vcp->vc_processing) {
 		req = list_entry(lh, struct upc_req, uc_chain);
+		req->uc_flags |= REQ_ABORT;
 	        wake_up(&req->uc_sleep);
         }
 	CDEBUG(D_PSDEV, "Done.\n");
@@ -320,7 +352,7 @@
       coda_psdev_write,      /* write */
       NULL,		     /* coda_psdev_readdir */
       coda_psdev_poll,       /* poll */
-      NULL,                  /* ioctl */
+      coda_psdev_ioctl,      /* ioctl */
       NULL,		     /* coda_psdev_mmap */
       coda_psdev_open,       /* open */
       NULL,
@@ -361,6 +393,7 @@
 	}
 	memset(&coda_upc_comm, 0, sizeof(coda_upc_comm));
 	memset(&coda_super_info, 0, sizeof(coda_super_info));
+	coda_upc_comm.vc_waitq = NULL;
 
 	coda_sysctl_init();
 
@@ -375,7 +408,7 @@
 int init_module(void)
 {
 	int status;
-	printk(KERN_INFO "Coda Kernel/Venus communications (module), v5.0-pre1, braam@cs.cmu.edu.\n");
+	printk(KERN_INFO "Coda Kernel/Venus communications (module), v5.3.8, coda@cs.cmu.edu.\n");
 
 	status = init_coda_psdev();
 	if ( status ) {
diff -urN linux-2.2.17-pre15/fs/coda/stats.c linux/fs/coda/stats.c
--- linux-2.2.17-pre15/fs/coda/stats.c	Fri Dec 18 12:45:00 1998
+++ linux/fs/coda/stats.c	Wed Dec 31 16:00:00 1969
@@ -1,416 +0,0 @@
-/*
- * stats.c
- * 
- * CODA operation statistics
- *
- * (c) March, 1998 Zhanyong Wan <zhanyong.wan@yale.edu>
- *
- */
-
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/sysctl.h>
-#include <linux/swapctl.h>
-#include <linux/proc_fs.h>
-#include <linux/malloc.h>
-#include <linux/stat.h>
-#include <linux/ctype.h>
-#include <asm/bitops.h>
-#include <asm/segment.h>
-#include <asm/uaccess.h>
-#include <linux/utsname.h>
-
-#include <linux/coda.h>
-#include <linux/coda_linux.h>
-#include <linux/coda_fs_i.h>
-#include <linux/coda_psdev.h>
-#include <linux/coda_cache.h>
-#include <linux/coda_proc.h>
-
-struct coda_vfs_stats		coda_vfs_stat;
-struct coda_permission_stats	coda_permission_stat;
-struct coda_cache_inv_stats	coda_cache_inv_stat;
-struct coda_upcall_stats_entry coda_upcall_stat[CODA_NCALLS];
-
-/* keep this in sync with coda.h! */
-char *coda_upcall_names[] = {
-	"totals      ",   /*  0 */
-	"noop        ",   /*  1 */
-	"root        ",   /*  2 */
-	"sync        ",   /*  3 */
-	"open        ",   /*  4 */
-	"close       ",   /*  5 */
-	"ioctl       ",   /*  6 */
-	"getattr     ",   /*  7 */
-	"setattr     ",   /*  8 */
-	"access      ",   /*  9 */
-	"lookup      ",   /* 10 */
-	"create      ",   /* 11 */
-	"remove      ",   /* 12 */
-	"link        ",   /* 13 */
-	"rename      ",   /* 14 */
-	"mkdir       ",   /* 15 */
-	"rmdir       ",   /* 16 */
-	"readdir     ",   /* 17 */
-	"symlink     ",   /* 18 */
-	"readlink    ",   /* 19 */
-	"fsync       ",   /* 20 */
-	"inactive    ",   /* 21 */
-	"vget        ",   /* 22 */
-	"signal      ",   /* 23 */
-	"replace     ",   /* 24 */
-	"flush       ",   /* 25 */
-	"purgeuser   ",   /* 26 */
-	"zapfile     ",   /* 27 */
-	"zapdir      ",   /* 28 */
-	"zapvnode    ",   /* 28 */
-	"purgefid    ",   /* 30 */
-	"open_by_path"    /* 31 */
-};
-
-
-
-
-void reset_coda_vfs_stats( void )
-{
-	memset( &coda_vfs_stat, 0, sizeof( coda_vfs_stat ) );
-}
-
-#if 0
-static void reset_upcall_entry( struct coda_upcall_stats_entry * pentry )
-{
-	pentry->count = 0;
-	pentry->time_sum = pentry->time_squared_sum = 0;
-}
-#endif
-
-void reset_coda_upcall_stats( void )
-{
-	memset( &coda_upcall_stat, 0, sizeof( coda_upcall_stat ) );
-}
-
-void reset_coda_permission_stats( void )
-{
-	memset( &coda_permission_stat, 0, sizeof( coda_permission_stat ) );
-}
-
-void reset_coda_cache_inv_stats( void )
-{
-	memset( &coda_cache_inv_stat, 0, sizeof( coda_cache_inv_stat ) );
-}
-
-
-void do_time_stats( struct coda_upcall_stats_entry * pentry, 
-		    unsigned long runtime )
-{
-	
-	unsigned long time = runtime * 1000 /HZ;	/* time in ms */
-	CDEBUG(D_SPECIAL, "time: %ld\n", time);
-
-	if ( pentry->count == 0 ) {
-		pentry->time_sum = pentry->time_squared_sum = 0;
-	}
-	
-	pentry->count++;
-	pentry->time_sum += time;
-	pentry->time_squared_sum += time*time;
-}
-
-
-
-void coda_upcall_stats(int opcode, long unsigned runtime) 
-{
-	struct coda_upcall_stats_entry * pentry;
-	
-	if ( opcode < 0 || opcode > CODA_NCALLS - 1) {
-		printk("Nasty opcode %d passed to coda_upcall_stats\n",
-		       opcode);
-		return;
-	}
-		
-	pentry = &coda_upcall_stat[opcode];
-	do_time_stats(pentry, runtime);
-
-        /* fill in the totals */
-	pentry = &coda_upcall_stat[0];
-	do_time_stats(pentry, runtime);
-
-}
-
-unsigned long get_time_average( const struct coda_upcall_stats_entry * pentry )
-{
-	return ( pentry->count == 0 ) ? 0 : pentry->time_sum / pentry->count;
-}
-
-static inline unsigned long absolute( unsigned long x )
-{
-	return x >= 0 ? x : -x;
-}
-
-static unsigned long sqr_root( unsigned long x )
-{
-	unsigned long y = x, r;
-	int n_bit = 0;
-  
-	if ( x == 0 )
-		return 0;
-	if ( x < 0)
-		x = -x;
-
-	while ( y ) {
-		y >>= 1;
-		n_bit++;
-	}
-  
-	r = 1 << (n_bit/2);
-  
-	while ( 1 ) {
-		r = (r + x/r)/2;
-		if ( r*r <= x && x < (r+1)*(r+1) )
-			break;
-	}
-  
-	return r;
-}
-
-unsigned long get_time_std_deviation( const struct coda_upcall_stats_entry * pentry )
-{
-	unsigned long time_avg;
-  
-	if ( pentry->count <= 1 )
-		return 0;
-  
-	time_avg = get_time_average( pentry );
-	return 
-	        sqr_root( (pentry->time_squared_sum / pentry->count) - 
-			    time_avg * time_avg );
-}
-
-int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
-			     void * buffer, size_t * lenp )
-{
-	if ( write ) {
-		reset_coda_vfs_stats();
-	}
-  
-	*lenp = 0;
-	return 0;
-}
-
-int do_reset_coda_upcall_stats( ctl_table * table, int write, 
-				struct file * filp, void * buffer, 
-				size_t * lenp )
-{
-	if ( write ) {
-		reset_coda_upcall_stats();
-	}
-  
-	*lenp = 0;
-	return 0;
-}
-
-int do_reset_coda_permission_stats( ctl_table * table, int write, 
-				    struct file * filp, void * buffer, 
-				    size_t * lenp )
-{
-	if ( write ) {
-		reset_coda_permission_stats();
-	}
-  
-	*lenp = 0;
-	return 0;
-}
-
-int do_reset_coda_cache_inv_stats( ctl_table * table, int write, 
-				   struct file * filp, void * buffer, 
-				   size_t * lenp )
-{
-	if ( write ) {
-		reset_coda_cache_inv_stats();
-	}
-  
-	*lenp = 0;
-	return 0;
-}
-
-int coda_vfs_stats_get_info( char * buffer, char ** start, off_t offset,
-			     int length, int dummy )
-{
-	int len=0;
-	off_t begin;
-	struct coda_vfs_stats * ps = & coda_vfs_stat;
-  
-  /* this works as long as we are below 1024 characters! */
-	len += sprintf( buffer,
-			"Coda VFS statistics\n"
-			"===================\n\n"
-			"File Operations:\n"
-			"\tfile_read\t%9d\n"
-			"\tfile_write\t%9d\n"
-			"\tfile_mmap\t%9d\n"
-			"\topen\t\t%9d\n"
-			"\trelase\t\t%9d\n"
-			"\tfsync\t\t%9d\n\n"
-			"Dir Operations:\n"
-			"\treaddir\t\t%9d\n\n"
-			"Inode Operations\n"
-			"\tcreate\t\t%9d\n"
-			"\tlookup\t\t%9d\n"
-			"\tlink\t\t%9d\n"
-			"\tunlink\t\t%9d\n"
-			"\tsymlink\t\t%9d\n"
-			"\tmkdir\t\t%9d\n"
-			"\trmdir\t\t%9d\n"
-			"\trename\t\t%9d\n"
-			"\tpermission\t%9d\n"
-			"\treadpage\t%9d\n",
-
-			/* file operations */
-			ps->file_read,
-			ps->file_write,
-			ps->file_mmap,
-			ps->open,
-			ps->release,
-			ps->fsync,
-
-			/* dir operations */
-			ps->readdir,
-		  
-			/* inode operations */
-			ps->create,
-			ps->lookup,
-			ps->link,
-			ps->unlink,
-			ps->symlink,
-			ps->mkdir,
-			ps->rmdir,
-			ps->rename,
-			ps->permission,
-			ps->readpage );
-  
-	begin = offset;
-	*start = buffer + begin;
-	len -= begin;
-
-	if ( len > length )
-		len = length;
-	if ( len < 0 )
-		len = 0;
-
-	return len;
-}
-
-int coda_upcall_stats_get_info( char * buffer, char ** start, off_t offset,
-				int length, int dummy )
-{
-	int len=0;
-	int i;
-	off_t begin;
-	off_t pos = 0;
-	char tmpbuf[80];
-	int tmplen = 0;
-
-	ENTRY;
-	/* this works as long as we are below 1024 characters! */
-	if ( offset < 80 ) 
-		len += sprintf( buffer,"%-79s\n",	"Coda upcall statistics");
-	if ( offset < 160) 
-		len += sprintf( buffer + len,"%-79s\n",	"======================");
-	if ( offset < 240) 
-		len += sprintf( buffer + len,"%-79s\n",	"upcall\t\t    count\tavg time(ms)\tstd deviation(ms)");
-	if ( offset < 320) 
-		len += sprintf( buffer + len,"%-79s\n",	"------\t\t    -----\t------------\t-----------------");
-	pos = 320; 
-	for ( i = 0 ; i < CODA_NCALLS ; i++ ) {
-		tmplen += sprintf(tmpbuf,"%s\t%9d\t%10ld\t%10ld", 
-				  coda_upcall_names[i],
-				  coda_upcall_stat[i].count, 
-				  get_time_average(&coda_upcall_stat[i]),
-				  coda_upcall_stat[i].time_squared_sum);
-		pos += 80;
-		if ( pos < offset ) 
-			continue; 
-		len += sprintf(buffer + len, "%-79s\n", tmpbuf);
-		if ( len >= length ) 
-			break; 
-	}
-  
-	begin = len- (pos - offset);
-	*start = buffer + begin;
-	len -= begin;
-
-	if ( len > length )
-		len = length;
-	if ( len < 0 )
-		len = 0;
-	EXIT;
-	return len;
-}
-
-int coda_permission_stats_get_info( char * buffer, char ** start, off_t offset,
-				    int length, int dummy )
-{
-	int len=0;
-	off_t begin;
-	struct coda_permission_stats * ps = & coda_permission_stat;
-  
-	/* this works as long as we are below 1024 characters! */
-	len += sprintf( buffer,
-			"Coda permission statistics\n"
-			"==========================\n\n"
-			"count\t\t%9d\n"
-			"hit count\t%9d\n",
-
-			ps->count,
-			ps->hit_count );
-  
-	begin = offset;
-	*start = buffer + begin;
-	len -= begin;
-
-	if ( len > length )
-		len = length;
-	if ( len < 0 )
-		len = 0;
-
-	return len;
-}
-
-int coda_cache_inv_stats_get_info( char * buffer, char ** start, off_t offset,
-				   int length, int dummy )
-{
-	int len=0;
-	off_t begin;
-	struct coda_cache_inv_stats * ps = & coda_cache_inv_stat;
-  
-	/* this works as long as we are below 1024 characters! */
-	len += sprintf( buffer,
-			"Coda cache invalidation statistics\n"
-			"==================================\n\n"
-			"flush\t\t%9d\n"
-			"purge user\t%9d\n"
-			"zap_dir\t\t%9d\n"
-			"zap_file\t%9d\n"
-			"zap_vnode\t%9d\n"
-			"purge_fid\t%9d\n"
-			"replace\t\t%9d\n",
-			ps->flush,
-			ps->purge_user,
-			ps->zap_dir,
-			ps->zap_file,
-			ps->zap_vnode,
-			ps->purge_fid,
-			ps->replace );
-  
-	begin = offset;
-	*start = buffer + begin;
-	len -= begin;
-
-	if ( len > length )
-		len = length;
-	if ( len < 0 )
-		len = 0;
-
-	return len;
-}
-
diff -urN linux-2.2.17-pre15/fs/coda/upcall.c linux/fs/coda/upcall.c
--- linux-2.2.17-pre15/fs/coda/upcall.c	Mon Aug  9 12:05:10 1999
+++ linux/fs/coda/upcall.c	Mon Dec  3 22:10:51 2001
@@ -88,7 +88,7 @@
 		       fidp->Volume, fidp->Vnode);
 	}
 
-	if (inp)  CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
         EXIT;
 	return error;
 }
@@ -110,8 +110,7 @@
 	if ( !error )
 	        *attr = outp->coda_getattr.attr;
 
-        if (inp) 
-		CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
         EXIT;
         return error;
 }
@@ -132,7 +131,7 @@
         error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
 
         CDEBUG(D_SUPER, " result %d\n", error); 
-        if ( inp ) CODA_FREE(inp, insize);
+        CODA_FREE(inp, insize);
         return error;
 }
 
@@ -162,7 +161,7 @@
 	        *resfid = outp->coda_lookup.VFid;
 		*type = outp->coda_lookup.vtype;
 	}
-	if (inp) CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 		
 	return error;
 }
@@ -188,8 +187,7 @@
 
         error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
 
-        if (inp) 
-		CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
         return error;
 }
 
@@ -216,8 +214,7 @@
 		*dev = 0;
 	}
 
-        if (inp) 
-                CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 
 	return error;
 }	
@@ -247,8 +244,7 @@
 	*attrs = outp->coda_mkdir.attr;
 	*newfid = outp->coda_mkdir.VFid;
 
-	if (inp) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;        
 }
 
@@ -288,7 +284,7 @@
               (char *)inp + (int) inp->coda_rename.destname);
         error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
 
-	if (inp) CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;
 }
 
@@ -321,8 +317,7 @@
 	*attrs = outp->coda_create.attr;
 	*newfid = outp->coda_create.VFid;
 
-	if (inp) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;        
 }
 
@@ -344,8 +339,7 @@
 	*((char *)inp + offset + length) = '\0';
         
         error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
-	if ( inp ) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;
 }
 
@@ -366,8 +360,7 @@
 	*((char *)inp + offset + length) = '\0';
         
         error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
-	if ( inp ) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;
 }
 
@@ -397,7 +390,7 @@
 		*(buffer + retlen) = '\0';
 	}
         
-        if (inp) CODA_FREE(inp, insize);
+        CODA_FREE(inp, insize);
         CDEBUG(D_INODE, " result %d\n",error);
         EXIT;
         return error;
@@ -427,8 +420,7 @@
         
         error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
 
-        if (inp) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
         CDEBUG(D_INODE, " result %d\n",error);
         EXIT;
         return error;
@@ -465,8 +457,7 @@
 
 	error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
 
-        if (inp) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
         CDEBUG(D_INODE, " result %d\n",error);
         EXIT;
         return error;
@@ -485,8 +476,7 @@
         error = coda_upcall(coda_sbp(sb), sizeof(union inputArgs), 
                             &outsize, inp);
 
-	if ( inp ) 
-		CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;
 }
 
@@ -504,7 +494,7 @@
 
 	error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
 
-	if (inp) CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
         EXIT;
 	return error;
 }
@@ -575,8 +565,7 @@
         }
 
  exit:
-        if (inp) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;
 }
 
@@ -601,7 +590,7 @@
 		printk("coda_statfs: Venus returns: %d\n", error);
 	}
 
-        if (inp) CODA_FREE(inp, insize);
+        CODA_FREE(inp, insize);
         CDEBUG(D_INODE, " result %d\n",error);
         EXIT;
         return error;
@@ -614,7 +603,7 @@
 
 static inline unsigned long coda_waitfor_upcall(struct upc_req *vmp)
 {
-	struct wait_queue	wait = { current, NULL };
+	struct wait_queue wait = { current, NULL };
 	struct timeval begin = { 0, 0 }, end = { 0, 0 };
 
 	vmp->uc_posttime = jiffies;
@@ -624,16 +613,20 @@
 
 	add_wait_queue(&vmp->uc_sleep, &wait);
 	for (;;) {
-		if ( coda_hard == 0 ) 
+		if ( !coda_hard && vmp->uc_opcode != CODA_CLOSE ) 
 			current->state = TASK_INTERRUPTIBLE;
 		else
 			current->state = TASK_UNINTERRUPTIBLE;
 
+		/* venus died */
+		if ( !coda_upc_comm.vc_inuse )
+			break;
+
 		/* got a reply */
-		if ( vmp->uc_flags & REQ_WRITE )
+		if ( vmp->uc_flags & (REQ_WRITE | REQ_ABORT) )
 			break;
 
-		if ( !coda_hard && signal_pending(current) ) {
+		if ( !coda_hard && vmp->uc_opcode != CODA_CLOSE && signal_pending(current) ) {
 			/* if this process really wants to die, let it go */
 			if ( sigismember(&(current->signal), SIGKILL) ||
 			     sigismember(&(current->signal), SIGINT) )
@@ -644,7 +637,6 @@
 				break; 
 		}
 		schedule();
-
 	}
 	remove_wait_queue(&vmp->uc_sleep, &wait);
 	current->state = TASK_RUNNING;
@@ -689,7 +681,7 @@
 ENTRY;
 
 	vcommp = &coda_upc_comm;
-	if ( !vcommp->vc_pid ) {
+	if ( !vcommp->vc_inuse ) {
 		printk("No pseudo device in upcall comms at %p\n", vcommp);
                 return -ENXIO;
 	}
@@ -733,17 +725,12 @@
 	CDEBUG(D_UPCALL, 
 	       "..process %d woken up by Venus for req at %p, data at %p\n", 
 	       current->pid, req, req->uc_data);
-	if (vcommp->vc_pid) {      /* i.e. Venus is still alive */
+	if (vcommp->vc_inuse) {      /* i.e. Venus is still alive */
 	    /* Op went through, interrupt or not... */
 	    if (req->uc_flags & REQ_WRITE) {
 		out = (union outputArgs *)req->uc_data;
 		/* here we map positive Venus errors to kernel errors */
-		if ( out->oh.result < 0 ) {
-			printk("Tell Peter: Venus returns negative error %ld, for oc %ld!\n",
-			       out->oh.result, out->oh.opcode);
-			out->oh.result = EINTR;
-		}
-		error = -out->oh.result;
+		error = -(int)out->oh.result;
 		CDEBUG(D_UPCALL, 
 		       "upcall: (u,o,r) (%ld, %ld, %ld) out at %p\n", 
 		       out->oh.unique, out->oh.opcode, out->oh.result, out);
@@ -847,7 +834,7 @@
 
 	/* Handle invalidation requests. */
           if ( !sb || !sb->s_root || !sb->s_root->d_inode) { 
-	          printk("coda_downcall: opcode %d, no sb!\n", opcode);
+	          CDEBUG(D_DOWNCALL, "coda_downcall: opcode %d, no sb!\n", opcode);
 		  return 0; 
 	  }
 
diff -urN linux-2.2.17-pre15/include/asm-ppc/pmu.h linux/include/asm-ppc/pmu.h
--- linux-2.2.17-pre15/include/asm-ppc/pmu.h	Mon Dec  3 22:10:45 2001
+++ linux/include/asm-ppc/pmu.h	Mon Dec  3 22:10:51 2001
@@ -26,9 +26,11 @@
 #define PMU_INT_ACK		0x78	/* read interrupt bits */
 #define PMU_SHUTDOWN		0x7e	/* turn power off */
 #define PMU_SLEEP		0x7f	/* put CPU to sleep */
+#define PMU_POWER_EVENTS	0x8f	/* Send power-event commands to PMU */
 #define PMU_RESET		0xd0	/* reset CPU */
 #define PMU_GET_BRIGHTBUTTON	0xd9	/* report brightness up/down pos */
 #define PMU_GET_COVER		0xdc	/* report cover open/closed */
+#define PMU_SYSTEM_READY	0xdf	/* tell PMU we are awake */
 
 /* Bits to use with the PMU_POWER_CTRL command */
 #define PMU_POW_ON		0x80	/* OR this to power ON the device */
@@ -54,6 +56,25 @@
 	PMU_KEYLARGO_BASED,	/* Core99 motherboard (PMU99) */
 };
 
+/* PMU PMU_POWER_EVENTS commands */
+enum {
+	PMU_PWR_GET_POWERUP_EVENTS	= 0x00,
+	PMU_PWR_SET_POWERUP_EVENTS	= 0x01,
+	PMU_PWR_CLR_POWERUP_EVENTS	= 0x02,
+	PMU_PWR_GET_WAKEUP_EVENTS	= 0x03,
+	PMU_PWR_SET_WAKEUP_EVENTS	= 0x04,
+	PMU_PWR_CLR_WAKEUP_EVENTS	= 0x05,
+};
+
+/* Power events wakeup bits */
+enum {
+	PMU_PWR_WAKEUP_KEY		= 0x01,	/* Wake on key press */
+	PMU_PWR_WAKEUP_AC_INSERT	= 0x02, /* Wake on AC adapter plug */
+	PMU_PWR_WAKEUP_AC_CHANGE	= 0x04,
+	PMU_PWR_WAKEUP_LID_OPEN		= 0x08,
+	PMU_PWR_WAKEUP_RING		= 0x10,
+};
+	
 /*
  * Ioctl commands for the /dev/pmu device
  */
@@ -65,7 +86,7 @@
 #define PMU_IOC_GET_BACKLIGHT	_IOR('B', 1, sizeof(__u32*))
 /* in param: u32	backlight value: 0 to 31 */
 #define PMU_IOC_SET_BACKLIGHT	_IOW('B', 2, sizeof(__u32))
-/* out param: u32*	backlight value: 0 to 31 */
+/* out param: u32*	PMU model */
 #define PMU_IOC_GET_MODEL	_IOR('B', 3, sizeof(__u32*))
 /* out param: u32*	has_adb: 0 or 1 */
 #define PMU_IOC_HAS_ADB		_IOR('B', 4, sizeof(__u32*)) 
diff -urN linux-2.2.17-pre15/include/asm-ppc/posix_types.h linux/include/asm-ppc/posix_types.h
--- linux-2.2.17-pre15/include/asm-ppc/posix_types.h	Thu Apr 29 12:39:01 1999
+++ linux/include/asm-ppc/posix_types.h	Mon Dec  3 22:10:51 2001
@@ -15,7 +15,7 @@
 typedef int		__kernel_pid_t;
 typedef unsigned int	__kernel_uid_t;
 typedef unsigned int	__kernel_gid_t;
-typedef unsigned long	__kernel_size_t;
+typedef unsigned int	__kernel_size_t;
 typedef long		__kernel_ssize_t;
 typedef long		__kernel_ptrdiff_t;
 typedef long		__kernel_time_t;
diff -urN linux-2.2.17-pre15/include/linux/coda_cache.h linux/include/linux/coda_cache.h
--- linux-2.2.17-pre15/include/linux/coda_cache.h	Fri Dec 18 12:45:00 1998
+++ linux/include/linux/coda_cache.h	Mon Dec  3 22:10:51 2001
@@ -32,46 +32,4 @@
 void coda_flag_inode(struct inode *inode, int flag);
 void coda_flag_inode_children(struct inode *inode, int flag);
 
-
-/*
- * Structure to contain statistics on the cache usage
- */
-
-struct cfsnc_statistics {
-	unsigned	hits;
-	unsigned	misses;
-	unsigned	enters;
-	unsigned	dbl_enters;
-	unsigned	long_name_enters;
-	unsigned	long_name_lookups;
-	unsigned	long_remove;
-	unsigned	lru_rm;
-	unsigned	zapPfids;
-	unsigned	zapFids;
-	unsigned	zapFile;
-	unsigned	zapUsers;
-	unsigned	Flushes;
-	unsigned        Sum_bucket_len;
-	unsigned        Sum2_bucket_len;
-	unsigned        Max_bucket_len;
-	unsigned        Num_zero_len;
-	unsigned        Search_len;
-};
-
-
-#define CFSNC_FIND		((u_long) 1)
-#define CFSNC_REMOVE		((u_long) 2)
-#define CFSNC_INIT		((u_long) 3)
-#define CFSNC_ENTER		((u_long) 4)
-#define CFSNC_LOOKUP		((u_long) 5)
-#define CFSNC_ZAPPFID		((u_long) 6)
-#define CFSNC_ZAPFID		((u_long) 7)
-#define CFSNC_ZAPVNODE		((u_long) 8)
-#define CFSNC_ZAPFILE		((u_long) 9)
-#define CFSNC_PURGEUSER	((u_long) 10)
-#define CFSNC_FLUSH		((u_long) 11)
-#define CFSNC_PRINTCFSNC	((u_long) 12)
-#define CFSNC_PRINTSTATS	((u_long) 13)
-#define CFSNC_REPLACE		((u_long) 14)
-
 #endif _CFSNC_HEADER_
diff -urN linux-2.2.17-pre15/include/linux/coda_fs_i.h linux/include/linux/coda_fs_i.h
--- linux-2.2.17-pre15/include/linux/coda_fs_i.h	Mon Aug  9 12:05:10 1999
+++ linux/include/linux/coda_fs_i.h	Mon Dec  3 22:10:51 2001
@@ -29,23 +29,18 @@
 
         struct ViceFid     c_fid;	/* Coda identifier */
         u_short	           c_flags;     /* flags (see below) */
-        u_short	           c_ocount;    /* count of openers */
-        u_short            c_owrite;    /* count of open for write */
-        u_short            c_mmcount;   /* count of mmappers */
         struct inode      *c_ovp;       /* open inode  pointer */
         struct list_head   c_cnhead;    /* head of cache entries */
 	struct list_head   c_volrootlist; /* list of volroot cnoddes */
         struct inode      *c_vnode;     /*  inode associated with cnode */
+	unsigned int	   c_contcount; /* refcount for container inode */
         int                c_magic;     /* to verify the data structure */
 };
 
 /* flags */
 #define C_VATTR       0x1   /* Validity of vattr in inode */
-#define C_PURGE       0x8
-#define C_ZAPDIR      0x10
-#define C_DYING       0x4   /* from venus (which died) */
-#define C_INITED      0x20
 #define C_FLUSH       0x2   /* used after a flush */
+#define C_PURGE       0x8
 
 int coda_cnode_make(struct inode **, struct ViceFid *, struct super_block *);
 int coda_cnode_makectl(struct inode **inode, struct super_block *sb);
diff -urN linux-2.2.17-pre15/include/linux/coda_linux.h linux/include/linux/coda_linux.h
--- linux-2.2.17-pre15/include/linux/coda_linux.h	Mon Aug  9 12:05:10 1999
+++ linux/include/linux/coda_linux.h	Mon Dec  3 22:10:51 2001
@@ -53,7 +53,6 @@
 int coda_iscontrol(const char *name, size_t length);
 
 void coda_load_creds(struct coda_cred *cred);
-int coda_mycred(struct coda_cred *);
 void coda_vattr_to_iattr(struct inode *, struct coda_vattr *);
 void coda_iattr_to_vattr(struct iattr *, struct coda_vattr *);
 unsigned short coda_flags_to_cflags(unsigned short);
@@ -69,8 +68,6 @@
 			   struct inode *open_inode, struct file *open_file);
 int coda_inode_grab(dev_t dev, ino_t ino, struct inode **ind);
 
-#define NB_SFS_SIZ 0x895440
-
 /* cache.c */
 void coda_purge_children(struct inode *, int);
 void coda_purge_dentries(struct inode *);
@@ -99,15 +96,13 @@
   if (coda_debug & mask) {                                        \
     printk("(%s,l. %d): ",  __FUNCTION__, __LINE__);              \
     printk(format, ## a); }                                       \
-} while (0) ;                            
+} while (0)
 
 #define ENTRY    \
     if(coda_print_entry) printk("Process %d entered %s\n",current->pid,__FUNCTION__)
 
 #define EXIT    \
     if(coda_print_entry) printk("Process %d leaving %s\n",current->pid,__FUNCTION__)
-
-#define CHECK_CNODE(c) do {  } while (0);
 
 #define CODA_ALLOC(ptr, cast, size)                                       \
 do {                                                                      \
diff -urN linux-2.2.17-pre15/include/linux/coda_opstats.h linux/include/linux/coda_opstats.h
--- linux-2.2.17-pre15/include/linux/coda_opstats.h	Mon Dec 22 09:26:12 1997
+++ linux/include/linux/coda_opstats.h	Wed Dec 31 16:00:00 1969
@@ -1,94 +0,0 @@
-
-/*
- * Operation statistics for Coda.
- * Copyright (C) 1997 Carnegie Mellon University
- * 
- * Carnegie Mellon University encourages users of this software
- * to contribute improvements to the Coda project. Contact Peter Braam
- * <coda@coda.cs.cmu.edu>.
- */
-
-
-
-#define CFS_MOUNT_STATS  0
-#define CFS_UMOUNT_STATS 1
-#define CFS_ROOT_STATS   2
-#define CFS_STATFS_STATS 3
-#define CFS_SYNC_STATS   4
-#define CFS_VGET_STATS   5
-#define CFS_VFSOPS_SIZE  6
-
-/* vnodeops:
- *            open: all to venus
- *            close: all to venus
- *            rdrw: bogus.  Maybe redirected to UFS.
- *                          May call open/close for internal opens/closes
- *                          (Does exec not call open?)
- *            ioctl: causes a lookupname
- *                   passes through
- *            select: can't get there from here.
- *            getattr: can be satsified by cache
- *            setattr: all go through
- *            access: can be satisfied by cache
- *            readlink: can be satisfied by cache
- *            fsync: passes through
- *            inactive: passes through
- *            lookup: can be satisfied by cache
- *            create: passes through
- *            remove: passes through
- *            link: passes through
- *            rename: passes through
- *            mkdir: passes through
- *            rmdir: passes through
- *            symlink: passes through
- *            readdir: may be redirected to UFS
- *                     may cause an "internal" open/close
- */
-
-#define CFS_OPEN_STATS     0
-#define CFS_CLOSE_STATS    1
-#define CFS_RDWR_STATS     2
-#define CFS_IOCTL_STATS    3
-#define CFS_SELECT_STATS   4
-#define CFS_GETATTR_STATS  5
-#define CFS_SETATTR_STATS  6
-#define CFS_ACCESS_STATS   7
-#define CFS_READLINK_STATS 8
-#define CFS_FSYNC_STATS    9
-#define CFS_INACTIVE_STATS 10
-#define CFS_LOOKUP_STATS   11
-#define CFS_CREATE_STATS   12
-#define CFS_REMOVE_STATS   13
-#define CFS_LINK_STATS     14
-#define CFS_RENAME_STATS   15
-#define CFS_MKDIR_STATS    16
-#define CFS_RMDIR_STATS    17
-#define CFS_SYMLINK_STATS  18
-#define CFS_READDIR_STATS  19
-#define CFS_VNODEOPS_SIZE  20
-
-
-/*
- * I propose the following structres:
- */
-
-
-struct cfs_op_stats {
-    int opcode;       /* vfs opcode */
-    long entries;     /* number of times call attempted */
-    long sat_intrn;   /* number of times call satisfied by cache */
-    long unsat_intrn; /* number of times call failed in cache, but
-                         was not bounced to venus proper. */
-    long gen_intrn;   /* number of times call generated internally */
-                      /* (do we need that?) */
-};
-
-
-/*
- * With each call to the minicache, we'll bump the counters whenver
- * a call is satisfied internally (through the cache or through a
- * redirect), and whenever an operation is caused internally.
- * Then, we can add the total operations caught by the minicache
- * to the world-wide totals, and leave a caveat for the specific
- * graphs later.
- */
diff -urN linux-2.2.17-pre15/include/linux/coda_psdev.h linux/include/linux/coda_psdev.h
--- linux-2.2.17-pre15/include/linux/coda_psdev.h	Mon Aug  9 12:04:41 1999
+++ linux/include/linux/coda_psdev.h	Mon Dec  3 22:10:51 2001
@@ -11,9 +11,8 @@
 struct coda_sb_info
 {
 	struct inode *      sbi_psdev;     /* /dev/cfs? Venus/kernel device */
-	struct inode *      sbi_ctlcp;     /* control magic file */
 	int                 sbi_refct;
-	struct venus_comm *      sbi_vcomm;
+	struct venus_comm * sbi_vcomm;
 	struct inode *      sbi_root;
 	struct super_block *sbi_sb;
 	struct list_head    sbi_cchead;
@@ -27,7 +26,6 @@
 	struct list_head    vc_pending;
 	struct list_head    vc_processing;
 	int                 vc_inuse;
-	pid_t               vc_pid;   /* Venus pid */
 };
 
 
@@ -101,6 +99,7 @@
 #define REQ_ASYNC  0x1
 #define REQ_READ   0x2
 #define REQ_WRITE  0x4
+#define REQ_ABORT  0x8
 
 
 /*
diff -urN linux-2.2.17-pre15/include/linux/pci.h linux/include/linux/pci.h
--- linux-2.2.17-pre15/include/linux/pci.h	Mon Dec  3 22:10:45 2001
+++ linux/include/linux/pci.h	Mon Dec  3 22:10:51 2001
@@ -327,17 +327,17 @@
 #define PCI_DEVICE_ID_ATI_215GT		0x4754
 #define PCI_DEVICE_ID_ATI_215GTB	0x4755
 #define PCI_DEVICE_ID_ATI_210888GX	0x4758
+#define PCI_DEVICE_ID_ATI_RAGE128_LE	0x4c45
+#define PCI_DEVICE_ID_ATI_RAGE128_LF	0x4c46
 #define PCI_DEVICE_ID_ATI_215LG		0x4c47
 #define PCI_DEVICE_ID_ATI_264LT		0x4c54
-#define PCI_DEVICE_ID_ATI_264VT		0x5654
+#define PCI_DEVICE_ID_ATI_RAGE128_PF	0x5046
+#define PCI_DEVICE_ID_ATI_RAGE128_PR	0x5052
 #define PCI_DEVICE_ID_ATI_RAGE128_RE	0x5245
 #define PCI_DEVICE_ID_ATI_RAGE128_RF	0x5246
 #define PCI_DEVICE_ID_ATI_RAGE128_RK	0x524b
 #define PCI_DEVICE_ID_ATI_RAGE128_RL	0x524c
-#define PCI_DEVICE_ID_ATI_RAGE128_PF	0x5046
-#define PCI_DEVICE_ID_ATI_RAGE128_PR	0x5052
-#define PCI_DEVICE_ID_ATI_RAGE128_LE	0x4c45
-#define PCI_DEVICE_ID_ATI_RAGE128_LF	0x4c46
+#define PCI_DEVICE_ID_ATI_264VT		0x5654
 
 #define PCI_VENDOR_ID_VLSI		0x1004
 #define PCI_DEVICE_ID_VLSI_82C592	0x0005
@@ -568,10 +568,12 @@
 #define PCI_DEVICE_ID_PICOP_PT80C524	0x8002
 
 #define PCI_VENDOR_ID_MYLEX		0x1069
-#define PCI_DEVICE_ID_MYLEX_DAC960P_V2	0x0001
-#define PCI_DEVICE_ID_MYLEX_DAC960P_V3	0x0002
-#define PCI_DEVICE_ID_MYLEX_DAC960P_V4	0x0010
-#define PCI_DEVICE_ID_MYLEX_DAC960P_V5	0x0020
+#define PCI_DEVICE_ID_MYLEX_DAC960_P	0x0001
+#define PCI_DEVICE_ID_MYLEX_DAC960_PD	0x0002
+#define PCI_DEVICE_ID_MYLEX_DAC960_PG	0x0010
+#define PCI_DEVICE_ID_MYLEX_DAC960_LA	0x0020
+#define PCI_DEVICE_ID_MYLEX_DAC960_LP	0x0050
+#define PCI_DEVICE_ID_MYLEX_DAC960_BA	0xBA56
 
 #define PCI_VENDOR_ID_APPLE		0x106b
 #define PCI_DEVICE_ID_APPLE_BANDIT	0x0001
@@ -1120,6 +1122,7 @@
 #define PCI_DEVICE_ID_INTEL_82430	0x0486
 #define PCI_DEVICE_ID_INTEL_82434	0x04a3
 #define PCI_DEVICE_ID_INTEL_I960	0x0960
+#define PCI_DEVICE_ID_INTEL_I960RN	0x0964
 #define PCI_DEVICE_ID_INTEL_82559ER	0x1209
 #define PCI_DEVICE_ID_INTEL_82092AA_0	0x1221
 #define PCI_DEVICE_ID_INTEL_82092AA_1	0x1222
diff -urN linux-2.2.17-pre15/mm/filemap.c linux/mm/filemap.c
--- linux-2.2.17-pre15/mm/filemap.c	Mon Dec  3 22:10:45 2001
+++ linux/mm/filemap.c	Mon Dec  3 22:10:51 2001
@@ -179,8 +179,6 @@
 		if ((gfp_mask & __GFP_DMA) && !PageDMA(page))
 			continue;
 
-		count--;
-
 		/*
 		 * Is it a page swap page? If so, we want to
 		 * drop it if it is no longer used, even if it
@@ -226,7 +224,7 @@
 			return 1;
 		}
 
-	} while (count > 0);
+	} while (--count > 0);
 	return 0;
 }
 
diff -urN linux-2.2.17-pre15/net/core/sock.c linux/net/core/sock.c
--- linux-2.2.17-pre15/net/core/sock.c	Mon Dec  3 22:10:45 2001
+++ linux/net/core/sock.c	Mon Dec  3 22:10:51 2001
@@ -568,7 +568,9 @@
 			skb->sk = sk;
 			return skb;
 		}
+#ifdef CONFIG_INET
 		net_statistics.SockMallocOOM++; 
+#endif
 	}
 	return NULL;
 }
@@ -592,7 +594,9 @@
 			skb->sk = sk;
 			return skb;
 		}
+#ifdef CONFIG_INET
 		net_statistics.SockMallocOOM++; 
+#endif
 	}
 	return NULL;
 }
@@ -610,7 +614,9 @@
 			skb->sk = sk;
 			return skb;
 		}
-		net_statistics.SockMallocOOM++; 
+#ifdef CONFIG_INET
+		net_statistics.SockMallocOOM++;
+#endif 
 	}
 	return NULL;
 }
@@ -630,7 +636,9 @@
 		if (mem)
 			return mem;
 		atomic_sub(size, &sk->omem_alloc);
+#ifdef CONFIG_INET
 		net_statistics.SockMallocOOM++; 
+#endif
 	}
 	return NULL;
 }
diff -urN linux-2.2.17-pre15/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- linux-2.2.17-pre15/net/ipv4/tcp.c	Mon Dec  3 22:10:45 2001
+++ linux/net/ipv4/tcp.c	Mon Dec  3 22:10:51 2001
@@ -703,12 +703,12 @@
  */
 static void wait_for_tcp_memory(struct sock * sk, int err)
 {
-	release_sock(sk);
-	if (!tcp_memory_free(sk)) {
+	if (1) { 
 		struct wait_queue wait = { current, NULL };
-
+	
 		sk->socket->flags &= ~SO_NOSPACE;
 		add_wait_queue(sk->sleep, &wait);
+		release_sock(sk);
 		for (;;) {
 			if (signal_pending(current))
 				break;
@@ -722,14 +722,14 @@
 			if (!err) 
 				schedule();
 			else {
-				schedule_timeout(1); 
+				schedule_timeout(net_random()%(HZ/5) + 1); 
 				break;
 			} 	
 		}
+		lock_sock(sk);
 		current->state = TASK_RUNNING;
 		remove_wait_queue(sk->sleep, &wait);
 	}
-	lock_sock(sk);
 }
 
 /*
@@ -927,7 +927,7 @@
 			/* If we didn't get any memory, we need to sleep. */
 			if (skb == NULL) {
 				sk->socket->flags |= SO_NOSPACE;
-				if (flags&MSG_DONTWAIT) {
+				if ((flags&MSG_DONTWAIT) && !err) {
 					err = -EAGAIN;
 					goto do_interrupted;
 				}
@@ -935,6 +935,7 @@
 					err = -ERESTARTSYS;
 					goto do_interrupted;
 				}
+
 				/* In OOM that would fail anyways so do not bother. */ 
 				if (!err) 
 					tcp_push_pending_frames(sk, tp);
diff -urN linux-2.2.17-pre15/net/irda/af_irda.c linux/net/irda/af_irda.c
--- linux-2.2.17-pre15/net/irda/af_irda.c	Wed Jun  7 14:26:44 2000
+++ linux/net/irda/af_irda.c	Mon Dec  3 22:10:51 2001
@@ -1073,7 +1073,8 @@
 
         sock->sk   = NULL;      
         sk->socket = NULL;      /* Not used, but we should do this. */
-
+	sk->protinfo.irda = NULL;
+	sock_put(sk);
         return 0;
 }
 
