## Automatically generated incremental diff
## From:   linux-2.0.39-pre7
## To:     linux-2.0.39-pre8
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $

diff -urN linux-2.0.39-pre7/CREDITS linux-2.0.39-pre8/CREDITS
--- linux-2.0.39-pre7/CREDITS	2003-08-15 15:05:04.000000000 -0700
+++ linux-2.0.39-pre8/CREDITS	2003-08-15 15:05:04.000000000 -0700
@@ -1543,7 +1543,6 @@
 N: David Weinehall
 E: tao@acc.umu.se
 W: http://www.acc.umu.se/~tao/
-W: http://www.acc.umu.se/~mcalinux/
 D: Miscellaneous fixes
 D: Cleanup of the Config-files
 S: Axtorpsvagen 40:20
diff -urN linux-2.0.39-pre7/drivers/block/ide.c linux-2.0.39-pre8/drivers/block/ide.c
--- linux-2.0.39-pre7/drivers/block/ide.c	2003-08-15 15:05:04.000000000 -0700
+++ linux-2.0.39-pre8/drivers/block/ide.c	2003-08-15 15:05:04.000000000 -0700
@@ -3422,7 +3422,19 @@
 
 	printk("%s ", msg);
 
-#endif
+	if (xparm < 0 && (drive->bios_cyl * drive->bios_head * drive->bios_sect) < (1024 * 16 * 63)) {
+		return 0;		/* small disk: no translation needed */
+	}
+
+	if (drive->id) {
+		drive->cyl  = drive->id->cyls;
+		drive->head = drive->id->heads;
+		drive->sect = drive->id->sectors;
+	}
+	drive->bios_cyl  = drive->cyl;
+	drive->bios_head = drive->head;
+	drive->bios_sect = drive->sect;
+	drive->special.b.set_geometry = 1;
 
 	tracks = drive->bios_cyl * drive->bios_head * drive->bios_sect / 63;
 	drive->bios_sect = 63;
@@ -3430,18 +3442,24 @@
 		drive->bios_head = xparm;
 		drive->bios_cyl = tracks / drive->bios_head;
 	} else {
-		heads = (xparm == -1) ? ez_head_vals : dm_head_vals;
 		while (drive->bios_cyl >= 1024) {
 			drive->bios_head = *heads;
 			drive->bios_cyl = tracks / drive->bios_head;
 			if (0 == *++heads)
 				break;
 		}
+#if FAKE_FDISK_FOR_EZDRIVE
+		if (xparm == -1) {
+			drive->remap_0_to_1 = 1;
+			msg = "0->1";
+		} else
+#endif /* FAKE_FDISK_FOR_EZDRIVE */
 		if (xparm == 1) {
 			drive->sect0 = 63;
 			drive->bios_cyl = (tracks - 1) / drive->bios_head;
-			printk("[remap +63] ");
+			msg = "+63";
 		}
+		printk("[remap %s] ", msg);
 	}
 	drive->part[0].nr_sects = current_capacity(drive);
 	printk("[%d/%d/%d]", drive->bios_cyl, drive->bios_head, drive->bios_sect);
diff -urN linux-2.0.39-pre7/drivers/block/xd.c linux-2.0.39-pre8/drivers/block/xd.c
--- linux-2.0.39-pre7/drivers/block/xd.c	1998-06-03 15:17:47.000000000 -0700
+++ linux-2.0.39-pre8/drivers/block/xd.c	2003-08-15 15:05:04.000000000 -0700
@@ -163,8 +163,6 @@
 static u_short xd_iobase = 0x320;
 static int xd_geo[XD_MAXDRIVES*3] = { 0,0,0,0,0,0 };
 
-static int xd[5];
-
 static volatile int xdc_busy = 0;
 static struct wait_queue *xdc_wait = NULL;
 
diff -urN linux-2.0.39-pre7/drivers/cdrom/Config.in linux-2.0.39-pre8/drivers/cdrom/Config.in
--- linux-2.0.39-pre7/drivers/cdrom/Config.in	2003-08-15 15:05:04.000000000 -0700
+++ linux-2.0.39-pre8/drivers/cdrom/Config.in	2003-08-15 15:05:04.000000000 -0700
@@ -1,26 +1,26 @@
 #
 # CDROM driver configuration
 #
-tristate 'Aztech/Orchid/Okano/Wearnes/TXC/CyDROM  CDROM support' CONFIG_AZTCD
-tristate 'Goldstar R420 CDROM support' CONFIG_GSCD
-tristate 'Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support' CONFIG_SBPCD
+tristate '  Aztech/Orchid/Okano/Wearnes/TXC/CyDROM  CDROM support' CONFIG_AZTCD
+tristate '  Goldstar R420 CDROM support' CONFIG_GSCD
+tristate '  Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support' CONFIG_SBPCD
 if [ "$CONFIG_SBPCD" = "y" ]; then
-   bool '  Matsushita/Panasonic, ... second CDROM controller support' CONFIG_SBPCD2
+   bool '    Matsushita/Panasonic, ... second CDROM controller support' CONFIG_SBPCD2
    if [ "$CONFIG_SBPCD2" = "y" ]; then
-      bool '    Matsushita/Panasonic, ... third CDROM controller support' CONFIG_SBPCD3
+      bool '      Matsushita/Panasonic, ... third CDROM controller support' CONFIG_SBPCD3
       if [ "$CONFIG_SBPCD3" = "y" ]; then
-	 bool '      Matsushita/Panasonic, ... fourth CDROM controller support' CONFIG_SBPCD4
+	 bool '        Matsushita/Panasonic, ... fourth CDROM controller support' CONFIG_SBPCD4
       fi
    fi
 fi
-tristate 'Mitsumi (standard) [no XA/Multisession] CDROM support' CONFIG_MCD
-tristate 'Mitsumi [XA/MultiSession] CDROM support' CONFIG_MCDX
-tristate 'Optics Storage DOLPHIN 8000AT CDROM support' CONFIG_OPTCD
-tristate 'Philips/LMS CM206 CDROM support' CONFIG_CM206
-tristate 'Sanyo CDR-H94A CDROM support' CONFIG_SJCD
-bool 'Soft configurable cdrom interface card support' CONFIG_CDI_INIT
+tristate '  Mitsumi (standard) [no XA/Multisession] CDROM support' CONFIG_MCD
+tristate '  Mitsumi [XA/MultiSession] CDROM support' CONFIG_MCDX
+tristate '  Optics Storage DOLPHIN 8000AT CDROM support' CONFIG_OPTCD
+tristate '  Philips/LMS CM206 CDROM support' CONFIG_CM206
+tristate '  Sanyo CDR-H94A CDROM support' CONFIG_SJCD
+bool '  Soft configurable cdrom interface card support' CONFIG_CDI_INIT
 if [ "$CONFIG_CDI_INIT" = "y" ]; then
-   tristate '  ISP16/MAD16/Mozart soft configurable cdrom interface support' CONFIG_ISP16_CDI
+   tristate '    ISP16/MAD16/Mozart soft configurable cdrom interface support' CONFIG_ISP16_CDI
 fi
-tristate 'Sony CDU31A/CDU33A CDROM support' CONFIG_CDU31A
-tristate 'Sony CDU535 CDROM support' CONFIG_CDU535
+tristate '  Sony CDU31A/CDU33A CDROM support' CONFIG_CDU31A
+tristate '  Sony CDU535 CDROM support' CONFIG_CDU535
diff -urN linux-2.0.39-pre7/drivers/net/pi2.c linux-2.0.39-pre8/drivers/net/pi2.c
--- linux-2.0.39-pre7/drivers/net/pi2.c	1999-06-13 10:21:01.000000000 -0700
+++ linux-2.0.39-pre8/drivers/net/pi2.c	2003-08-15 15:05:04.000000000 -0700
@@ -1199,7 +1199,7 @@
 }
 
 
-int pi_init(void)
+int pi2_init(void)
 {
     int *port;
     int ioaddr = 0;
@@ -1689,7 +1689,7 @@
 int init_module(void)
 {
     register_symtab(NULL);
-    return pi_init();
+    return pi2_init();
 }
 
 void cleanup_module(void)
diff -urN linux-2.0.39-pre7/drivers/net/pt.c linux-2.0.39-pre8/drivers/net/pt.c
--- linux-2.0.39-pre7/drivers/net/pt.c	1999-06-13 10:21:01.000000000 -0700
+++ linux-2.0.39-pre8/drivers/net/pt.c	2003-08-15 15:05:04.000000000 -0700
@@ -494,7 +494,7 @@
 	
 	
 
-int pt_init(void)
+int ptwin_init(void)
 {
     int *port;
     int ioaddr = 0;
@@ -551,7 +551,7 @@
     pt0b.irq = pt0a.irq;	/* IRQ is shared */
     
     return 0;
-} /* pt_init() */
+} /* ptwin_init() */
 
 /*
  * Probe for PT card.  Also initialises the timers
@@ -1785,7 +1785,7 @@
 int init_module(void)
 {
     register_symtab(NULL);
-    return pt_init();
+    return ptwin_init();
 }
 
 void cleanup_module(void)
diff -urN linux-2.0.39-pre7/drivers/scsi/Config.in linux-2.0.39-pre8/drivers/scsi/Config.in
--- linux-2.0.39-pre7/drivers/scsi/Config.in	2003-08-15 15:05:04.000000000 -0700
+++ linux-2.0.39-pre8/drivers/scsi/Config.in	2003-08-15 15:05:04.000000000 -0700
@@ -85,8 +85,8 @@
 fi
 dep_tristate 'PAS16 SCSI support' CONFIG_SCSI_PAS16 $CONFIG_SCSI
 dep_tristate 'PCI-2000 support' CONFIG_SCSI_PCI2000 $CONFIG_SCSI
-dep_tristate 'PCI2220I support' CONFIG_SCSI_PCI2220I $CONFIG_SCSI
-dep_tristate 'PSI240I support' CONFIG_SCSI_PSI240I $CONFIG_SCSI
+dep_tristate 'PCI-2220i support' CONFIG_SCSI_PCI2220I $CONFIG_SCSI
+dep_tristate 'PSI-240i support' CONFIG_SCSI_PSI240I $CONFIG_SCSI
 dep_tristate 'Qlogic FAS SCSI support' CONFIG_SCSI_QLOGIC_FAS $CONFIG_SCSI
 if [ "$CONFIG_PCI" = "y" ]; then
    dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI
diff -urN linux-2.0.39-pre7/drivers/scsi/pci2000.c linux-2.0.39-pre8/drivers/scsi/pci2000.c
--- linux-2.0.39-pre7/drivers/scsi/pci2000.c	1999-06-13 10:21:02.000000000 -0700
+++ linux-2.0.39-pre8/drivers/scsi/pci2000.c	2003-08-15 15:05:04.000000000 -0700
@@ -1,7 +1,7 @@
 /*+M*************************************************************************
  * Perceptive Solutions, Inc. PCI-2000 device driver proc support for Linux.
  *
- * Copyright (c) 1997 Perceptive Solutions, Inc.
+ * Copyright (c) 1999 Perceptive Solutions, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,12 +21,15 @@
  *	File Name:		pci2000i.c
  *
  *	Revisions	1.10	Jan-21-1999
- *
  *		- Fixed sign on message to reflect proper controller name.
  *		- Added support for RAID status monitoring and control.
  *
+ *  Revisions	1.11	Mar-22-1999
+ *		- Fixed control timeout to not lock up the entire system if
+ *		  controller goes offline completely.
+ *
  *-M*************************************************************************/
-#define PCI2000_VERSION		"1.10"
+#define PCI2000_VERSION		"1.11"
 
 #include <linux/module.h>
 
@@ -108,13 +111,14 @@
  ****************************************************************/
 static int WaitReady (PADAPTER2000 padapter)
 	{
-	ULONG	timer;
+	ULONG	z;
 
-	timer = jiffies + TIMEOUT_COMMAND;								// calculate the timeout value
-	do	{
+	for ( z = 0;  z < (TIMEOUT_COMMAND * 4);  z++ )
+		{
 		if ( !inb_p (padapter->cmd) )
 			return FALSE;
-		}	while ( timer > jiffies );									// test for timeout
+		udelay (250);
+		};								
 	return TRUE;
 	}
 /****************************************************************
@@ -318,7 +322,7 @@
 	OpDone (SCpnt, DID_OK << 16);
 	}
 /****************************************************************
- *	Name:	Pci2220i_QueueCommand
+ *	Name:	Pci2000_QueueCommand
  *
  *	Description:	Process a queued command from the SCSI manager.
  *
@@ -507,7 +511,7 @@
 			if ( cmd )
 				break;
 		default:
-			DEB (printk ("pci2220i_queuecommand: Unsupported command %02X\n", *cdb));
+			DEB (printk ("pci2000_queuecommand: Unsupported command %02X\n", *cdb));
 			OpDone (SCpnt, DID_ERROR << 16);
 			return 0;
 		}
@@ -534,7 +538,7 @@
 	SCpnt->SCp.Status++;
 	}
 /****************************************************************
- *	Name:	Pci2220i_Command
+ *	Name:	Pci2000_Command
  *
  *	Description:	Process a command from the SCSI manager.
  *
@@ -555,7 +559,7 @@
 	return SCpnt->result;
 	}
 /****************************************************************
- *	Name:	Pci2220i_Detect
+ *	Name:	Pci2000_Detect
  *
  *	Description:	Detect and initialize our boards.
  *
@@ -638,7 +642,7 @@
 	return pci_index;
 	}
 /****************************************************************
- *	Name:	Pci2220i_Abort
+ *	Name:	Pci2000_Abort
  *
  *	Description:	Process the Abort command from the SCSI manager.
  *
@@ -653,7 +657,7 @@
 	return SCSI_ABORT_SNOOZE;
 	}
 /****************************************************************
- *	Name:	Pci2220i_Reset
+ *	Name:	Pci2000_Reset
  *
  *	Description:	Process the Reset command from the SCSI manager.
  *
@@ -675,7 +679,7 @@
 #include "sd.h"
 
 /****************************************************************
- *	Name:	Pci2220i_BiosParam
+ *	Name:	Pci2000_BiosParam
  *
  *	Description:	Process the biosparam request from the SCSI manager to
  *					return C/H/S data.
@@ -709,7 +713,7 @@
 
 #ifdef MODULE
 /* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = PCI2000;
+Scsi_Host_Template driver_template = PCI2220I;
 
 #include "scsi_module.c"
 #endif
diff -urN linux-2.0.39-pre7/drivers/scsi/pci2220i.c linux-2.0.39-pre8/drivers/scsi/pci2220i.c
--- linux-2.0.39-pre7/drivers/scsi/pci2220i.c	1999-06-13 10:21:02.000000000 -0700
+++ linux-2.0.39-pre8/drivers/scsi/pci2220i.c	2003-08-15 15:05:04.000000000 -0700
@@ -1,7 +1,7 @@
 /*+M*************************************************************************
- * Perceptive Solutions, Inc. PCI-2000 device driver proc support for Linux.
+ * Perceptive Solutions, Inc. PCI-2220I device driver proc support for Linux.
  *
- * Copyright (c) 1997 Perceptive Solutions, Inc.
+ * Copyright (c) 1999 Perceptive Solutions, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,7 +25,6 @@
  *-M*************************************************************************/
 
 #include <linux/module.h>
-
 #include <linux/kernel.h>
 #include <linux/head.h>
 #include <linux/types.h>
@@ -36,46 +35,41 @@
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
+#include <linux/stat.h>
+#include <linux/kdev_t.h>
+#include <linux/blk.h>
+#include <linux/timer.h>
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/io.h>
-#include <linux/blk.h>
 #include "scsi.h"
 #include "hosts.h"
-
 #include "pci2220i.h"
-#include "psi_dale.h"
 
-#include<linux/stat.h>
+#define	PCI2220I_VERSION		"1.10"
+//#define	READ_CMD				IDE_COMMAND_READ
+//#define	WRITE_CMD				IDE_COMMAND_WRITE
+//#define	MAX_BUS_MASTER_BLOCKS	1		// This is the maximum we can bus master
+#define	READ_CMD				IDE_CMD_READ_MULTIPLE
+#define	WRITE_CMD				IDE_CMD_WRITE_MULTIPLE
+#define	MAX_BUS_MASTER_BLOCKS	SECTORSXFER		// This is the maximum we can bus master
+
 
 struct proc_dir_entry Proc_Scsi_Pci2220i =
-	{ PROC_SCSI_PCI2220I, 7, "pci2220i", S_IFDIR | S_IRUGO | S_IXUGO, 2 };
+	{ PROC_SCSI_PCI2220I, 8, "pci2220i", S_IFDIR | S_IRUGO | S_IXUGO, 2 };
 
 //#define DEBUG 1
 
 #ifdef DEBUG
 #define DEB(x) x
-#define STOP_HERE	{int st;for(st=0;st<100;st++){st=1;}}
+#define STOP_HERE()	{int st;for(st=0;st<100;st++){st=1;}}
 #else
 #define DEB(x)
-#define STOP_HERE
+#define STOP_HERE()
 #endif
 
-#define MAXADAPTER 4	/* Increase this and the sizes of the arrays below, if you need more. */
-
-#define	MAX_BUS_MASTER_BLOCKS	1		// This is the maximum we can bus master for (1024 bytes)
+#define MAXADAPTER 4					// Increase this and the sizes of the arrays below, if you need more.
 
-#define	PORT_DATA				0
-#define	PORT_ERROR				1
-#define	PORT_SECTOR_COUNT		2
-#define	PORT_LBA_0				3
-#define	PORT_LBA_8				4
-#define	PORT_LBA_16				5
-#define	PORT_LBA_24				6
-#define	PORT_STAT_CMD			7
-#define	PORT_STAT_SEL			8
-#define	PORT_FAIL				9
-#define	PORT_ALT_STAT		   	10
 
 typedef struct
 	{
@@ -88,44 +82,245 @@
 	USHORT			cylinders;			// number of cylinders for this device
 	USHORT			spareword;			// placeholder
 	ULONG			blocks;				// number of blocks on device
-	}	OUR_DEVICE, *POUR_DEVICE;
+	DISK_MIRROR		DiskMirror[2];		// RAID status and control
+	ULONG			lastsectorlba[2];	// last addressable sector on the drive
+	USHORT			raid;				// RAID active flag
+	USHORT			mirrorRecon;
+	UCHAR			hotRecon;
+	USHORT			reconCount;
+	}	OUR_DEVICE, *POUR_DEVICE;	
 
 typedef struct
 	{
-	USHORT		 ports[12];
-	USHORT		 regDmaDesc;					// address of the DMA discriptor register for direction of transfer
-	USHORT		 regDmaCmdStat;					// Byte #1 of DMA command status register
-	USHORT		 regDmaAddrPci;					// 32 bit register for PCI address of DMA
-	USHORT		 regDmaAddrLoc;					// 32 bit register for local bus address of DMA
-	USHORT		 regDmaCount;					// 32 bit register for DMA transfer count
-	USHORT		 regDmaMode;						// 32 bit register for DMA mode control
-	USHORT		 regRemap;						// 32 bit local space remap
-	USHORT		 regDesc;						// 32 bit local region descriptor
-	USHORT		 regRange;						// 32 bit local range
-	USHORT		 regIrqControl;					// 16 bit Interrupt enable/disable and status
-	USHORT		 regScratchPad;					// scratch pad I/O base address
-	USHORT		 regBase;						// Base I/O register for data space
-	USHORT		 basePort;						// PLX base I/O port
-	USHORT		 timingMode;					// timing mode currently set for adapter
-	ULONG		 timingAddress;					// address to use on adapter for current timing mode
-	OUR_DEVICE	 device[4];
-	IDE_STRUCT	 ide;
+	USHORT		 regDmaDesc;			// address of the DMA discriptor register for direction of transfer
+	USHORT		 regDmaCmdStat;			// Byte #1 of DMA command status register
+	USHORT		 regDmaAddrPci;			// 32 bit register for PCI address of DMA
+	USHORT		 regDmaAddrLoc;			// 32 bit register for local bus address of DMA
+	USHORT		 regDmaCount;			// 32 bit register for DMA transfer count
+	USHORT		 regDmaMode;			// 32 bit register for DMA mode control
+	USHORT		 regRemap;				// 32 bit local space remap
+	USHORT		 regDesc;				// 32 bit local region descriptor
+	USHORT		 regRange;				// 32 bit local range
+	USHORT		 regIrqControl;			// 16 bit Interrupt enable/disable and status
+	USHORT		 regScratchPad;			// scratch pad I/O base address
+	USHORT		 regBase;				// Base I/O register for data space
+	USHORT		 regData;				// data register I/O address
+	USHORT		 regError;				// error register I/O address
+	USHORT		 regSectCount;			// sector count register I/O address
+	USHORT		 regLba0;				// least significant byte of LBA
+	USHORT		 regLba8;				// next least significant byte of LBA
+	USHORT		 regLba16;				// next most significan byte of LBA
+	USHORT		 regLba24;				// head and most 4 significant bits of LBA
+	USHORT		 regStatCmd;			// status on read and command on write register
+	USHORT		 regStatSel;			// board status on read and spigot select on write register
+	USHORT		 regFail;				// fail bits control register
+	USHORT		 regAltStat;			// alternate status and drive control register
+	USHORT		 basePort;				// PLX base I/O port
+	USHORT		 timingMode;			// timing mode currently set for adapter
+	USHORT		 timingPIO;				// TRUE if PIO timing is active
+	ULONG		 timingAddress;			// address to use on adapter for current timing mode
+	OUR_DEVICE	 device[DALE_MAXDRIVES];
+	DISK_MIRROR	*raidData[8];
 	ULONG		 startSector;
 	USHORT		 sectorCount;
+	UCHAR		 cmd;
 	Scsi_Cmnd	*SCpnt;
 	VOID		*buffer;
+	POUR_DEVICE	 pdev;					// current device opearating on
 	USHORT		 expectingIRQ;
-	USHORT		 readPhase;
+	USHORT		 reconIsStarting;		// indicate hot reconstruct is starting
+	USHORT		 reconOn;				// Hot reconstruct is to be done.
+	USHORT		 reconPhase;			// Hot reconstruct operation is in progress.
+	ULONG		 reconSize;
+	USHORT		 demoFail;				// flag for RAID failure demonstration
+	USHORT		 survivor;
+	USHORT		 failinprog;
+	USHORT		 timeoutReconRetry;
+	struct timer_list	reconTimer;	
+	struct timer_list	timer;
 	}	ADAPTER2220I, *PADAPTER2220I;
 
 #define HOSTDATA(host) ((PADAPTER2220I)&host->hostdata)
 
+#define	RECON_PHASE_READY		0x01
+#define	RECON_PHASE_COPY		0x02
+#define	RECON_PHASE_UPDATE		0x03
+#define	RECON_PHASE_LAST		0x04
+#define	RECON_PHASE_END			0x07	
+#define	RECON_PHASE_MARKING		0x80
+#define	RECON_PHASE_FAILOVER	0xFF
 
 static struct	Scsi_Host 	   *PsiHost[MAXADAPTER] = {NULL,};  // One for each adapter
 static			int				NumAdapters = 0;
-static			IDENTIFY_DATA	identifyData;
 static			SETUP			DaleSetup;
+static			DISK_MIRROR		DiskMirror[2];
+static			ULONG			ModeArray[] = {DALE_DATA_MODE2, DALE_DATA_MODE3, DALE_DATA_MODE4, DALE_DATA_MODE4P};
+static			UCHAR			Buffer[SECTORSXFER * BYTES_PER_SECTOR];
+
+static void ReconTimerExpiry (unsigned long data);
+
+/****************************************************************
+ *	Name:	MuteAlarm	:LOCAL
+ *
+ *	Description:	Mute the audible alarm.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static void MuteAlarm (PADAPTER2220I padapter)
+	{
+	UCHAR	old;
 
+	old = (inb_p (padapter->regStatSel) >> 3) | (inb_p (padapter->regStatSel) & 0x83);
+	outb_p (old | 0x40, padapter->regFail);
+	}
+/****************************************************************
+ *	Name:	WaitReady	:LOCAL
+ *
+ *	Description:	Wait for device ready.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static int WaitReady (PADAPTER2220I padapter)
+	{
+	ULONG	z;
+	UCHAR	status;
+
+	for ( z = 0;  z < (TIMEOUT_READY * 4);  z++ )
+		{
+		status = inb_p (padapter->regStatCmd);
+		if ( (status & (IDE_STATUS_DRDY | IDE_STATUS_BUSY)) == IDE_STATUS_DRDY )
+			return 0;
+		udelay (250);
+		}
+	return status;
+	}
+/****************************************************************
+ *	Name:	WaitReadyReset	:LOCAL
+ *
+ *	Description:	Wait for device ready.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static int WaitReadyReset (PADAPTER2220I padapter)
+	{
+	ULONG	z;
+	UCHAR	status;
+
+	for ( z = 0;  z < (250 * 4);  z++ )				// wait up to 1/4 second
+		{
+		status = inb_p (padapter->regStatCmd);
+		if ( (status & (IDE_STATUS_DRDY | IDE_STATUS_BUSY)) == IDE_STATUS_DRDY )
+			{
+			DEB (printk ("\nPCI2220I:  Reset took %ld mSec to be ready", z / 4));
+			return 0;
+			}
+		udelay (250);
+		}
+	DEB (printk ("\nPCI2220I:  Reset took more than 1 Second to come ready, Disk Failure"));
+	return status;
+	}
+/****************************************************************
+ *	Name:	WaitDrq	:LOCAL
+ *
+ *	Description:	Wait for device ready for data transfer.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static int WaitDrq (PADAPTER2220I padapter)
+	{
+	ULONG	z;
+	UCHAR	status;
+
+	for ( z = 0;  z < (TIMEOUT_DRQ * 4);  z++ )
+		{
+		status = inb_p (padapter->regStatCmd);
+		if ( status & IDE_STATUS_DRQ )
+			return 0;
+		udelay (250);
+		}
+	return status;
+	}
+/****************************************************************
+ *	Name:	HardReset	:LOCAL
+ *
+ *	Description:	Wait for device ready for data transfer.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *					pdev	 - Pointer to device.
+ *					spigot	 - Spigot number.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static int HardReset (PADAPTER2220I padapter, POUR_DEVICE pdev, UCHAR spigot)
+	{
+	SelectSpigot (padapter, spigot | 0x80);
+	
+	outb_p (0x0E, padapter->regAltStat);					// reset the suvivor
+	udelay (100);											// wait a little	
+	outb_p (0x08, padapter->regAltStat);					// clear the reset
+	udelay (100);
+	outb_p (0xA0, padapter->regLba24);						//Specify drive
+
+	outb_p (pdev->byte6, padapter->regLba24);				// select the drive
+	if ( WaitReadyReset (padapter) )
+		return TRUE;
+	outb_p (SECTORSXFER, padapter->regSectCount);
+	WriteCommand (padapter, IDE_CMD_SET_MULTIPLE);	
+	if ( WaitReady (padapter) )
+		return TRUE;
+	return FALSE;
+	}
+/****************************************************************
+ *	Name:	BusMaster	:LOCAL
+ *
+ *	Description:	Do a bus master I/O.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *					datain	 - TRUE if data read.
+ *					irq		 - TRUE if bus master interrupt expected.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static void BusMaster (PADAPTER2220I padapter, UCHAR datain, UCHAR irq)
+	{
+	ULONG zl;
+	
+	outl (padapter->timingAddress, padapter->regDmaAddrLoc);
+	outl (virt_to_bus (padapter->buffer), padapter->regDmaAddrPci);
+	zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
+	padapter->sectorCount -= zl;
+	zl *= (ULONG)BYTES_PER_SECTOR;
+	padapter->buffer += zl;
+	outl (zl, padapter->regDmaCount);
+	if ( datain )
+		{
+		outb_p (8, padapter->regDmaDesc);						// read operation
+		if ( irq && !padapter->sectorCount )
+			outb_p (5, padapter->regDmaMode);					// interrupt on
+		else
+			outb_p (1, padapter->regDmaMode);					// no interrupt
+		}
+	else
+		{
+		outb_p (0, padapter->regDmaDesc);						// write operation
+		outb_p (1, padapter->regDmaMode);						// no interrupt
+		}
+	outb_p (0x03, padapter->regDmaCmdStat);						// kick the DMA engine in gear
+	}
 /****************************************************************
  *	Name:	WriteData	:LOCAL
  *
@@ -138,114 +333,224 @@
  ****************************************************************/
 static int WriteData (PADAPTER2220I padapter)
 	{
-	ULONG	timer;
-	USHORT *pports = padapter->ports;
+	ULONG	zl;
+	
+	if ( !WaitDrq (padapter) )
+		{
+		if ( padapter->timingPIO )
+			{
+			zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
+			outsw (padapter->regData, padapter->buffer, zl * (BYTES_PER_SECTOR / 2));
+			padapter->sectorCount -= zl;
+			padapter->buffer += zl * BYTES_PER_SECTOR;
+			}
+		else
+			BusMaster (padapter, 0, 0);
+		return 0;
+		}
+	padapter->cmd = 0;												// null out the command byte
+	return 1;
+	}
+/****************************************************************
+ *	Name:	WriteDataBoth	:LOCAL
+ *
+ *	Description:	Write data to device.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static int WriteDataBoth (PADAPTER2220I padapter)
+	{
+	ULONG	zl;
+	UCHAR	status0, status1;
 
-	timer = jiffies + TIMEOUT_DRQ;								// calculate the timeout value
-	do  {
-		if ( inb_p (pports[PORT_STAT_CMD]) & IDE_STATUS_DRQ )
-			{
-			outb_p (0, padapter->regDmaDesc);							// write operation
-			outl (padapter->timingAddress, padapter->regDmaAddrLoc);
-			outl (virt_to_bus (padapter->buffer), padapter->regDmaAddrPci);
-			outl ((ULONG)padapter->ide.ide.ide[2] * (ULONG)512, padapter->regDmaCount);
-			outb_p (1, padapter->regDmaMode);							// interrupts off
-			outb_p (0x03, padapter->regDmaCmdStat);						// kick the DMA engine in gear
+	SelectSpigot (padapter, 1);
+	status0 = WaitDrq (padapter);
+	if ( !status0 )
+		{
+		SelectSpigot (padapter, 2);
+		status1 = WaitDrq (padapter);
+		if ( !status1 )
+			{
+			SelectSpigot (padapter, 3);
+			if ( padapter->timingPIO )
+				{
+				zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
+				outsw (padapter->regData, padapter->buffer, zl * (BYTES_PER_SECTOR / 2));
+				padapter->sectorCount -= zl;
+				padapter->buffer += zl * BYTES_PER_SECTOR;
+				}
+			else
+				BusMaster (padapter, 0, 0);
 			return 0;
 			}
-		}	while ( timer > jiffies );									// test for timeout
-
-	padapter->ide.ide.ides.cmd = 0;									// null out the command byte
-	return 1;
+		}
+	padapter->cmd = 0;												// null out the command byte
+	if ( status0 )
+		return 1;
+	return 2;
 	}
 /****************************************************************
  *	Name:	IdeCmd	:LOCAL
  *
- *	Description:	Process a queued command from the SCSI manager.
+ *	Description:	Process an IDE command.
  *
  *	Parameters:		padapter - Pointer adapter data structure.
+ *					pdev	 - Pointer to device.
  *
  *	Returns:		Zero if no error or status register contents on error.
  *
  ****************************************************************/
-static UCHAR IdeCmd (PADAPTER2220I padapter)
+static UCHAR IdeCmd (PADAPTER2220I padapter, POUR_DEVICE pdev)
 	{
-	ULONG	timer;
-	USHORT *pports = padapter->ports;
 	UCHAR	status;
 
-	outb_p (padapter->ide.ide.ides.spigot, pports[PORT_STAT_SEL]);	// select the spigot
-	outb_p (padapter->ide.ide.ide[6], pports[PORT_LBA_24]);			// select the drive
-	timer = jiffies + TIMEOUT_READY;							// calculate the timeout value
-	DEB(printk ("\npci2220i Issueing new command: 0x%X",padapter->ide.ide.ides.cmd));
-	do  {
-		status = inb_p (padapter->ports[PORT_STAT_CMD]);
-		if ( status & IDE_STATUS_DRDY )
-			{
-			outb_p (padapter->ide.ide.ide[2], pports[PORT_SECTOR_COUNT]);
-			outb_p (padapter->ide.ide.ide[3], pports[PORT_LBA_0]);
-			outb_p (padapter->ide.ide.ide[4], pports[PORT_LBA_8]);
-			outb_p (padapter->ide.ide.ide[5], pports[PORT_LBA_16]);
-			padapter->expectingIRQ = 1;
-			outb_p (padapter->ide.ide.ide[7], pports[PORT_STAT_CMD]);
-
-			if ( padapter->ide.ide.ides.cmd == IDE_CMD_WRITE_MULTIPLE )
-				return (WriteData (padapter));
-			return 0;
-			}
-		}	while ( timer > jiffies );									// test for timeout
+	SelectSpigot (padapter, pdev->spigot);							// select the spigot
+	outb_p (pdev->byte6 | ((UCHAR *)(&padapter->startSector))[3], padapter->regLba24);			// select the drive
+	status = WaitReady (padapter);
+	if ( !status )
+		{
+		outb_p (padapter->sectorCount, padapter->regSectCount);
+		outb_p (((UCHAR *)(&padapter->startSector))[0], padapter->regLba0);
+		outb_p (((UCHAR *)(&padapter->startSector))[1], padapter->regLba8);
+		outb_p (((UCHAR *)(&padapter->startSector))[2], padapter->regLba16);
+		padapter->expectingIRQ = TRUE;
+		WriteCommand (padapter, padapter->cmd);
+		return 0;
+		}
 
-	padapter->ide.ide.ides.cmd = 0;									// null out the command byte
+	padapter->cmd = 0;									// null out the command byte
 	return status;
 	}
 /****************************************************************
- *	Name:	SetupTransfer	:LOCAL
+ *	Name:	IdeCmdBoth	:LOCAL
  *
- *	Description:	Setup a data transfer command.
+ *	Description:	Process an IDE command to both drivers.
  *
  *	Parameters:		padapter - Pointer adapter data structure.
- *					drive	 - Drive/head register upper nibble only.
  *
- *	Returns:		TRUE if no data to transfer.
+ *	Returns:		Zero if no error or spigot of error.
  *
  ****************************************************************/
-static int SetupTransfer (PADAPTER2220I padapter, UCHAR drive)
+static UCHAR IdeCmdBoth (PADAPTER2220I padapter)
 	{
-	if ( padapter->sectorCount )
+	UCHAR	status0;
+	UCHAR	status1;
+
+	SelectSpigot (padapter, 3);										// select the spigots
+	outb_p (padapter->pdev->byte6 | ((UCHAR *)(&padapter->startSector))[3], padapter->regLba24);// select the drive
+	SelectSpigot (padapter, 1);
+	status0 = WaitReady (padapter);
+	if ( !status0 )
 		{
-		*(ULONG *)padapter->ide.ide.ides.lba = padapter->startSector;
-		padapter->ide.ide.ide[6] |= drive;
-//		padapter->ide.ide.ides.sectors = ( padapter->sectorCount > SECTORSXFER ) ? SECTORSXFER : padapter->sectorCount;
-		padapter->ide.ide.ides.sectors = ( padapter->sectorCount > MAX_BUS_MASTER_BLOCKS ) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
-		padapter->sectorCount -= padapter->ide.ide.ides.sectors;	// bump the start and count for next xfer
-		padapter->startSector += padapter->ide.ide.ides.sectors;
-		return 0;
+		SelectSpigot (padapter, 2);
+		status1 = WaitReady (padapter);
+		if ( !status1 )
+			{
+			SelectSpigot (padapter, 3);
+			outb_p (padapter->sectorCount, padapter->regSectCount);
+			outb_p (((UCHAR *)(&padapter->startSector))[0], padapter->regLba0);
+			outb_p (((UCHAR *)(&padapter->startSector))[1], padapter->regLba8);
+			outb_p (((UCHAR *)(&padapter->startSector))[2], padapter->regLba16);
+			padapter->expectingIRQ = TRUE;
+			WriteCommand (padapter, padapter->cmd);
+			return 0;
+			}
+		}
+	padapter->cmd = 0;									// null out the command byte
+	if ( status0 )
+		return 1;
+	return 2;
+	}
+/****************************************************************
+ *	Name:	OpDone	:LOCAL
+ *
+ *	Description:	Complete an operatoin done sequence.
+ *
+ *	Parameters:		padapter - Pointer to host data block.
+ *					spigot	 - Spigot select code.
+ *					device	 - Device byte code.
+ *
+ *	Returns:		Nothing.
+ *
+ ****************************************************************/
+static void OpDone (PADAPTER2220I padapter, ULONG result)
+	{
+	Scsi_Cmnd	   *SCpnt = padapter->SCpnt;
+	
+	if ( padapter->reconPhase )
+		{
+		padapter->reconPhase = 0;
+		if ( padapter->SCpnt )
+			{
+			Pci2220i_QueueCommand (SCpnt, SCpnt->scsi_done);
+			}
+		else
+			{
+			if ( padapter->reconOn )
+				{
+				ReconTimerExpiry ((unsigned long)padapter);
+				}
+			}
 		}
 	else
 		{
-		padapter->ide.ide.ides.cmd = 0;								// null out the command byte
-		padapter->SCpnt = NULL;
-		return 1;
+		padapter->cmd = 0;
+		padapter->SCpnt = NULL;	
+		SCpnt->result = result;
+		SCpnt->scsi_done (SCpnt);
+		if ( padapter->reconOn && !padapter->reconTimer.data )
+			{
+			padapter->reconTimer.expires = jiffies + (HZ / 4);	// start in 1/4 second
+			padapter->reconTimer.data = (unsigned long)padapter;
+			add_timer (&padapter->reconTimer);
+			}
 		}
 	}
 /****************************************************************
+ *	Name:	InlineIdentify	:LOCAL
+ *
+ *	Description:	Do an intline inquiry on a drive.
+ *
+ *	Parameters:		padapter - Pointer to host data block.
+ *					spigot	 - Spigot select code.
+ *					device	 - Device byte code.
+ *
+ *	Returns:		Last addressable sector or zero if none.
+ *
+ ****************************************************************/
+static ULONG InlineIdentify (PADAPTER2220I padapter, UCHAR spigot, UCHAR device)
+	{
+	PIDENTIFY_DATA	pid = (PIDENTIFY_DATA)Buffer;
+
+	SelectSpigot (padapter, spigot | 0x80);						// select the spigot
+	outb_p (device << 4, padapter->regLba24);				// select the drive
+	if ( WaitReady (padapter) )
+		return 0;
+	WriteCommand (padapter, IDE_COMMAND_IDENTIFY);	
+	if ( WaitDrq (padapter) )
+		return 0;
+	insw (padapter->regData, Buffer, sizeof (IDENTIFY_DATA) >> 1);
+	return (pid->LBATotalSectors - 1);
+	}
+/****************************************************************
  *	Name:	DecodeError	:LOCAL
  *
  *	Description:	Decode and process device errors.
  *
- *	Parameters:		pshost - Pointer to host data block.
+ *	Parameters:		padapter - Pointer to adapter data.
  *					status - Status register code.
  *
  *	Returns:		The driver status code.
  *
  ****************************************************************/
-static ULONG DecodeError (struct Scsi_Host *pshost, UCHAR status)
+static ULONG DecodeError (PADAPTER2220I	padapter, UCHAR status)
 	{
-	PADAPTER2220I	padapter = HOSTDATA(pshost);
 	UCHAR			error;
 
 	padapter->expectingIRQ = 0;
-	padapter->SCpnt = NULL;
 	if ( status & IDE_STATUS_WRITE_FAULT )
 		{
 		return DID_PARITY << 16;
@@ -253,7 +558,7 @@
 	if ( status & IDE_STATUS_BUSY )
 		return DID_BUS_BUSY << 16;
 
-	error = inb_p (padapter->ports[PORT_ERROR]);
+	error = inb_p (padapter->regError);
 	DEB(printk ("\npci2220i error register: %x", error));
 	switch ( error )
 		{
@@ -269,6 +574,483 @@
 	return DID_ERROR << 16;
 	}
 /****************************************************************
+ *	Name:	StartTimer	:LOCAL
+ *
+ *	Description:	Start the timer.
+ *
+ *	Parameters:		ipadapter - Pointer adapter data structure.
+ *
+ *	Returns:		Nothing.
+ *
+ ****************************************************************/
+static void StartTimer (PADAPTER2220I padapter)
+	{
+	padapter->timer.expires = jiffies + TIMEOUT_DATA;
+	add_timer (&padapter->timer);
+	}
+/****************************************************************
+ *	Name:	WriteSignature	:LOCAL
+ *
+ *	Description:	Start the timer.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *					pdev	 - Pointer to our device.
+ *					spigot	 - Selected spigot.
+ *					index	 - index of mirror signature on device.
+ *
+ *	Returns:		TRUE on any error.
+ *
+ ****************************************************************/
+static int WriteSignature (PADAPTER2220I padapter, POUR_DEVICE pdev, UCHAR spigot, int index)
+	{
+	ULONG	zl;
+
+	SelectSpigot (padapter, spigot);
+	zl = pdev->lastsectorlba[index];
+	outb_p (pdev->byte6 | ((UCHAR *)&zl)[3], padapter->regLba24);		
+	outb_p (((UCHAR *)&zl)[2], padapter->regLba16);
+	outb_p (((UCHAR *)&zl)[1], padapter->regLba8);
+	outb_p (((UCHAR *)&zl)[0], padapter->regLba0);
+	outb_p (1, padapter->regSectCount);
+
+	WriteCommand (padapter, IDE_COMMAND_WRITE);	
+	if ( WaitDrq (padapter) )
+		return TRUE;
+	StartTimer (padapter);	
+	padapter->expectingIRQ = TRUE;
+	
+	outsw (padapter->regData, Buffer, DISK_MIRROR_POSITION / 2);
+	outsw (padapter->regData, &pdev->DiskMirror[index], sizeof (DISK_MIRROR) / 2);
+	outsw (padapter->regData, Buffer, ((512 - (DISK_MIRROR_POSITION + sizeof (DISK_MIRROR))) / 2));
+	return FALSE;
+	}
+/*******************************************************************************************************
+ *	Name:			InitFailover
+ *
+ *	Description:	This is the beginning of the failover routine
+ *
+ *	Parameters:		SCpnt	 - Pointer to SCSI command structure.
+ *					padapter - Pointer adapter data structure.
+ *					pdev	 - Pointer to our device.
+ *	
+ *	Returns:		TRUE on error.
+ *
+ ******************************************************************************************************/
+static int InitFailover (PADAPTER2220I padapter, POUR_DEVICE pdev)
+	{
+	UCHAR			 spigot;
+	
+	DEB (printk ("\npci2220i:  Initialize failover process - survivor = %d", padapter->survivor));
+	pdev->raid = FALSE;									//initializes system for non raid mode
+	pdev->hotRecon = 0;
+	padapter->reconOn = FALSE;
+	spigot = (padapter->survivor) ? 2 : 1;	
+
+	if ( pdev->DiskMirror[padapter->survivor].status & UCBF_REBUILD )
+		return (TRUE); 	
+
+	if ( HardReset (padapter, pdev, spigot) )
+		return TRUE;
+
+	outb_p (0x3C | spigot, padapter->regFail);			// sound alarm and set fail light		
+	pdev->DiskMirror[padapter->survivor].status = UCBF_MIRRORED | UCBF_SURVIVOR;	//clear present status
+	
+	if ( WriteSignature (padapter, pdev, spigot, padapter->survivor) )
+		return TRUE;
+	padapter->failinprog = TRUE;
+	return FALSE;
+	}
+/****************************************************************
+ *	Name:	TimerExpiry	:LOCAL
+ *
+ *	Description:	Timer expiry routine.
+ *
+ *	Parameters:		data - Pointer adapter data structure.
+ *
+ *	Returns:		Nothing.
+ *
+ ****************************************************************/
+static void TimerExpiry (unsigned long data)
+	{
+	PADAPTER2220I	padapter = (PADAPTER2220I)data;
+	POUR_DEVICE		pdev = padapter->pdev;
+	ULONG			flags;
+	UCHAR			status = IDE_STATUS_BUSY;
+	UCHAR			temp, temp1;
+
+	DEB (printk ("\nPCI2220I: Timeout expired "));
+	save_flags (flags);
+	cli ();
+
+	if ( padapter->failinprog )
+		{
+		DEB (printk ("in failover process"));
+		restore_flags (flags);
+		OpDone (padapter, DecodeError (padapter, inb_p (padapter->regStatCmd)));
+		return;
+		}
+	
+	while ( padapter->reconPhase )
+		{
+		DEB (printk ("in recon phase %X", padapter->reconPhase));
+		if ( --padapter->timeoutReconRetry )
+			{
+			StartTimer (padapter);
+			return;
+			}
+		switch ( padapter->reconPhase )
+			{
+			case RECON_PHASE_MARKING:
+			case RECON_PHASE_LAST:
+				padapter->survivor = (pdev->spigot ^ 3) >> 1;
+				restore_flags (flags);
+				DEB (printk ("\npci2220i: FAILURE 1"));
+				if ( InitFailover (padapter, pdev) )
+					OpDone (padapter, DID_ERROR << 16);
+				return;
+			
+			case RECON_PHASE_READY:
+				OpDone (padapter, DID_ERROR << 16);
+				return;
+
+			case RECON_PHASE_COPY:
+				padapter->survivor = (pdev->spigot) >> 1;
+				restore_flags (flags);
+				DEB (printk ("\npci2220i: FAILURE 2"));
+				if ( InitFailover (padapter, pdev) )
+					OpDone (padapter, DID_ERROR << 16);
+				return;
+
+			case RECON_PHASE_UPDATE:
+				padapter->survivor = (pdev->spigot) >> 1;
+				restore_flags (flags);
+				DEB (printk ("\npci2220i: FAILURE 3"));
+				if ( InitFailover (padapter, pdev) )
+					OpDone (padapter, DID_ERROR << 16);
+				return;
+
+			case RECON_PHASE_END:
+				padapter->survivor = (pdev->spigot) >> 1;
+				restore_flags (flags);
+				DEB (printk ("\npci2220i: FAILURE 4"));
+				if ( InitFailover (padapter, pdev) )
+					OpDone (padapter, DID_ERROR << 16);
+				return;
+			
+			default:
+				return;
+			}
+		}
+	
+	while ( padapter->cmd )
+		{
+		outb_p (0x08, padapter->regDmaCmdStat);					// cancel interrupt from DMA engine
+		if ( pdev->raid )
+			{
+			if ( padapter->cmd == WRITE_CMD )
+				{
+				DEB (printk ("in RAID write operation"));
+				if ( inb_p (padapter->regStatSel) & 1 )
+					{
+					SelectSpigot (padapter, 0x81 ); // Masking the interrupt during spigot select
+					temp = inb_p (padapter->regStatCmd);
+					}
+				else
+					temp = IDE_STATUS_BUSY;
+
+				if ( inb (padapter->regStatSel) & 2 )
+					{
+					SelectSpigot (padapter, 0x82 ); // Masking the interrupt during spigot select
+					temp1 = inb_p (padapter->regStatCmd);
+					}
+				else
+					temp1 = IDE_STATUS_BUSY;
+			
+				if ( (temp & IDE_STATUS_BUSY) || (temp1 & IDE_STATUS_BUSY) )
+					{
+	 				if ( (temp & IDE_STATUS_BUSY) && (temp1 & IDE_STATUS_BUSY) ) 
+						{
+						status = temp;
+						break;
+						}		
+					else	
+						{
+						if (temp & IDE_STATUS_BUSY)
+							padapter->survivor = 1;
+						else
+							padapter->survivor = 0;
+						restore_flags (flags);
+				DEB (printk ("\npci2220i: FAILURE 5"));
+						if ( InitFailover (padapter, pdev) )
+							{
+							status = inb_p (padapter->regStatCmd);
+							break;
+							}
+						return;
+						}
+					}
+				}
+			else
+				{
+				DEB (printk ("in RAID read operation"));
+				padapter->survivor = (pdev->spigot ^ 3) >> 1;
+				restore_flags (flags);
+				DEB (printk ("\npci2220i: FAILURE 6"));
+				if ( InitFailover (padapter, pdev) )
+					{
+					status = inb_p (padapter->regStatCmd);
+					break;
+					}
+				return;
+				}
+			}
+		else
+			{
+			DEB (printk ("in I/O operation"));
+			status = inb_p (padapter->regStatCmd);
+			}
+		break;
+		}
+	
+	restore_flags (flags);
+	OpDone (padapter, DecodeError (padapter, status));
+	}
+/****************************************************************
+ *	Name:			SetReconstruct	:LOCAL
+ *
+ *	Description:	Set the reconstruct up.
+ *
+ *	Parameters:		pdev	- Pointer to device structure.
+ *					index	- Mirror index number.
+ *
+ *	Returns:		Number of sectors on new disk required.
+ *
+ ****************************************************************/
+static LONG SetReconstruct (POUR_DEVICE pdev, int index)
+	{
+	pdev->DiskMirror[index].status = UCBF_MIRRORED;							// setup the flags
+	pdev->DiskMirror[index ^ 1].status = UCBF_MIRRORED | UCBF_REBUILD;
+	pdev->DiskMirror[index ^ 1].reconstructPoint = 0;						// start the reconstruct
+	pdev->reconCount = 1990;												// mark target drive early
+	pdev->hotRecon = 1 >> index;
+	return pdev->DiskMirror[index].reconstructPoint;
+	}
+/****************************************************************
+ *	Name:	ReconTimerExpiry	:LOCAL
+ *
+ *	Description:	Reconstruct timer expiry routine.
+ *
+ *	Parameters:		data - Pointer adapter data structure.
+ *
+ *	Returns:		Nothing.
+ *
+ ****************************************************************/
+static void ReconTimerExpiry (unsigned long data)
+	{
+	PADAPTER2220I	padapter;
+	POUR_DEVICE		pdev;
+	ULONG			testsize = 0;
+	PIDENTIFY_DATA	pid;
+	USHORT			minmode;
+	ULONG			zl;
+	UCHAR			zc;
+
+	padapter = (PADAPTER2220I)data;
+	if ( padapter->SCpnt )
+		return;
+
+	pdev = padapter->device;
+	pid = (PIDENTIFY_DATA)Buffer;
+	padapter->reconTimer.data = 0;
+	padapter->timeoutReconRetry = 2;
+	padapter->pdev = pdev;
+	if ( padapter->reconIsStarting )
+		{
+		padapter->reconIsStarting = FALSE;
+		padapter->reconOn = FALSE;
+		pdev->hotRecon = FALSE;
+
+		if ( (pdev->DiskMirror[0].signature == SIGNATURE) && (pdev->DiskMirror[1].signature == SIGNATURE) &&
+			 (pdev->DiskMirror[0].pairIdentifier == (pdev->DiskMirror[1].pairIdentifier ^ 1)) )
+			{
+			if ( (pdev->DiskMirror[0].status & UCBF_MATCHED) && (pdev->DiskMirror[1].status & UCBF_MATCHED) )
+				{
+				return;
+				}
+
+			if ( pdev->DiskMirror[0].status & UCBF_SURVIVOR )				// is first drive survivor?
+				testsize = SetReconstruct (pdev, 0);
+			else
+				if ( pdev->DiskMirror[1].status & UCBF_SURVIVOR )			// is second drive survivor?
+					testsize = SetReconstruct (pdev, 1);
+
+			if ( (pdev->DiskMirror[0].status & UCBF_REBUILD) || (pdev->DiskMirror[1].status & UCBF_REBUILD) )
+				{
+				if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
+					{
+					pdev->hotRecon = 1;
+					pdev->mirrorRecon = 0;
+					}
+				else
+					{
+					pdev->hotRecon = 2;
+					pdev->mirrorRecon = 1;
+					}
+				}
+			}
+
+		if ( !pdev->hotRecon )
+			return;
+
+		zc = ((inb_p (padapter->regStatSel) >> 3) | inb_p (padapter->regStatSel)) & 0x83;		// mute the alarm
+		outb_p (zc | pdev->hotRecon | 0x40, padapter->regFail);
+
+		while ( 1 )
+			{
+			if ( HardReset (padapter, pdev, pdev->hotRecon) )
+				{
+				DEB (printk ("\npci2220i: sub 1"));
+				break;
+				}
+
+			pdev->lastsectorlba[pdev->mirrorRecon] = InlineIdentify (padapter, pdev->hotRecon, 0);
+
+			if ( pdev->lastsectorlba[pdev->mirrorRecon] < testsize )
+				{
+				DEB (printk ("\npci2220i: sub 2 %ld %ld", pdev->lastsectorlba[pdev->mirrorRecon], testsize));
+				break;
+				}
+
+	        // test LBA and multiper sector transfer compatability
+			if (!pid->SupportLBA || (pid->NumSectorsPerInt < SECTORSXFER) || !pid->Valid_64_70 )
+				{
+				DEB (printk ("\npci2220i: sub 3"));
+				break;
+				}
+
+	        // test PIO/bus matering mode compatability
+			if ( (pid->MinPIOCycleWithoutFlow > 240) && !pid->SupportIORDYDisable && !padapter->timingPIO )
+				{
+				DEB (printk ("\npci2220i: sub 4"));
+				break;
+				}
+
+			if ( pid->MinPIOCycleWithoutFlow <= 120 )	// setup timing mode of drive
+				minmode = 5;
+			else
+				{
+				if ( pid->MinPIOCylceWithFlow <= 150 )
+					minmode = 4;
+				else
+					{
+					if ( pid->MinPIOCylceWithFlow <= 180 )
+						minmode = 3;
+					else
+						{
+						if ( pid->MinPIOCylceWithFlow <= 240 )
+							minmode = 2;
+						else
+							{
+							DEB (printk ("\npci2220i: sub 5"));
+							break;
+							}
+						}
+					}
+				}
+
+			if ( padapter->timingMode > minmode )									// set minimum timing mode
+				padapter->timingMode = minmode;
+			if ( padapter->timingMode >= 2 )
+				padapter->timingAddress	= ModeArray[padapter->timingMode - 2];
+			else
+				padapter->timingPIO = TRUE;
+
+			padapter->reconOn = TRUE;
+			break;
+			}
+
+		if ( !padapter->reconOn )
+			{		
+			pdev->hotRecon = FALSE;
+			padapter->survivor = pdev->mirrorRecon ^ 1;
+			padapter->reconPhase = RECON_PHASE_FAILOVER;
+				DEB (printk ("\npci2220i: FAILURE 7"));
+			InitFailover (padapter, pdev);
+			return;
+			}
+
+		pdev->raid = TRUE;
+	
+		if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) )
+			return;
+		padapter->reconPhase = RECON_PHASE_MARKING;
+		return;
+		}
+
+	//**********************************
+	// reconstruct copy starts here	
+	//**********************************
+	if ( pdev->reconCount++ > 2000 )
+		{
+		pdev->reconCount = 0;
+		if ( WriteSignature (padapter, pdev, pdev->hotRecon, pdev->mirrorRecon) )
+			{
+			padapter->survivor = pdev->mirrorRecon ^ 1;
+			padapter->reconPhase = RECON_PHASE_FAILOVER;
+				DEB (printk ("\npci2220i: FAILURE 8"));
+			InitFailover (padapter, pdev);
+			return;
+			}
+		padapter->reconPhase = RECON_PHASE_UPDATE;
+		return;
+		}
+
+	zl = pdev->DiskMirror[pdev->mirrorRecon].reconstructPoint;	
+	padapter->reconSize = pdev->DiskMirror[pdev->mirrorRecon ^ 1].reconstructPoint - zl;
+	if ( padapter->reconSize > MAX_BUS_MASTER_BLOCKS )
+		padapter->reconSize = MAX_BUS_MASTER_BLOCKS;
+
+	if ( padapter->reconSize )
+		{
+		SelectSpigot (padapter, 3);										// select the spigots
+		outb_p (pdev->byte6 | ((UCHAR *)(&zl))[3], padapter->regLba24);// select the drive
+		SelectSpigot (padapter, pdev->spigot);
+		if ( WaitReady (padapter) )
+			return;
+
+		SelectSpigot (padapter, pdev->hotRecon);
+		if ( WaitReady (padapter) )
+			{
+			padapter->survivor = pdev->mirrorRecon ^ 1;
+			padapter->reconPhase = RECON_PHASE_FAILOVER;
+				DEB (printk ("\npci2220i: FAILURE 9"));
+			InitFailover (padapter, pdev);
+			return;
+			}
+	
+		SelectSpigot (padapter, 3);
+		outb_p (padapter->reconSize & 0xFF, padapter->regSectCount);
+		outb_p (((UCHAR *)(&zl))[0], padapter->regLba0);
+		outb_p (((UCHAR *)(&zl))[1], padapter->regLba8);
+		outb_p (((UCHAR *)(&zl))[2], padapter->regLba16);
+		padapter->expectingIRQ = TRUE;
+		padapter->reconPhase = RECON_PHASE_READY;
+		SelectSpigot (padapter, pdev->hotRecon);
+		WriteCommand (padapter, WRITE_CMD);
+		StartTimer (padapter);
+		SelectSpigot (padapter, pdev->spigot);
+		WriteCommand (padapter, READ_CMD);
+		return;
+		}
+
+	pdev->DiskMirror[pdev->mirrorRecon].status = UCBF_MIRRORED | UCBF_MATCHED;
+	pdev->DiskMirror[pdev->mirrorRecon ^ 1].status = UCBF_MIRRORED | UCBF_MATCHED;
+	if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) )
+		return;
+	padapter->reconPhase = RECON_PHASE_LAST;
+	return;
+	}
+/****************************************************************
  *	Name:	Irq_Handler	:LOCAL
  *
  *	Description:	Interrupt handler.
@@ -284,12 +1066,14 @@
 	{
 	struct Scsi_Host   *shost = NULL;	// Pointer to host data block
 	PADAPTER2220I		padapter;		// Pointer to adapter control structure
-	USHORT		 	   *pports;			// I/O port array
+	POUR_DEVICE			pdev;
 	Scsi_Cmnd		   *SCpnt;
 	UCHAR				status;
+	UCHAR				status1;
 	int					z;
+	ULONG				zl;
 
-//	DEB(printk ("\npci2220i recieved interrupt\n"));
+//	DEB (printk ("\npci2220i recieved interrupt\n"));
 
 	for ( z = 0; z < NumAdapters;  z++ )								// scan for interrupt to process
 		{
@@ -310,82 +1094,264 @@
 		}
 
 	padapter = HOSTDATA(shost);
-	pports = padapter->ports;
+	pdev = padapter->pdev;
 	SCpnt = padapter->SCpnt;
 
-	if ( !padapter->expectingIRQ )
+	if ( !padapter->expectingIRQ || !(SCpnt || padapter->reconPhase) )
 		{
 		DEB(printk ("\npci2220i Unsolicited interrupt\n"));
+		STOP_HERE ();
 		return;
 		}
 	padapter->expectingIRQ = 0;
+	outb_p (0x08, padapter->regDmaCmdStat);									// cancel interrupt from DMA engine
 
-	status = inb_p (padapter->ports[PORT_STAT_CMD]);					// read the device status
-	if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
-		goto irqerror;
-
-	switch ( padapter->ide.ide.ides.cmd )								// decide how to handle the interrupt
-		{
-		case IDE_CMD_READ_MULTIPLE:
-			if ( padapter->readPhase == 1 )								// is this a bus master channel complete?
-				{
-				DEB(printk ("\npci2220i processing read interrupt cleanup"));
-				outb_p (0x08, padapter->regDmaCmdStat);					// cancel interrupt from DMA engine
-				padapter->buffer += padapter->ide.ide.ides.sectors * 512;
-				if ( SetupTransfer (padapter, padapter->ide.ide.ide[6] & 0xF0) )
-					{
-					SCpnt->result = DID_OK << 16;
-					padapter->SCpnt = NULL;
-					SCpnt->scsi_done (SCpnt);
+	if ( padapter->failinprog )
+		{
+		DEB (printk ("\npci2220i interrupt failover complete"));
+		padapter->failinprog = FALSE;
+		status = inb_p (padapter->regStatCmd);								// read the device status
+		if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+			{
+			DEB (printk ("\npci2220i: interrupt failover error from drive %X", status));
+			padapter->cmd = 0;
+			}
+		else
+			{
+			DEB (printk ("\npci2220i: restarting failed opertation."));
+			pdev->spigot = (padapter->survivor) ? 2 : 1;
+			del_timer (&padapter->timer);
+			if ( padapter->reconPhase )
+				OpDone (padapter, DID_OK << 16);
+			else
+				Pci2220i_QueueCommand (SCpnt, SCpnt->scsi_done);
+			return;		
+			}
+		}
+
+	if ( padapter->reconPhase )
+		{
+		switch ( padapter->reconPhase )
+			{
+			case RECON_PHASE_MARKING:
+			case RECON_PHASE_LAST:
+				status = inb_p (padapter->regStatCmd);						// read the device status
+				del_timer (&padapter->timer);
+				if ( padapter->reconPhase == RECON_PHASE_LAST )
+					{
+					if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+						{
+						padapter->survivor = (pdev->spigot ^ 3) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 10"));
+						if ( InitFailover (padapter, pdev) )
+							OpDone (padapter, DecodeError (padapter, status));
+						return;
+						}
+					if ( WriteSignature (padapter, pdev, pdev->hotRecon, pdev->mirrorRecon) )
+						{
+						padapter->survivor = (pdev->spigot) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 11"));
+						if ( InitFailover (padapter, pdev) )
+							OpDone (padapter, DecodeError (padapter, status));
+						return;
+						}
+					padapter->reconPhase = RECON_PHASE_END;	
 					return;
 					}
-				padapter->readPhase = 0;
-				if ( !(status = IdeCmd (padapter)) )
+				OpDone (padapter, DID_OK << 16);
+				return;
+
+			case RECON_PHASE_READY:
+				status = inb_p (padapter->regStatCmd);						// read the device status
+				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
 					{
-					DEB (printk ("\npci2220i interrupt complete, waiting for another"));
+					del_timer (&padapter->timer);
+					OpDone (padapter, DecodeError (padapter, status));
 					return;
 					}
-				}
-			if ( status & IDE_STATUS_DRQ )
+				SelectSpigot (padapter, pdev->hotRecon);
+				if ( WaitDrq (padapter) )
+					{
+					del_timer (&padapter->timer);
+					padapter->survivor = (pdev->spigot) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 12"));
+					if ( InitFailover (padapter, pdev) )
+						OpDone (padapter, DecodeError (padapter, status));
+					return;
+					}
+				SelectSpigot (padapter, pdev->spigot | 0x40);
+				padapter->reconPhase = RECON_PHASE_COPY;
+				padapter->expectingIRQ = TRUE;
+				if ( padapter->timingPIO )
+					{
+					insw (padapter->regData, Buffer, padapter->reconSize * (BYTES_PER_SECTOR / 2));
+					}
+				else
+					{
+					outl (padapter->timingAddress, padapter->regDmaAddrLoc);
+					outl (virt_to_bus (Buffer), padapter->regDmaAddrPci);
+					outl (padapter->reconSize * BYTES_PER_SECTOR, padapter->regDmaCount);
+					outb_p (8, padapter->regDmaDesc);						// read operation
+					outb_p (1, padapter->regDmaMode);						// no interrupt
+					outb_p (0x03, padapter->regDmaCmdStat);					// kick the DMA engine in gear
+					}
+				return;
+
+			case RECON_PHASE_COPY:
+				pdev->DiskMirror[pdev->mirrorRecon].reconstructPoint += padapter->reconSize;
+
+			case RECON_PHASE_UPDATE:
+				SelectSpigot (padapter, pdev->hotRecon | 0x80);
+				status = inb_p (padapter->regStatCmd);						// read the device status
+				del_timer (&padapter->timer);
+				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+					{
+					padapter->survivor = (pdev->spigot) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 13"));
+				DEB (printk ("  status = %X  error = %X", status, inb_p (padapter->regError)));
+					if ( InitFailover (padapter, pdev) )
+						OpDone (padapter, DecodeError (padapter, status));
+					return;
+					}
+				OpDone (padapter, DID_OK << 16);
+				return;
+
+			case RECON_PHASE_END:
+				status = inb_p (padapter->regStatCmd);						// read the device status
+				del_timer (&padapter->timer);
+				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+					{
+					padapter->survivor = (pdev->spigot) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 14"));
+					if ( InitFailover (padapter, pdev) )
+						OpDone (padapter, DecodeError (padapter, status));
+					return;
+					}
+				padapter->reconOn = FALSE;
+				pdev->hotRecon = 0;
+				OpDone (padapter, DID_OK << 16);
+				return;
+
+			default:
+				return;
+			}
+		}
+		
+	switch ( padapter->cmd )												// decide how to handle the interrupt
+		{
+		case READ_CMD:
+			if ( padapter->sectorCount )
 				{
-				DEB(printk ("\npci2220i processing read interrupt start bus master cycle"));
-				outb_p (8, padapter->regDmaDesc); 				   		// read operation
-				padapter->readPhase = 1;
-				padapter->expectingIRQ = 1;
-				outl   (padapter->timingAddress, padapter->regDmaAddrLoc);
-				outl   (virt_to_bus (padapter->buffer), padapter->regDmaAddrPci);
-				outl   ((ULONG)padapter->ide.ide.ides.sectors * (ULONG)512, padapter->regDmaCount);
-				outb_p (5, padapter->regDmaMode);				   		// interrupt enable/disable
-				outb_p (0x03, padapter->regDmaCmdStat);			   		// kick the DMA engine in gear
+				status = inb_p (padapter->regStatCmd);						// read the device status
+				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+					{
+					if ( pdev->raid )
+						{
+						padapter->survivor = (pdev->spigot ^ 3) >> 1;
+						del_timer (&padapter->timer);
+				DEB (printk ("\npci2220i: FAILURE 15"));
+						if ( !InitFailover (padapter, pdev) )
+							return;
+						}
+					break;	
+					}
+				if ( padapter->timingPIO )
+					{
+					zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
+					insw (padapter->regData, padapter->buffer, zl * (BYTES_PER_SECTOR / 2));
+					padapter->sectorCount -= zl;
+					padapter->buffer += zl * BYTES_PER_SECTOR;
+					if ( !padapter->sectorCount )
+						{
+						status = 0;
+						break;
+						}
+					}
+				else
+					BusMaster (padapter, 1, 1);
+				padapter->expectingIRQ = TRUE;
 				return;
 				}
+			status = 0;
 			break;
 
-		case IDE_CMD_WRITE_MULTIPLE:
-			DEB(printk ("\npci2220i processing write interrupt cleanup"));
-			padapter->buffer += padapter->ide.ide.ides.sectors * 512;
-			if ( SetupTransfer (padapter, padapter->ide.ide.ide[6] & 0xF0) )
+		case WRITE_CMD:
+			SelectSpigot (padapter, pdev->spigot | 0x80);				
+			status = inb_p (padapter->regStatCmd);								// read the device status
+			if ( pdev->raid )
 				{
-				SCpnt->result = DID_OK << 16;
-				padapter->SCpnt = NULL;
-				SCpnt->scsi_done (SCpnt);
-				return;
+				SelectSpigot (padapter, (pdev->spigot ^ 3) | 0x80);				
+				status1 = inb_p (padapter->regStatCmd);							// read the device status
 				}
-			if ( !(status = IdeCmd (padapter)) )
+			else
+				status1 = 0;
+		
+			if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+				{	
+				if ( pdev->raid && !(status1 & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT)) )
+					{
+					padapter->survivor = (pdev->spigot ^ 3) >> 1;
+					del_timer (&padapter->timer);
+				SelectSpigot (padapter, pdev->spigot | 0x80);
+				DEB (printk ("\npci2220i: FAILURE 16  status = %X  error = %X", status, inb_p (padapter->regError)));
+					if ( !InitFailover (padapter, pdev) )
+						return;
+					}
+				break;
+				}
+			if ( pdev->raid )
 				{
-				DEB (printk ("\npci2220i interrupt complete, waiting for another"));
+				if ( status1 & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+					{	
+					padapter->survivor = pdev->spigot >> 1;
+					del_timer (&padapter->timer);
+				DEB (printk ("\npci2220i: FAILURE 17  status = %X  error = %X", status1, inb_p (padapter->regError)));
+					if ( !InitFailover (padapter, pdev) )
+						return;
+					status = status1;
+					break;
+					}
+				if ( padapter->sectorCount )
+					{
+					status = WriteDataBoth (padapter);
+					if ( status )
+						{
+						padapter->survivor = (status ^ 3) >> 1;
+						del_timer (&padapter->timer);
+				DEB (printk ("\npci2220i: FAILURE 18"));
+						if ( !InitFailover (padapter, pdev) )
+							return;
+						SelectSpigot (padapter, status | 0x80);				
+						status = inb_p (padapter->regStatCmd);								// read the device status
+						break;
+						}
+					padapter->expectingIRQ = TRUE;
+					return;
+					}
+				status = 0;
+				break;
+				}
+			if ( padapter->sectorCount )	
+				{	
+				SelectSpigot (padapter, pdev->spigot);
+				status = WriteData (padapter);
+				if ( status )
+					break;
+				padapter->expectingIRQ = TRUE;
 				return;
 				}
+			status = 0;
 			break;
 
 		case IDE_COMMAND_IDENTIFY:
 			{
 			PINQUIRYDATA	pinquiryData  = SCpnt->request_buffer;
+			PIDENTIFY_DATA	pid = (PIDENTIFY_DATA)Buffer;
 
-			DEB(printk ("\npci2220i processing verify interrupt cleanup"));
+			status = inb_p (padapter->regStatCmd);
 			if ( status & IDE_STATUS_DRQ )
 				{
-				insw (pports[PORT_DATA], &identifyData, sizeof (identifyData) >> 1);
+				insw (padapter->regData, pid, sizeof (IDENTIFY_DATA) >> 1);
 
 				memset (pinquiryData, 0, SCpnt->request_bufflen);		// Zero INQUIRY data structure.
 				pinquiryData->DeviceType = 0;
@@ -395,8 +1361,8 @@
 				// Fill in vendor identification fields.
 				for ( z = 0;  z < 20;  z += 2 )
 					{
-					pinquiryData->VendorId[z]	  = ((UCHAR *)identifyData.ModelNumber)[z + 1];
-					pinquiryData->VendorId[z + 1] = ((UCHAR *)identifyData.ModelNumber)[z];
+					pinquiryData->VendorId[z]	  = ((UCHAR *)pid->ModelNumber)[z + 1];
+					pinquiryData->VendorId[z + 1] = ((UCHAR *)pid->ModelNumber)[z];
 					}
 
 				// Initialize unused portion of product id.
@@ -407,30 +1373,32 @@
 				// product revision in INQUIRY data.
 				for ( z = 0;  z < 4;  z += 2 )
 					{
-					pinquiryData->ProductRevisionLevel[z]	 = ((UCHAR *)identifyData.FirmwareRevision)[z + 1];
-					pinquiryData->ProductRevisionLevel[z + 1] = ((UCHAR *)identifyData.FirmwareRevision)[z];
+					pinquiryData->ProductRevisionLevel[z]	 = ((UCHAR *)pid->FirmwareRevision)[z + 1];
+					pinquiryData->ProductRevisionLevel[z + 1] = ((UCHAR *)pid->FirmwareRevision)[z];
 					}
-
-				SCpnt->result = DID_OK << 16;
-				padapter->SCpnt = NULL;
-				SCpnt->scsi_done (SCpnt);
-				return;
+				if ( pdev == padapter->device )
+					*((USHORT *)(&pinquiryData->VendorSpecific)) = DEVICE_DALE_1;
+				
+				status = 0;
 				}
 			break;
 			}
 
 		default:
-			DEB(printk ("\npci2220i no real process here!"));
-			SCpnt->result = DID_OK << 16;
-			padapter->SCpnt = NULL;
-			SCpnt->scsi_done (SCpnt);
-			return;
+			status = 0;
+			break;
 		}
 
-irqerror:;
-	DEB(printk ("\npci2220i error  Device Status: %X\n", status));
-	SCpnt->result = DecodeError (shost, status);
-	SCpnt->scsi_done (SCpnt);
+	del_timer (&padapter->timer);
+	if ( status )
+		{
+		DEB (printk ("\npci2220i Interupt hanlder return error"));
+		zl = DecodeError (padapter, status);
+		}
+	else
+		zl = DID_OK << 16;
+
+	OpDone (padapter, zl);
 	}
 /****************************************************************
  *	Name:	Pci2220i_QueueCommand
@@ -449,121 +1417,182 @@
 	PADAPTER2220I	padapter = HOSTDATA(SCpnt->host);			// Pointer to adapter control structure
 	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->target];// Pointer to device information
 	UCHAR			rc;											// command return code
+	int				z; 
+	PDEVICE_RAID1	pdr;
 
 	SCpnt->scsi_done = done;
-	padapter->ide.ide.ides.spigot = pdev->spigot;
 	padapter->buffer = SCpnt->request_buffer;
-	if (done)
+	padapter->SCpnt = SCpnt;  									// Save this command data
+	if ( !done )
 		{
-		if ( !pdev->device || SCpnt->lun )
-			{
-			SCpnt->result = DID_BAD_TARGET << 16;
-			done (SCpnt);
-			return 0;
-			}
+		printk("pci2220i_queuecommand: %02X: done can't be NULL\n", *cdb);
+		return 0;
 		}
-	else
+	
+	if ( padapter->reconPhase )
+		return 0;
+	if ( padapter->reconTimer.data )
 		{
-		printk("pci2220i_queuecommand: %02X: done can't be NULL\n", *cdb);
+		del_timer (&padapter->reconTimer);
+		padapter->reconTimer.data = 0;
+		}
+		
+	if ( !pdev->device || SCpnt->lun )
+		{
+		OpDone (padapter, DID_BAD_TARGET << 16);
 		return 0;
 		}
 
-	DEB (if(*cdb) printk ("\nCDB: %X-  %X %X %X %X %X %X %X %X %X %X ", SCpnt->cmd_len, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]));
+	
 	switch ( *cdb )
 		{
 		case SCSIOP_INQUIRY:   					// inquiry CDB
 			{
-			padapter->ide.ide.ide[6] = pdev->byte6;
-			padapter->ide.ide.ides.cmd = IDE_COMMAND_IDENTIFY;
+			if ( cdb[2] == SC_MY_RAID )
+				{
+				switch ( cdb[3] ) 
+					{
+					case MY_SCSI_REBUILD:
+						padapter->reconOn = padapter->reconIsStarting = TRUE;
+						OpDone (padapter, DID_OK << 16);
+						break;
+					case MY_SCSI_ALARMMUTE:
+						MuteAlarm (padapter);
+						OpDone (padapter, DID_OK << 16);
+						break;
+					case MY_SCSI_DEMOFAIL:
+						padapter->demoFail = TRUE;				
+						OpDone (padapter, DID_OK << 16);
+						break;
+					default:
+						z = cdb[5];				// get index
+						pdr = (PDEVICE_RAID1)SCpnt->request_buffer;
+						if ( padapter->raidData[z] )
+							{
+							memcpy (&pdr->DiskRaid1, padapter->raidData[z], sizeof (DISK_MIRROR));
+							pdr->TotalSectors = padapter->device[0].blocks;
+							}
+						else
+							memset (pdr, 0, sizeof (DEVICE_RAID1));
+						OpDone (padapter, DID_OK << 16);
+						break;
+					}	
+				return 0;
+				}
+			padapter->cmd = IDE_COMMAND_IDENTIFY;
 			break;
 			}
 
 		case SCSIOP_TEST_UNIT_READY:			// test unit ready CDB
-			SCpnt->result = DID_OK << 16;
-			done (SCpnt);
+			OpDone (padapter, DID_OK << 16);
 			return 0;
-
 		case SCSIOP_READ_CAPACITY:			  	// read capctiy CDB
 			{
 			PREAD_CAPACITY_DATA	pdata = (PREAD_CAPACITY_DATA)SCpnt->request_buffer;
 
 			pdata->blksiz = 0x20000;
 			XANY2SCSI ((UCHAR *)&pdata->blks, pdev->blocks);
-			SCpnt->result = DID_OK << 16;
-			done (SCpnt);
+			OpDone (padapter, DID_OK << 16);
 			return 0;
 			}
-
 		case SCSIOP_VERIFY:						// verify CDB
-			*(ULONG *)padapter->ide.ide.ides.lba = XSCSI2LONG (&cdb[2]);
-			padapter->ide.ide.ide[6] |= pdev->byte6;
-			padapter->ide.ide.ide[2] = (UCHAR)((USHORT)cdb[8] | ((USHORT)cdb[7] << 8));
-			padapter->ide.ide.ides.cmd = IDE_COMMAND_VERIFY;
+			padapter->startSector = XSCSI2LONG (&cdb[2]);
+			padapter->sectorCount = (UCHAR)((USHORT)cdb[8] | ((USHORT)cdb[7] << 8));
+			padapter->cmd = IDE_COMMAND_VERIFY;
 			break;
-
 		case SCSIOP_READ:						// read10 CDB
 			padapter->startSector = XSCSI2LONG (&cdb[2]);
 			padapter->sectorCount = (USHORT)cdb[8] | ((USHORT)cdb[7] << 8);
-			SetupTransfer (padapter, pdev->byte6);
-			padapter->ide.ide.ides.cmd = IDE_CMD_READ_MULTIPLE;
-			padapter->readPhase = 0;
+			padapter->cmd = READ_CMD;
 			break;
-
 		case SCSIOP_READ6:						// read6  CDB
 			padapter->startSector = SCSI2LONG (&cdb[1]);
 			padapter->sectorCount = cdb[4];
-			SetupTransfer (padapter, pdev->byte6);
-			padapter->ide.ide.ides.cmd = IDE_CMD_READ_MULTIPLE;
-			padapter->readPhase = 0;
+			padapter->cmd = READ_CMD;
 			break;
-
 		case SCSIOP_WRITE:						// write10 CDB
 			padapter->startSector = XSCSI2LONG (&cdb[2]);
 			padapter->sectorCount = (USHORT)cdb[8] | ((USHORT)cdb[7] << 8);
-			SetupTransfer (padapter, pdev->byte6);
-			padapter->ide.ide.ides.cmd = IDE_CMD_WRITE_MULTIPLE;
+			padapter->cmd = WRITE_CMD;
 			break;
 		case SCSIOP_WRITE6:						// write6  CDB
 			padapter->startSector = SCSI2LONG (&cdb[1]);
 			padapter->sectorCount = cdb[4];
-			SetupTransfer (padapter, pdev->byte6);
-			padapter->ide.ide.ides.cmd = IDE_CMD_WRITE_MULTIPLE;
+			padapter->cmd = WRITE_CMD;
 			break;
-
 		default:
 			DEB (printk ("pci2220i_queuecommand: Unsupported command %02X\n", *cdb));
-			SCpnt->result = DID_ERROR << 16;
-			done (SCpnt);
+			OpDone (padapter, DID_ERROR << 16);
 			return 0;
 		}
 
-	padapter->SCpnt = SCpnt;  									// Save this command data
+	if ( padapter->reconPhase )
+		return 0;
+	
+	padapter->pdev = pdev;
 
-	rc = IdeCmd (padapter);
-	if ( rc )
+	while ( padapter->demoFail )
 		{
-		padapter->expectingIRQ = 0;
-		DEB (printk ("pci2220i_queuecommand: %02X, %02X: Device failed to respond for command\n", *cdb, padapter->ide.ide.ides.cmd));
-		SCpnt->result = DID_ERROR << 16;
-		done (SCpnt);
+		padapter->demoFail = FALSE;
+		if ( !pdev->raid || 
+			 (pdev->DiskMirror[0].status & UCBF_SURVIVOR) || 
+			 (pdev->DiskMirror[1].status & UCBF_SURVIVOR) )
+			{
+			break;
+			}
+		if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
+			padapter->survivor = 1;
+		else
+			padapter->survivor = 0;
+				DEB (printk ("\npci2220i: FAILURE 19"));
+		if ( InitFailover (padapter, pdev ) )
+			break;
 		return 0;
 		}
-	if ( padapter->ide.ide.ides.cmd == IDE_CMD_WRITE_MULTIPLE )
+
+	StartTimer (padapter);
+	if ( pdev->raid && (padapter->cmd == WRITE_CMD) )
 		{
-		if ( WriteData (padapter) )
+		rc = IdeCmdBoth (padapter);
+		if ( !rc )
+			rc = WriteDataBoth (padapter);
+		if ( rc )
 			{
+			del_timer (&padapter->timer);
 			padapter->expectingIRQ = 0;
-			DEB (printk ("pci2220i_queuecommand: %02X, %02X: Device failed to accept data\n", *cdb, padapter->ide.ide.ides.cmd));
-			SCpnt->result = DID_ERROR << 16;
-			done (SCpnt);
+			padapter->survivor = (rc ^ 3) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 20"));
+			if ( InitFailover (padapter, pdev) )
+				{
+				OpDone (padapter, DID_ERROR << 16);
+				return 0;
+				}
+			}
+		}
+	else
+		{
+		rc = IdeCmd (padapter, pdev);
+		if ( (padapter->cmd == WRITE_CMD) && !rc )
+			rc = WriteData (padapter);
+		if ( rc )
+			{
+			del_timer (&padapter->timer);
+			padapter->expectingIRQ = 0;
+			if ( pdev->raid )
+				{
+				padapter->survivor = (pdev->spigot ^ 3) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 21"));
+				if ( !InitFailover (padapter, pdev) )
+					return 0;
+				}
+			OpDone (padapter, DID_ERROR << 16);
 			return 0;
 			}
 		}
-	DEB (printk("  now waiting for initial interrupt "));
 	return 0;
 	}
 
-static void internal_done(Scsi_Cmnd * SCpnt)
+static void internal_done(Scsi_Cmnd *SCpnt)
 	{
 	SCpnt->SCp.Status++;
 	}
@@ -579,10 +1608,7 @@
  ****************************************************************/
 int Pci2220i_Command (Scsi_Cmnd *SCpnt)
 	{
-	DEB(printk("pci2220i_command: ..calling pci2220i_queuecommand\n"));
-
 	Pci2220i_QueueCommand (SCpnt, internal_done);
-
     SCpnt->SCp.Status = 0;
 	while (!SCpnt->SCp.Status)
 		barrier ();
@@ -593,7 +1619,7 @@
  *
  *	Description:	Read information from controller Flash memory.
  *
- *	Parameters:		hostdata - Pointer to host interface data structure.
+ *	Parameters:		padapter - Pointer to host interface data structure.
  *					pdata	 - Pointer to data structures.
  *					base	 - base address in Flash.
  *					length	 - lenght of data space in bytes.
@@ -601,25 +1627,24 @@
  *	Returns:		Nothing.
  *
  ****************************************************************/
-VOID ReadFlash (PADAPTER2220I hostdata, VOID *pdata, ULONG base, ULONG length)
+VOID ReadFlash (PADAPTER2220I padapter, VOID *pdata, ULONG base, ULONG length)
 	{
 	ULONG	 oldremap;
 	UCHAR	 olddesc;
 	ULONG	 z;
 	UCHAR	*pd = (UCHAR *)pdata;
 
-	oldremap = inl (hostdata->regRemap);									// save values to restore later
-	olddesc  = inb_p (hostdata->regDesc);
+	oldremap = inl (padapter->regRemap);									// save values to restore later
+	olddesc  = inb_p (padapter->regDesc);
 
-	outl (base | 1, hostdata->regRemap);									// remap to Flash space as specified
-	outb_p (0x40, hostdata->regDesc);										// describe remap region as 8 bit
+	outl (base | 1, padapter->regRemap);									// remap to Flash space as specified
+	outb_p (0x40, padapter->regDesc);										// describe remap region as 8 bit
 	for ( z = 0;  z < length;  z++)											// get "length" data count
-		*pd++ = inb_p (hostdata->regBase + z);								// read in the data
+		*pd++ = inb_p (padapter->regBase + z);								// read in the data
 
-	outl (oldremap, hostdata->regRemap);									// restore remap register values
-	outb_p (olddesc, hostdata->regDesc);
+	outl (oldremap, padapter->regRemap);									// restore remap register values
+	outb_p (olddesc, padapter->regDesc);
 	}
-
 /****************************************************************
  *	Name:	Pci2220i_Detect
  *
@@ -634,11 +1659,14 @@
 	{
 	int					pci_index = 0;
 	struct Scsi_Host   *pshost;
-	PADAPTER2220I	    hostdata;
-	ULONG				modearray[] = {DALE_DATA_MODE2, DALE_DATA_MODE3, DALE_DATA_MODE4, DALE_DATA_MODE4P};
+	PADAPTER2220I	    padapter;
 	int					unit;
 	int					z;
+	USHORT				zs;
+	USHORT				raidon = FALSE;
 	int					setirq;
+	UCHAR				spigot1 = FALSE;
+	UCHAR				spigot2 = FALSE;
 
 	if ( pcibios_present () )
 		{
@@ -650,55 +1678,51 @@
 				break;
 
 			pshost = scsi_register (tpnt, sizeof(ADAPTER2220I));
-			hostdata = HOSTDATA(pshost);
+			padapter = HOSTDATA(pshost);
+			memset (padapter, 0, sizeof (ADAPTER2220I));
 
-			pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &hostdata->basePort);
-			hostdata->basePort &= 0xFFFE;
-			DEB (printk ("\nBase Regs = %#04X", hostdata->basePort));
-			hostdata->regRemap		= hostdata->basePort + RTR_LOCAL_REMAP;				// 32 bit local space remap
-			DEB (printk (" %#04X", hostdata->regRemap));
-			hostdata->regDesc		= hostdata->basePort + RTR_REGIONS;	  				// 32 bit local region descriptor
-			DEB (printk (" %#04X", hostdata->regDesc));
-			hostdata->regRange		= hostdata->basePort + RTR_LOCAL_RANGE;				// 32 bit local range
-			DEB (printk (" %#04X", hostdata->regRange));
-			hostdata->regIrqControl	= hostdata->basePort + RTR_INT_CONTROL_STATUS;		// 16 bit interupt control and status
-			DEB (printk (" %#04X", hostdata->regIrqControl));
-			hostdata->regScratchPad	= hostdata->basePort + RTR_MAILBOX;	  				// 16 byte scratchpad I/O base address
-			DEB (printk (" %#04X", hostdata->regScratchPad));
-
-			pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_2, &hostdata->regBase);
-			hostdata->regBase &= 0xFFFE;
-			for ( z = 0;  z < 9;  z++ )													// build regester address array
-				hostdata->ports[z] = hostdata->regBase + 0x80 + (z * 4);
-			hostdata->ports[PORT_FAIL] = hostdata->regBase + REG_FAIL;
-			hostdata->ports[PORT_ALT_STAT] = hostdata->regBase + REG_ALT_STAT;
-			DEB (printk ("\nPorts ="));
-			DEB (for (z=0;z<11;z++) printk(" %#04X", hostdata->ports[z]););
-
-			hostdata->regDmaDesc	= hostdata->regBase + RTL_DMA1_DESC_PTR;			// address of the DMA discriptor register for direction of transfer
-			DEB (printk ("\nDMA Regs = %#04X", hostdata->regDmaDesc));
-			hostdata->regDmaCmdStat	= hostdata->regBase + RTL_DMA_COMMAND_STATUS + 1;	// Byte #1 of DMA command status register
-			DEB (printk (" %#04X", hostdata->regDmaCmdStat));
-			hostdata->regDmaAddrPci	= hostdata->regBase + RTL_DMA1_PCI_ADDR;			// 32 bit register for PCI address of DMA
-			DEB (printk (" %#04X", hostdata->regDmaAddrPci));
-			hostdata->regDmaAddrLoc	= hostdata->regBase + RTL_DMA1_LOCAL_ADDR;			// 32 bit register for local bus address of DMA
-			DEB (printk (" %#04X", hostdata->regDmaAddrLoc));
-			hostdata->regDmaCount	= hostdata->regBase + RTL_DMA1_COUNT;				// 32 bit register for DMA transfer count
-			DEB (printk (" %#04X", hostdata->regDmaCount));
-			hostdata->regDmaMode	= hostdata->regBase + RTL_DMA1_MODE + 1;			// 32 bit register for DMA mode control
-			DEB (printk (" %#04X", hostdata->regDmaMode));
+			pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &zs);
+			zs &= 0xFFFE;
+			padapter->basePort = zs;
+			padapter->regRemap		= zs + RTR_LOCAL_REMAP;				// 32 bit local space remap
+			padapter->regDesc		= zs + RTR_REGIONS;	  				// 32 bit local region descriptor
+			padapter->regRange		= zs + RTR_LOCAL_RANGE;				// 32 bit local range
+			padapter->regIrqControl	= zs + RTR_INT_CONTROL_STATUS;		// 16 bit interupt control and status
+			padapter->regScratchPad	= zs + RTR_MAILBOX;	  				// 16 byte scratchpad I/O base address
+
+			pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_2, &zs);
+			zs &= 0xFFFE;
+			padapter->regBase		= zs;
+			padapter->regData		= zs + REG_DATA;					// data register I/O address
+			padapter->regError		= zs + REG_ERROR;					// error register I/O address
+			padapter->regSectCount	= zs + REG_SECTOR_COUNT;			// sector count register I/O address
+			padapter->regLba0		= zs + REG_LBA_0;					// least significant byte of LBA
+			padapter->regLba8		= zs + REG_LBA_8;					// next least significant byte of LBA
+			padapter->regLba16		= zs + REG_LBA_16;					// next most significan byte of LBA
+			padapter->regLba24		= zs + REG_LBA_24;					// head and most 4 significant bits of LBA
+			padapter->regStatCmd	= zs + REG_STAT_CMD;				// status on read and command on write register
+			padapter->regStatSel	= zs + REG_STAT_SEL;				// board status on read and spigot select on write register
+			padapter->regFail		= zs + REG_FAIL;
+			padapter->regAltStat	= zs + REG_ALT_STAT;
+
+			padapter->regDmaDesc	= zs + RTL_DMA1_DESC_PTR;			// address of the DMA discriptor register for direction of transfer
+			padapter->regDmaCmdStat	= zs + RTL_DMA_COMMAND_STATUS + 1;	// Byte #1 of DMA command status register
+			padapter->regDmaAddrPci	= zs + RTL_DMA1_PCI_ADDR;			// 32 bit register for PCI address of DMA
+			padapter->regDmaAddrLoc	= zs + RTL_DMA1_LOCAL_ADDR;			// 32 bit register for local bus address of DMA
+			padapter->regDmaCount	= zs + RTL_DMA1_COUNT;				// 32 bit register for DMA transfer count
+			padapter->regDmaMode	= zs + RTL_DMA1_MODE + 1;			// 32 bit register for DMA mode control
 
-			if ( !inb_p (hostdata->regScratchPad + DALE_NUM_DRIVES) )					// if no devices on this board
+			if ( !inb_p (padapter->regScratchPad + DALE_NUM_DRIVES) )	// if no devices on this board
 				goto unregister;
 
 			pcibios_read_config_byte (pci_bus, pci_device_fn, PCI_INTERRUPT_LINE, &pshost->irq);
 			setirq = 1;
-			for ( z = 0;  z < pci_index;  z++ )											// scan for shared interrupts
+			for ( z = 0;  z < pci_index;  z++ )							// scan for shared interrupts
 				{
-				if ( PsiHost[z]->irq == pshost->irq )						// if shared then, don't posses
+				if ( PsiHost[z]->irq == pshost->irq )					// if shared then, don't posses
 					setirq = 0;
 				}
-			if ( setirq )																// if not shared, posses
+			if ( setirq )												// if not shared, posses
 				{
 				if ( request_irq (pshost->irq, Irq_Handler, 0, "pci2220i", NULL) )
 					{
@@ -706,45 +1730,110 @@
 					goto unregister;
 					}
 				}
-			PsiHost[pci_index]	= pshost;												// save SCSI_HOST pointer
+			PsiHost[pci_index]	= pshost;								// save SCSI_HOST pointer
 
-			pshost->unique_id	= hostdata->regBase;
+			pshost->unique_id	= padapter->regBase;
 			pshost->max_id		= 4;
 
-			outb_p (0x01, hostdata->regRange);											// fix our range register because other drivers want to tromp on it
+			outb_p (0x01, padapter->regRange);							// fix our range register because other drivers want to tromp on it
 
-			hostdata->timingMode	= inb_p (hostdata->regScratchPad + DALE_TIMING_MODE);
-			hostdata->timingAddress	= modearray[hostdata->timingMode - 2];
-			ReadFlash (hostdata, &DaleSetup, DALE_FLASH_SETUP, sizeof (SETUP));
-
-			for ( z = 0;  z < inb_p (hostdata->regScratchPad + DALE_NUM_DRIVES);  ++z )
-				{
-				unit = inb_p (hostdata->regScratchPad + DALE_CHANNEL_DEVICE_0 + z) & 0x0F;
-				hostdata->device[unit].device	 = inb_p (hostdata->regScratchPad + DALE_SCRATH_DEVICE_0 + unit);
-				hostdata->device[unit].byte6	 = (UCHAR)(((unit & 1) << 4) | 0xE0);
-				hostdata->device[unit].spigot	 = (UCHAR)(1 << (unit >> 1));
-				hostdata->device[unit].sectors	 = DaleSetup.setupDevice[unit].sectors;
-				hostdata->device[unit].heads	 = DaleSetup.setupDevice[unit].heads;
-				hostdata->device[unit].cylinders = DaleSetup.setupDevice[unit].cylinders;
-				hostdata->device[unit].blocks	 = DaleSetup.setupDevice[unit].blocks;
-				DEB (printk ("\nHOSTDATA->device    = %X", hostdata->device[unit].device));
-				DEB (printk ("\n          byte6     = %X", hostdata->device[unit].byte6));
-				DEB (printk ("\n          spigot    = %X", hostdata->device[unit].spigot));
-				DEB (printk ("\n          sectors   = %X", hostdata->device[unit].sectors));
-				DEB (printk ("\n          heads     = %X", hostdata->device[unit].heads));
-				DEB (printk ("\n          cylinders = %X", hostdata->device[unit].cylinders));
-				DEB (printk ("\n          blocks    = %lX", hostdata->device[unit].blocks));
-				}
-
-			printk("\nPSI-2220I EIDE CONTROLLER: at I/O = %X/%X  IRQ = %d\n", hostdata->basePort, hostdata->regBase, pshost->irq);
-			printk("(C) 1997 Perceptive Solutions, Inc. All rights reserved\n\n");
+			padapter->timingMode = inb_p (padapter->regScratchPad + DALE_TIMING_MODE);
+			if ( padapter->timingMode >= 2 )
+				padapter->timingAddress	= ModeArray[padapter->timingMode - 2];
+			else
+				padapter->timingPIO = TRUE;
+			
+			ReadFlash (padapter, &DaleSetup, DALE_FLASH_SETUP, sizeof (SETUP));
+			for ( z = 0;  z < inb_p (padapter->regScratchPad + DALE_NUM_DRIVES);  ++z )
+				{
+				unit = inb_p (padapter->regScratchPad + DALE_CHANNEL_DEVICE_0 + z) & 0x0F;
+				padapter->device[z].device	 = inb_p (padapter->regScratchPad + DALE_SCRATH_DEVICE_0 + unit);
+				padapter->device[z].byte6	 = (UCHAR)(((unit & 1) << 4) | 0xE0);
+				padapter->device[z].spigot	 = (UCHAR)(1 << (unit >> 1));
+				padapter->device[z].sectors	 = DaleSetup.setupDevice[unit].sectors;
+				padapter->device[z].heads	 = DaleSetup.setupDevice[unit].heads;
+				padapter->device[z].cylinders = DaleSetup.setupDevice[unit].cylinders;
+				padapter->device[z].blocks	 = DaleSetup.setupDevice[unit].blocks;
 
+				if ( !z )
+					{
+					ReadFlash (padapter, &DiskMirror, DALE_FLASH_RAID, sizeof (DiskMirror));
+					DiskMirror[0].status = inb_p (padapter->regScratchPad + DALE_RAID_0_STATUS);		
+					DiskMirror[1].status = inb_p (padapter->regScratchPad + DALE_RAID_1_STATUS);		
+					if ( (DiskMirror[0].signature == SIGNATURE) && (DiskMirror[1].signature == SIGNATURE) &&
+					     (DiskMirror[0].pairIdentifier == (DiskMirror[1].pairIdentifier ^ 1)) )
+						{			 
+						raidon = TRUE;
+						}	
+
+					memcpy (padapter->device[z].DiskMirror, DiskMirror, sizeof (DiskMirror));
+					padapter->raidData[0] = &padapter->device[z].DiskMirror[0];
+					padapter->raidData[2] = &padapter->device[z].DiskMirror[1];
+				
+					if ( raidon )
+						{
+						padapter->device[z].lastsectorlba[0] = InlineIdentify (padapter, 1, 0);
+						padapter->device[z].lastsectorlba[1] = InlineIdentify (padapter, 2, 0);
+						
+						if ( !(DiskMirror[1].status & UCBF_SURVIVOR) && padapter->device[z].lastsectorlba[0] )
+							spigot1 = TRUE;
+						if ( !(DiskMirror[0].status & UCBF_SURVIVOR) && padapter->device[z].lastsectorlba[1] )
+							spigot2 = TRUE;
+						if ( DiskMirror[0].status & UCBF_SURVIVOR & DiskMirror[1].status & UCBF_SURVIVOR )
+							spigot1 = TRUE;
+
+						if ( spigot1 && spigot2 )
+							{
+							padapter->device[z].raid = 1;
+							if ( DiskMirror[0].status & UCBF_REBUILD )
+								padapter->device[z].spigot = 2;
+							else
+								padapter->device[z].spigot = 1;
+							if ( (DiskMirror[0].status & UCBF_REBUILD) || (DiskMirror[1].status & UCBF_REBUILD) )
+								{
+								padapter->reconOn = padapter->reconIsStarting = TRUE;
+								}
+							}
+						else
+							{
+							if ( spigot1 )
+								{
+								if ( DiskMirror[0].status & UCBF_REBUILD )
+									goto unregister;
+								DiskMirror[0].status = UCBF_MIRRORED | UCBF_SURVIVOR;
+								padapter->device[z].spigot = 1;
+								}
+							else
+								{
+								if ( DiskMirror[1].status & UCBF_REBUILD )
+									goto unregister;
+								DiskMirror[1].status = UCBF_MIRRORED | UCBF_SURVIVOR;
+								padapter->device[z].spigot = 2;
+								}
+							if ( DaleSetup.rebootRebuil )
+								padapter->reconOn = padapter->reconIsStarting = TRUE;
+							}
+				
+						break;
+						}
+					}
+				}
+			
+			init_timer (&padapter->timer);
+			padapter->timer.function = TimerExpiry;
+			padapter->timer.data = (unsigned long)padapter;
+			init_timer (&padapter->reconTimer);
+			padapter->reconTimer.function = ReconTimerExpiry;
+			padapter->reconTimer.data = (unsigned long)padapter;
+			printk("\nPCI-2220I EIDE CONTROLLER: at I/O = %X/%X  IRQ = %d\n", padapter->basePort, padapter->regBase, pshost->irq);
+			printk("Version %s, Compiled %s %s\n\n", PCI2220I_VERSION, __DATE__, __TIME__);
 			NumAdapters++;
 			continue;
 unregister:;
 			scsi_unregister (pshost);
 			}
 		}
+	
 	return NumAdapters;
 	}
 /****************************************************************
@@ -759,7 +1848,6 @@
  ****************************************************************/
 int Pci2220i_Abort (Scsi_Cmnd *SCpnt)
 	{
-	DEB (printk ("pci2220i_abort\n"));
 	return SCSI_ABORT_SNOOZE;
 	}
 /****************************************************************
@@ -816,4 +1904,3 @@
 
 #include "scsi_module.c"
 #endif
-
diff -urN linux-2.0.39-pre7/drivers/scsi/pci2220i.h linux-2.0.39-pre8/drivers/scsi/pci2220i.h
--- linux-2.0.39-pre7/drivers/scsi/pci2220i.h	1999-06-13 10:21:02.000000000 -0700
+++ linux-2.0.39-pre8/drivers/scsi/pci2220i.h	2003-08-15 15:05:04.000000000 -0700
@@ -1,7 +1,7 @@
 /*+M*************************************************************************
- * Perceptive Solutions, Inc. PCI-2000 device driver proc support for Linux.
+ * Perceptive Solutions, Inc. PCI-2220i device driver proc support for Linux.
  *
- * Copyright (c) 1997 Perceptive Solutions, Inc.
+ * Copyright (c) 1999 Perceptive Solutions, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,12 +25,6 @@
  *
  *-M*************************************************************************/
 
-#ifndef _PCI2220I_H
-#define _PCI2220I_H
-
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-
 #ifndef	PSI_EIDE_SCSIOP
 #define	PSI_EIDE_SCSIOP	1
 
@@ -46,11 +40,14 @@
 #define	ULONG		unsigned long
 #define	VOID		void
 
+#include "psi_dale.h"
+
 /************************************************/
 /*		Timeout konstants		 				*/
 /************************************************/
-#define	TIMEOUT_READY				10		// 100 mSec
-#define	TIMEOUT_DRQ					40		// 400 mSec
+#define	TIMEOUT_READY				100			// 100 mSec
+#define	TIMEOUT_DRQ					300			// 300 mSec
+#define	TIMEOUT_DATA				(3 * HZ)	// 3 seconds
 
 /************************************************/
 /*		Misc. macros			 				*/
@@ -76,6 +73,9 @@
 + (((long)(((UCHAR *)up)[2])) <<  8)	\
 + ((long)(((UCHAR *)up)[3])) )
 
+#define	SelectSpigot(padapter,spigot)	outb_p (spigot, padapter->regStatSel)
+#define WriteCommand(padapter,cmd)		outb_p (cmd, padapter->regStatCmd)
+
 /************************************************/
 /*		SCSI CDB operation codes 				*/
 /************************************************/
@@ -163,8 +163,6 @@
 #define	IDE_CMD_READ_MULTIPLE		0xC4
 #define	IDE_CMD_WRITE_MULTIPLE		0xC5
 #define	IDE_CMD_SET_MULTIPLE		0xC6
-#define IDE_COMMAND_WRITE_DMA		0xCA
-#define IDE_COMMAND_READ_DMA		0xC8
 #define IDE_COMMAND_IDENTIFY		0xEC
 
 // IDE status definitions
@@ -187,23 +185,6 @@
 #define	IDE_ERROR_UNC				0x40
 #define	IDE_ERROR_BBK				0x80
 
-//	IDE interface structure
-typedef struct _IDE_STRUCT
-	{
-	union
-		{
-		UCHAR	ide[9];
-		struct
-			{
-			USHORT	data;
-			UCHAR	sectors;
-			UCHAR	lba[4];
-			UCHAR	cmd;
-			UCHAR	spigot;
-			}	ides;
-		} ide;
-	}	IDE_STRUCT;
-
 // SCSI read capacity structure
 typedef	struct _READ_CAPACITY_DATA
 	{
@@ -238,73 +219,64 @@
 	}	INQUIRYDATA, *PINQUIRYDATA;
 
 // IDE IDENTIFY data
+#pragma pack (1)
+#pragma align 1
 typedef struct _IDENTIFY_DATA
 	{
-    USHORT GeneralConfiguration;            // 00
-    USHORT NumberOfCylinders;               // 02
-    USHORT Reserved1;                       // 04
-    USHORT NumberOfHeads;                   // 06
-    USHORT UnformattedBytesPerTrack;        // 08
-    USHORT UnformattedBytesPerSector;       // 0A
-    USHORT SectorsPerTrack;                 // 0C
-    USHORT VendorUnique1[3];                // 0E
-    USHORT SerialNumber[10];                // 14
-    USHORT BufferType;                      // 28
-    USHORT BufferSectorSize;                // 2A
-    USHORT NumberOfEccBytes;                // 2C
-    USHORT FirmwareRevision[4];             // 2E
-    USHORT ModelNumber[20];                 // 36
-    UCHAR  MaximumBlockTransfer;            // 5E
-    UCHAR  VendorUnique2;                   // 5F
-    USHORT DoubleWordIo;                    // 60
-    USHORT Capabilities;                    // 62
-    USHORT Reserved2;                       // 64
-    UCHAR  VendorUnique3;                   // 66
-    UCHAR  PioCycleTimingMode;              // 67
-    UCHAR  VendorUnique4;                   // 68
-    UCHAR  DmaCycleTimingMode;              // 69
-    USHORT TranslationFieldsValid:1;        // 6A
-    USHORT Reserved3:15;
-    USHORT NumberOfCurrentCylinders;        // 6C
-    USHORT NumberOfCurrentHeads;            // 6E
-    USHORT CurrentSectorsPerTrack;          // 70
-    ULONG  CurrentSectorCapacity;           // 72
-    USHORT Reserved4[197];                  // 76
+    USHORT	GeneralConfiguration;		//  0
+    USHORT	NumberOfCylinders;			//  1
+    USHORT	Reserved1;					//  2
+    USHORT	NumberOfHeads;				//  3
+    USHORT	UnformattedBytesPerTrack;	//  4
+    USHORT	UnformattedBytesPerSector;	//  5
+    USHORT	SectorsPerTrack;			//  6
+	USHORT	NumBytesISG;				//  7 Byte Len - inter-sector gap
+	USHORT	NumBytesSync;				//  8          - sync field
+	USHORT	NumWordsVUS;				//  9 Len - Vendor Unique Info
+    USHORT	SerialNumber[10];			// 10
+    USHORT	BufferType;					// 20
+    USHORT	BufferSectorSize;			// 21
+    USHORT	NumberOfEccBytes;			// 22
+    USHORT	FirmwareRevision[4];		// 23
+    USHORT	ModelNumber[20];			// 27
+	USHORT	NumSectorsPerInt	:8;		// 47 Multiple Mode - Sec/Blk
+	USHORT	Reserved2			:8;		// 47
+	USHORT	DoubleWordMode;				// 48 flag for double word mode capable
+	USHORT	VendorUnique1		:8;		// 49
+	USHORT	SupportDMA			:1;		// 49 DMA supported
+	USHORT	SupportLBA			:1;		// 49 LBA supported
+	USHORT	SupportIORDYDisable	:1;		// 49 IORDY can be disabled
+	USHORT	SupportIORDY		:1;		// 49 IORDY supported
+	USHORT	ReservedPsuedoDMA	:1;		// 49 reserved for pseudo DMA mode support
+	USHORT	Reserved3			:3;		// 49
+	USHORT	Reserved4;					// 50
+	USHORT	Reserved5			:8;		// 51 Transfer Cycle Timing - PIO
+	USHORT	PIOCycleTime		:8;		// 51 Transfer Cycle Timing - PIO
+	USHORT	Reserved6			:8;		// 52                       - DMA
+	USHORT	DMACycleTime		:8;		// 52                       - DMA
+	USHORT	Valid_54_58			:1;		// 53 words 54 - 58 are vaild
+	USHORT	Valid_64_70			:1;		// 53 words 64 - 70 are valid
+	USHORT	Reserved7			:14;	// 53
+	USHORT	LogNumCyl;					// 54 Current Translation - Num Cyl
+	USHORT	LogNumHeads;				// 55                       Num Heads
+	USHORT	LogSectorsPerTrack;			// 56                       Sec/Trk
+	ULONG	LogTotalSectors;			// 57                       Total Sec
+	USHORT	CurrentNumSecPerInt	:8;		// 59 current setting for number of sectors per interrupt
+	USHORT	ValidNumSecPerInt	:1;		// 59 Current setting is valid for number of sectors per interrupt
+	USHORT	Reserved8			:7;		// 59
+	ULONG	LBATotalSectors;			// 60 LBA Mode - Sectors
+	USHORT	DMASWordFlags;				// 62
+	USHORT	DMAMWordFlags;				// 63
+	USHORT	AdvancedPIOSupport  :8;		// 64 Flow control PIO transfer modes supported
+	USHORT	Reserved9			:8;		// 64
+	USHORT	MinMultiDMACycle;			// 65 minimum multiword DMA transfer cycle time per word
+	USHORT	RecomendDMACycle;			// 66 Manufacturer's recommende multiword DMA transfer cycle time
+	USHORT	MinPIOCycleWithoutFlow;		// 67 Minimum PIO transfer cycle time without flow control
+	USHORT	MinPIOCylceWithFlow;		// 68 Minimum PIO transfer cycle time with IORDY flow control
+	USHORT	ReservedSpace[256-69];		// 69
 	}	IDENTIFY_DATA, *PIDENTIFY_DATA;
-
-// Identify data without the Reserved4.
-typedef struct _IDENTIFY_DATA2 {
-    USHORT GeneralConfiguration;            // 00
-    USHORT NumberOfCylinders;               // 02
-    USHORT Reserved1;                       // 04
-    USHORT NumberOfHeads;                   // 06
-    USHORT UnformattedBytesPerTrack;        // 08
-    USHORT UnformattedBytesPerSector;       // 0A
-    USHORT SectorsPerTrack;                 // 0C
-    USHORT VendorUnique1[3];                // 0E
-    USHORT SerialNumber[10];                // 14
-    USHORT BufferType;                      // 28
-    USHORT BufferSectorSize;                // 2A
-    USHORT NumberOfEccBytes;                // 2C
-    USHORT FirmwareRevision[4];             // 2E
-    USHORT ModelNumber[20];                 // 36
-    UCHAR  MaximumBlockTransfer;            // 5E
-    UCHAR  VendorUnique2;                   // 5F
-    USHORT DoubleWordIo;                    // 60
-    USHORT Capabilities;                    // 62
-    USHORT Reserved2;                       // 64
-    UCHAR  VendorUnique3;                   // 66
-    UCHAR  PioCycleTimingMode;              // 67
-    UCHAR  VendorUnique4;                   // 68
-    UCHAR  DmaCycleTimingMode;              // 69
-	USHORT TranslationFieldsValid:1;     	// 6A
-    USHORT Reserved3:15;
-    USHORT NumberOfCurrentCylinders;        // 6C
-    USHORT NumberOfCurrentHeads;            // 6E
-    USHORT CurrentSectorsPerTrack;          // 70
-    ULONG  CurrentSectorCapacity;           // 72
-	}	IDENTIFY_DATA2, *PIDENTIFY_DATA2;
-
+#pragma pack ()
+#pragma align 0
 #endif	// PSI_EIDE_SCSIOP
 
 // function prototypes
@@ -322,10 +294,10 @@
 extern struct proc_dir_entry Proc_Scsi_Pci2220i;
 
 #define PCI2220I { NULL, NULL,						\
-			&Proc_Scsi_Pci2220i,/* proc_dir_entry */	\
+			&Proc_Scsi_Pci2220i,/* proc_dir_entry */\
 			NULL,		                			\
 			"PCI-2220I EIDE Disk Controller",		\
-			Pci2220i_Detect,							\
+			Pci2220i_Detect,						\
 			NULL,									\
 			NULL,	 								\
 			Pci2220i_Command,						\
@@ -333,7 +305,7 @@
 			Pci2220i_Abort,							\
 			Pci2220i_Reset,							\
 			NULL,									\
-			Pci2220i_BiosParam,                 		\
+			Pci2220i_BiosParam,                 	\
 			1, 										\
 			-1, 									\
 			SG_NONE,		 						\
@@ -342,4 +314,3 @@
 			0, 										\
 			DISABLE_CLUSTERING }
 
-#endif
diff -urN linux-2.0.39-pre7/drivers/scsi/psi_chip.h linux-2.0.39-pre8/drivers/scsi/psi_chip.h
--- linux-2.0.39-pre7/drivers/scsi/psi_chip.h	1999-06-13 10:21:02.000000000 -0700
+++ linux-2.0.39-pre8/drivers/scsi/psi_chip.h	2003-08-15 15:05:04.000000000 -0700
@@ -1,5 +1,5 @@
 /*+M*************************************************************************
- * Perceptive Solutions, Inc. PSI-240I device driver proc support for Linux.
+ * Perceptive Solutions, Inc. PSI-240i device driver proc support for Linux.
  *
  * Copyright (c) 1997 Perceptive Solutions, Inc.
  *
@@ -191,4 +191,4 @@
 	SETUP_DEVICE	setupDevice[8];
 	}	SETUP, *PSETUP;
 
-#endif
\ No newline at end of file
+#endif
diff -urN linux-2.0.39-pre7/drivers/scsi/psi_dale.h linux-2.0.39-pre8/drivers/scsi/psi_dale.h
--- linux-2.0.39-pre7/drivers/scsi/psi_dale.h	1999-06-13 10:21:02.000000000 -0700
+++ linux-2.0.39-pre8/drivers/scsi/psi_dale.h	2003-08-15 15:05:04.000000000 -0700
@@ -1,7 +1,7 @@
 /*+M*************************************************************************
- * Perceptive Solutions, Inc. PCI-2000 device driver proc support for Linux.
+ * Perceptive Solutions, Inc. PCI-2220i device driver proc support for Linux.
  *
- * Copyright (c) 1997 Perceptive Solutions, Inc.
+ * Copyright (c) 1999 Perceptive Solutions, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,13 +21,10 @@
  *	File Name:		psi_dale.h
  *
  *	Description:	This file contains the interface defines and
- *					error codes.
+ *					error codes. 
  *
  *-M*************************************************************************/
 
-#ifndef PSI_DALE
-#define PSI_DALE
-
 /************************************************/
 /*		Dale PCI setup							*/
 /************************************************/
@@ -58,24 +55,24 @@
 /************************************************/
 /*		DALE Register address offsets			*/
 /************************************************/
-#define	REG_DATA				0x80
-#define	REG_ERROR				0x84
-#define	REG_SECTOR_COUNT		0x88
-#define	REG_LBA_0				0x8C
-#define	REG_LBA_8				0x90
-#define	REG_LBA_16				0x94
-#define	REG_LBA_24				0x98
-#define	REG_STAT_CMD			0x9C
-#define	REG_STAT_SEL			0xA0
-#define	REG_FAIL				0xB0
-#define	REG_ALT_STAT			0xB8
-#define	REG_DRIVE_ADRS			0xBC
-
-#define	DALE_DATA_SLOW			0x00040000L
-#define	DALE_DATA_MODE2			0x00040000L
-#define	DALE_DATA_MODE3			0x00050000L
-#define	DALE_DATA_MODE4			0x00060000L
-#define	DALE_DATA_MODE4P		0x00070000L
+#define	REG_DATA						0x80
+#define	REG_ERROR						0x84
+#define	REG_SECTOR_COUNT				0x88
+#define	REG_LBA_0						0x8C
+#define	REG_LBA_8						0x90
+#define	REG_LBA_16						0x94
+#define	REG_LBA_24						0x98
+#define	REG_STAT_CMD					0x9C
+#define	REG_STAT_SEL					0xA0
+#define	REG_FAIL						0xB0
+#define	REG_ALT_STAT					0xB8
+#define	REG_DRIVE_ADRS					0xBC
+
+#define	DALE_DATA_SLOW					0x00040000L
+#define	DALE_DATA_MODE2					0x00040000L
+#define	DALE_DATA_MODE3					0x00050000L
+#define	DALE_DATA_MODE4					0x00060000L
+#define	DALE_DATA_MODE4P				0x00070000L
 
 #define RTR_LOCAL_RANGE					0x000
 #define RTR_LOCAL_REMAP					0x004
@@ -110,52 +107,52 @@
 /************************************************/
 /*		Dale Scratchpad locations				*/
 /************************************************/
-#define	DALE_CHANNEL_DEVICE_0	0		// device channel locations
-#define	DALE_CHANNEL_DEVICE_1	1
-#define	DALE_CHANNEL_DEVICE_2	2
-#define	DALE_CHANNEL_DEVICE_3	3
-
-#define	DALE_SCRATH_DEVICE_0	4		// device type codes
-#define	DALE_SCRATH_DEVICE_1	5
-#define DALE_SCRATH_DEVICE_2	6
-#define	DALE_SCRATH_DEVICE_3	7
-
-#define	DALE_RAID_0_STATUS		8
-#define DALE_RAID_1_STATUS		9
-
-#define	DALE_TIMING_MODE		12		// bus master timing mode (2, 3, 4, 5)
-#define	DALE_NUM_DRIVES			13		// number of addressable drives on this board
-#define	DALE_RAID_ON			14 		// RAID status On
-#define	DALE_LAST_ERROR			15		// Last error code from BIOS
+#define	DALE_CHANNEL_DEVICE_0			0		// device channel locations
+#define	DALE_CHANNEL_DEVICE_1			1
+#define	DALE_CHANNEL_DEVICE_2			2
+#define	DALE_CHANNEL_DEVICE_3			3
+
+#define	DALE_SCRATH_DEVICE_0			4		// device type codes
+#define	DALE_SCRATH_DEVICE_1			5
+#define DALE_SCRATH_DEVICE_2			6
+#define	DALE_SCRATH_DEVICE_3			7
+
+#define	DALE_RAID_0_STATUS				8
+#define DALE_RAID_1_STATUS				9
+
+#define	DALE_TIMING_MODE				12		// bus master timing mode (2, 3, 4, 5)
+#define	DALE_NUM_DRIVES					13		// number of addressable drives on this board
+#define	DALE_RAID_ON					14 		// RAID status On
+#define	DALE_LAST_ERROR					15		// Last error code from BIOS
 
 /************************************************/
 /*		Dale cable select bits					*/
 /************************************************/
-#define	SEL_NONE				0x00
-#define	SEL_1					0x01
-#define	SEL_2					0x02
+#define	SEL_NONE						0x00
+#define	SEL_1							0x01
+#define	SEL_2							0x02
 
 /************************************************/
 /*		Programmable Interrupt Controller		*/
 /************************************************/
-#define	PIC1					0x20				// first 8259 base port address
-#define	PIC2					0xA0				// second 8259 base port address
-#define	INT_OCW1				1					// Operation Control Word 1: IRQ mask
-#define	EOI						0x20				// non-specific end-of-interrupt
+#define	PIC1							0x20		// first 8259 base port address
+#define	PIC2							0xA0		// second 8259 base port address
+#define	INT_OCW1						1			// Operation Control Word 1: IRQ mask
+#define	EOI								0x20		// non-specific end-of-interrupt
 
 /************************************************/
 /*		Device/Geometry controls				*/
 /************************************************/
-#define GEOMETRY_NONE	 	0x0			// No device
-#define GEOMETRY_SET		0x1			// Geometry set
-#define	GEOMETRY_LBA		0x2			// Geometry set in default LBA mode
-#define	GEOMETRY_PHOENIX	0x3			// Geometry set in Pheonix BIOS compatibility mode
-
-#define	DEVICE_NONE			0x0			// No device present
-#define	DEVICE_INACTIVE		0x1			// device present but not registered active
-#define	DEVICE_ATAPI		0x2			// ATAPI device (CD_ROM, Tape, Etc...)
-#define	DEVICE_DASD_NONLBA	0x3			// Non LBA incompatible device
-#define	DEVICE_DASD_LBA		0x4			// LBA compatible device
+#define GEOMETRY_NONE	 			0x0				// No device
+#define GEOMETRY_SET				0x1				// Geometry set
+#define	GEOMETRY_LBA				0x2				// Geometry set in default LBA mode
+#define	GEOMETRY_PHOENIX			0x3				// Geometry set in Pheonix BIOS compatibility mode
+
+#define	DEVICE_NONE					0x0				// No device present
+#define	DEVICE_INACTIVE				0x1				// device present but not registered active
+#define	DEVICE_ATAPI				0x2				// ATAPI device (CD_ROM, Tape, Etc...)
+#define	DEVICE_DASD_NONLBA			0x3				// Non LBA incompatible device
+#define	DEVICE_DASD_LBA				0x4				// LBA compatible device
 
 /************************************************/
 /*		Setup Structure Definitions				*/
@@ -184,4 +181,38 @@
 	SETUP_DEVICE	setupDevice[4];
 	}	SETUP, *PSETUP;
 
-#endif
+/************************************************/
+/*		RAID Structure Definitions				*/
+/************************************************/
+typedef	struct
+	{
+	UCHAR	signature;			// 0x55 our mirror signature
+	UCHAR	status;				// current status bits
+	UCHAR	pairIdentifier;		// unique identifier for pair
+	ULONG	reconstructPoint;	// recontruction point for hot reconstruct
+	}	DISK_MIRROR;
+
+typedef struct	DEVICE_RAID1
+	{
+	long		TotalSectors;
+	DISK_MIRROR DiskRaid1;
+	}	DEVICE_RAID1, *PDEVICE_RAID1;
+
+#define	DISK_MIRROR_POSITION	0x01A8
+#define	SIGNATURE				0x55
+
+#define	MASK_SERIAL_NUMBER	0x0FFE			// mask for serial number matching
+#define	MASK_SERIAL_UNIT	0x0001			// mask for unit portion of serial number
+
+// Status bits
+#define	UCBF_MIRRORED		0x0010								// drive has a pair
+#define	UCBF_MATCHED		0x0020								// drive pair is matched
+#define	UCBF_SURVIVOR		0x0040								// this unit is a survivor of a pair
+#define	UCBF_REBUILD		0x0080								// rebuild in progress on this device
+
+// SCSI controls for RAID
+#define	SC_MY_RAID			0xBF			// our special CDB command byte for Win95... interface
+#define	MY_SCSI_QUERY1		0x32			// byte 1 subcommand to query driver for RAID 1 informatation
+#define	MY_SCSI_REBUILD		0x40			// byte 1 subcommand to reconstruct a mirrored pair
+#define MY_SCSI_DEMOFAIL	0x54			// byte 1 subcommand for RAID failure demonstration
+#define	MY_SCSI_ALARMMUTE	0x60			// byte 1 subcommand to mute any alarm currently on
diff -urN linux-2.0.39-pre7/drivers/scsi/psi_roy.h linux-2.0.39-pre8/drivers/scsi/psi_roy.h
--- linux-2.0.39-pre7/drivers/scsi/psi_roy.h	1999-06-13 10:21:02.000000000 -0700
+++ linux-2.0.39-pre8/drivers/scsi/psi_roy.h	2003-08-15 15:05:04.000000000 -0700
@@ -40,7 +40,7 @@
 #define MAXADAPTER			4			// Increase this and the sizes of the arrays below, if you need more.
 #define	MAX_BUS				2
 #define	MAX_UNITS			16
-#define	TIMEOUT_COMMAND		30 			// number of jiffies for command busy timeout
+#define	TIMEOUT_COMMAND		400			// number of milliSecondos for command busy timeout
 
 /************************************************/
 /*		I/O address offsets						*/
diff -urN linux-2.0.39-pre7/MAINTAINERS linux-2.0.39-pre8/MAINTAINERS
--- linux-2.0.39-pre7/MAINTAINERS	2003-08-15 15:05:04.000000000 -0700
+++ linux-2.0.39-pre8/MAINTAINERS	2003-08-15 15:05:04.000000000 -0700
@@ -73,38 +73,38 @@
 3C501 NETWORK DRIVER
 P:	Alan Cox
 M:	alan@the.3c501.cabal.tm
-L:	linux-net@vger.rutgers.edu
+L:	linux-net@vger.kernel.org
 S:	Maintained
 
 3C505 NETWORK DRIVER
 P:	Philip Blundell
 M:	Philip.Blundell@pobox.com
-L:	linux-net@vger.rutgers.edu
+L:	linux-net@vger.kernel.org
 S:	Maintained
 
 8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
 P:	Paul Gortmaker
 M:	gpg109@rsphy1.anu.edu.au
-L:	linux-net@vger.rutgers.edu
+L:	linux-net@vger.kernel.org
 S:	Maintained
 
 ADVANSYS SCSI DRIVER
 P:	Bob Frey
 M:	linux@advansys.com
 W:	http://www.advansys.com/linux.html
-L:	linux-scsi@vger.rutgers.edu
+L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
 AHA152X SCSI DRIVER
 P:	Juergen E. Fischer
 M:	Juergen Fischer <fischer@et-inf.fho-emden.de>
-L:	linux-scsi@vger.rutgers.edu
+L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
 APM DRIVER
 P:	Stephen Rothwell
 M:	apm@linuxcare.com.au
-L:	linux-laptop@vger.rutgers.edu
+L:	linux-laptop@vger.kernel.org
 W:	http://linuxcare.com.au/apm/
 S:	Maintained
 
@@ -117,7 +117,7 @@
 ARPD SUPPORT
 P:	Jonathan Layes
 M:	layes@loran.com
-L:	linux-net@vger.rutgers.edu
+L:	linux-net@vger.kernel.org
 S:	Maintained
 
 AX.25 DAMA SLAVE
@@ -125,19 +125,19 @@
 M:	jreuter@poboxes.com
 W:	http://poboxes.com/jreuter/
 W:	http://qsl.net/dl1bke/
-L:	linux-hams@vger.rutgers.edu
+L:	linux-hams@vger.kernel.org
 S:	Maintained
 
 AX.25 NETWORK LAYER
 P:	Matthias Welwarsky
 M:	dg2fef@afthd.tu-darmstadt.de
-L:	linux-hams@vger.rutgers.edu
+L:	linux-hams@vger.kernel.org
 S:	Maintained
 
 BUSLOGIC SCSI DRIVER
 P:	Leonard N. Zubkoff
 M:	Leonard N. Zubkoff <lnz@dandelion.com>
-L:	linux-scsi@vger.rutgers.edu
+L:	linux-scsi@vger.kernel.org
 W:	http://www.dandelion.com/Linux/
 S:	Maintained
 
@@ -155,7 +155,7 @@
 DAC960 RAID DRIVER
 P:	Leonard N. Zubkoff
 M:	Leonard N. Zubkoff <lnz@dandelion.com>
-L:	linux-raid@vger.rutgers.edu
+L:	linux-raid@vger.kernel.org
 S:	Maintained
 
 DC390/AM53C974 SCSI driver
@@ -167,7 +167,7 @@
 DEVICE NUMBER REGISTRY
 P:	H. Peter Anvin
 M:	hpa@zytor.com
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 DIGIBOARD DRIVER
@@ -179,44 +179,44 @@
 DIGI RIGHTSWITCH NETWORK DRIVER
 P:	Rick Richardson
 M:	rick@dgii.com
-L:	linux-net@vger.rutgers.edu
+L:	linux-net@vger.kernel.org
 W:	http://www.dgii.com/linux/
 S:	Maintained
 
 EATA-DMA SCSI DRIVER
 P:	Michael Neuffer
 M:	mike@i-Connect.Net
-L:	linux-eata@i-connect.net, linux-scsi@vger.rutgers.edu
+L:	linux-eata@i-connect.net, linux-scsi@vger.kernel.org
 S:	Maintained
 
 EATA ISA/EISA/PCI SCSI DRIVER
 P:	Dario Ballabio
 M:	dario@milano.europe.dg.com
-L:	linux-scsi@vger.rutgers.edu
+L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
 EATA-PIO SCSI DRIVER
 P:	Michael Neuffer
 M:	mike@i-Connect.Net
-L:	linux-eata@i-connect.net, linux-scsi@vger.rutgers.edu
+L:	linux-eata@i-connect.net, linux-scsi@vger.kernel.org
 S:	Maintained
 
 ETHEREXPRESS-16 NETWORK DRIVER
 P:	Philip Blundell
 M:	Philip.Blundell@pobox.com
-L:	linux-net@vger.rutgers.edu
+L:	linux-net@vger.kernel.org
 S:	Maintained
 
 EXT2 FILE SYSTEM
 P:	Remy Card
 M:	Remy.Card@linux.org
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 FILE LOCKING (flock() and fcntl()/lockf())
 P:	Andy Walker
 M:	andy@lysaker.kvaerner.no
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 FPU EMULATOR
@@ -228,46 +228,46 @@
 FRAME RELAY DLCI/FRAD (Sangoma drivers too)
 P:	Mike McLagan
 M:	mike.mclagan@linux.org
-L:	linux-net@vger.rutgers.edu
+L:	linux-net@vger.kernel.org
 S:	Maintained
 
 FTAPE/QIC-117
 P:	Claus-Justus Heine
 M:	claus@momo.math.rwth-aachen.de
-L:	linux-tape@vger.rutgers.edu
+L:	linux-tape@vger.kernel.org
 W:	http://www-math.math.rwth-aachen.de/~LBFM/claus/ftape/
 S:	Maintained
 
 FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
 P:	Rik Faith
 M:	faith@cs.unc.edu
-L:	linux-scsi@vger.rutgers.edu
+L:	linux-scsi@vger.kernel.org
 S:	Odd fixes (e.g., new signatures)
 
 GSCD CDROM DRIVER
 P:	Oliver Raupach
 M:	oliver@mm.gop.de
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 IDE DRIVER [GENERAL]
 P:	Andre Hedrick
 M:	andre@linux-ide.org
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 W:	http://linux.kernel.org/pub/linux/kernel/people/hedrick/
 S:	Supported
 
 IDE/ATAPI CDROM DRIVER 
 P:	Jens Axboe
 M:	axboe@suse.de
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 W:	http://www.kernel.dk
 S:	Maintained
 
 IDE/ATAPI TAPE/FLOPPY DRIVERS
 P:	Gadi Oxman
 M:	Gadi Oxman <gadio@netvision.net.il>
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 IP MASQUERADING (IPV4)
@@ -279,7 +279,7 @@
 IPX NETWORK LAYER
 P:	Alan Cox [for the moment]
 M:	net-patches@lxorguk.ukuu.org.uk
-L:	linux-ipx@vger.rutgers.edu [will change]
+L:	linux-ipx@vger.kernel.org [will change]
 S:	Maintained
 
 ISDN SUBSYSTEM [GENERAL]
@@ -305,26 +305,26 @@
 LANCE AND LANCE32 NETWORK DRIVER
 P:	Thomas Bogendoerfer
 M:	tsbogend@bigbug.franken.de
-L:	linux-net@vger.rutgers.edu
+L:	linux-net@vger.kernel.org
 S:	Maintained
 
 MENUCONFIG
 P:	William Roadcap
 M:	roadcapw@titus.org
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 MODULE SUPPORT [GENERAL], KERNELD
 P:	Bjorn Ekwall
 M:	bj0rn@blox.se
 W:	http://www.pi.se/blox/modules/
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 MOUSE AND MISC DEVICES [GENERAL]
 P:	Alessandro Rubini
 M:	rubini@ipvvis.unipv.it
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 NCP FILESYSTEM
@@ -336,53 +336,53 @@
 NETROM NETWORK LAYER
 P:	Jon Naylor
 M:	jsn@cs.nott.ac.uk
-L:	linux-hams@vger.rutgers.edu
+L:	linux-hams@vger.kernel.org
 S:	Maintained
 
 NETWORKING [GENERAL]
 P:	Alan Cox
 M:	net-patches@lxorguk.ukuu.org.uk
-L:	linux-net@vger.rutgers.edu
+L:	linux-net@vger.kernel.org
 S:	Odd Fixes <-> Maintained subject to workloads
 
 NON-IDE/NON-SCSI CDROM DRIVERS [GENERAL] (come on, crew - mark your responsibility)
 P:	Eberhard Moenkeberg
 M:	emoenke@gwdg.de
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 PPP PROTOCOL DRIVERS AND COMPRESSORS
 P:	Al Longyear
 M:	longyear@pobox.com
-L:	linux-ppp@vger.rutgers.edu
+L:	linux-ppp@vger.kernel.org
 S:	Maintained
 
 REAL TIME CLOCK DRIVER
 P:	Paul Gortmaker
 M:	p_gortmaker@yahoo.com
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 RISCOM8 DRIVER
 P:	Dmitry Gorodchanin
 M:	pgmdsg@ibi.com
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 SBPCD CDROM DRIVER
 P:	Eberhard Moenkeberg
 M:	emoenke@gwdg.de
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 SCSI SUBSYSTEM
-L:	linux-scsi@vger.rutgers.edu
+L:	linux-scsi@vger.kernel.org
 S:	Unmaintained
 
 SCSI TAPE DRIVER
 P:	Kai Mäkisara
 M:	Kai.Makisara@metla.fi
-L:	linux-scsi@vger.rutgers.edu
+L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
 SMB FILESYSTEM
@@ -395,20 +395,20 @@
 SMP (except SPARC)
 P:	Alan Cox
 M:	smp-patches@lxorguk.ukuu.org.uk
-L:	linux-smp@vger.rutgers.edu
+L:	linux-smp@vger.kernel.org
 S:	Maintained
 
 SPARC
 P:	David S. Miller
 M:	davem@redhat.com
-L:	sparclinux@vger.rutgers.edu
+L:	sparclinux@vger.kernel.org
 S:	Maintained
 
 SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
 P:	Roger Wolff
 M:	R.E.Wolff@BitWizard.nl
 M:	io8-linux@specialix.co.uk
-L:	linux-kernel@vger.rutgers.edu ?
+L:	linux-kernel@vger.kernel.org ?
 S:	Supported
 
 STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
@@ -424,7 +424,7 @@
 THE V2.0 KERNEL IN GENERAL
 P:	David Weinehall
 M:	tao@acc.umu.se
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 TLAN NETWORK DRIVER
@@ -436,20 +436,20 @@
 TOKEN-RING NETWORK DRIVER
 P:      Paul Norton
 M:	pnorton@ieee.org
-L:      linux-net@vger.rutgers.edu
+L:      linux-net@vger.kernel.org
 L:	linux-tr@linuxtr.net
 S:      Maintained
 
 U14-34F SCSI DRIVER
 P:	Dario Ballabio
 M:	dario@milano.europe.dg.com
-L:	linux-scsi@vger.rutgers.edu
+L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
 VFAT FILESYSTEM
 P:	Gordon Chaffee
 M:	chaffee@plateau.cs.berkeley.edu
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 W:	http://bmrc.berkeley.edu/people/chaffee
 S:	Maintained
 
@@ -462,7 +462,7 @@
 WD7000 SCSI DRIVER
 P:	Miroslav Zagorac
 M:	zaga@fly.cc.fer.hr
-L:	linux-scsi@vger.rutgers.edu
+L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
 Z8530 SCC DRIVER FOR AX.25
@@ -470,7 +470,7 @@
 M:	jreuter@poboxes.com
 W:	http://poboxes.com/jreuter/
 W:	http://qsl.net/dl1bke/
-L:	linux-hams@vger.rutgers.edu
+L:	linux-hams@vger.kernel.org
 S:	Maintained
 
 THE REST
