Parent repository is bk://linux-scsi.bkbits.net/scsi-misc-2.6
jejb@mulgrave.(none)|ChangeSet|20040311043103|02905 jejb

diff -Nru a/Documentation/scsi/st.txt b/Documentation/scsi/st.txt
--- a/Documentation/scsi/st.txt	Wed Mar 10 21:09:42 2004
+++ b/Documentation/scsi/st.txt	Wed Mar 10 21:09:42 2004
@@ -2,7 +2,7 @@
 The driver is currently maintained by Kai Mäkisara (email
 Kai.Makisara@kolumbus.fi)
 
-Last modified: Thu Feb 19 21:57:30 2004 by makisara
+Last modified: Wed Feb 25 14:09:08 2004 by makisara
 
 
 BASICS
@@ -36,8 +36,9 @@
 manager. The changes persist until the defaults again come into
 effect.
 
-3. Up to four modes can be defined and selected using the minor number
-(bits 5 and 6). Mode 0 corresponds to the defaults discussed
+3. By default, up to four modes can be defined and selected using the minor
+number (bits 5 and 6). The number of modes can be changed by changing
+ST_NBR_MODE_BITS in st.h. Mode 0 corresponds to the defaults discussed
 above. Additional modes are dormant until they are defined by the
 system manager (root). When specification of a new mode is started,
 the configuration of mode 0 is used to provide a starting point for
@@ -107,7 +108,7 @@
 dev_upper non-rew mode dev-lower
   20 -  8     7    6 5  4      0
 The non-rewind bit is always bit 7 (the uppermost bit in the lowermost
-byte). The bits defining the mode are next to the non-rewind bits. The
+byte). The bits defining the mode are below the non-rewind bit. The
 remaining bits define the tape device number. This numbering is
 backward compatible with the numbering used when the minor number was
 only 8 bits wide.
@@ -117,10 +118,10 @@
 
 The driver creates the directory /sys/class/scsi_tape and populates it with
 directories corresponding to the existing tape devices. There are autorewind
-and non-rewind entries for each mode. The names are stxmy and stxmyn, where x
-is the tape number and y is the mode. For example, the directories for the
-first tape device are (assuming four modes): st0m0  st0m0n  st0m1  st0m1n
-st0m2  st0m2n  st0m3  st0m3n.
+and non-rewind entries for each mode. The names are stxy and nstxy, where x
+is the tape number and y a character corresponding to the mode (none, l, m,
+a). For example, the directories for the first tape device are (assuming four
+modes): st0  nst0  st0l  nst0l  st0m  nst0m  st0a  nst0a.
 
 Each directory contains the entries: default_blksize  default_compression
 default_density  defined  dev  device  driver. The file 'defined' contains 1
@@ -130,7 +131,7 @@
 'device' and 'driver' point to the SCSI device and driver entries.
 
 A link named 'tape' is made from the SCSI device directory to the class
-directory corresponding to the mode 0 auto-rewind device (e.g., st0m0). 
+directory corresponding to the mode 0 auto-rewind device (e.g., st0). 
 
 
 BSD AND SYS V SEMANTICS
diff -Nru a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig
--- a/drivers/message/fusion/Kconfig	Wed Mar 10 21:09:43 2004
+++ b/drivers/message/fusion/Kconfig	Wed Mar 10 21:09:43 2004
@@ -3,7 +3,7 @@
 
 config FUSION
 	tristate "Fusion MPT (base + ScsiHost) drivers"
-	depends on BLK_DEV_SD && PCI
+	depends on PCI
 	---help---
 	  LSI Logic Fusion(TM) Message Passing Technology (MPT) device support
 	  provides high performance SCSI host initiator, and LAN [1] interface
@@ -14,41 +14,6 @@
 
 	  [1] LAN is not supported on parallel SCSI medium.
 
-	  These drivers require a Fusion MPT compatible PCI adapter installed
-	  in the host system.  MPT adapters contain specialized I/O processors
-	  to handle I/O workload, and more importantly to offload this work
-	  from the host CPU(s).
-
-	  If you have Fusion MPT hardware and want to use it, you can say
-	  Y or M here to add MPT (base + ScsiHost) drivers.
-	  <Y> = build lib (fusion), and link [static] into the kernel [2]
-	  proper
-	  <M> = compiled as [dynamic] modules [3] named: (mptbase,
-	  mptscsih)
-
-	  [2] In order enable capability to boot the linux kernel
-	  natively from a Fusion MPT target device, you MUST
-	  answer Y here! (currently requires CONFIG_BLK_DEV_SD)
-	  [3] To compile this support as modules, choose M here.
-
-	  If unsure, say N.
-
-	  If you say Y or M here you will get a choice of these
-	  additional protocol and support module options:         Module Name:
-	  <M>   Enhanced SCSI error reporting                     (isense)
-	  <M>   Fusion MPT misc device (ioctl) driver             (mptctl)
-	  <M>   Fusion MPT LAN driver                             (mptlan)
-
-	  ---
-	  Fusion MPT is trademark of LSI Logic Corporation, and its
-	  architecture is based on LSI Logic's Message Passing Interface (MPI)
-	  specification.
-
-config FUSION_BOOT
-	bool
-	depends on FUSION=y
-	default y
-
 config FUSION_MAX_SGE
 	int "Maximum number of scatter gather entries"
 	depends on FUSION
@@ -62,7 +27,6 @@
 	  necessary (or recommended) unless the user will be running 
 	  large I/O's via the raw interface.
 
-#  How can we force these options to module or nothing?
 config FUSION_ISENSE
 	tristate "Enhanced SCSI error reporting"
 	depends on MODULES && FUSION && m
@@ -132,17 +96,4 @@
 
 	  If unsure whether you really want or need this, say N.
 
-	  NOTES: This feature is NOT available nor supported for linux-2.2.x
-	  kernels.  You must be building a linux-2.3.x or linux-2.4.x kernel
-	  in order to configure this option.
-	  Support for building this feature into the linux kernel is not
-	  yet available.
-
-#  if [ "$CONFIG_FUSION_LAN" != "n" ]; then
-#    define_bool CONFIG_NET_FC y
-#  fi
-# These <should> be define_tristate, but we leave them define_bool
-# for backward compatibility with pre-linux-2.2.15 kernels.
-# (Bugzilla:fibrebugs, #384)
 endmenu
-
diff -Nru a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile
--- a/drivers/message/fusion/Makefile	Wed Mar 10 21:09:43 2004
+++ b/drivers/message/fusion/Makefile	Wed Mar 10 21:09:43 2004
@@ -17,10 +17,16 @@
 
 # Fusion MPT drivers; recognized debug defines...
 #  MPT general:
-#EXTRA_CFLAGS += -DDEBUG
+#EXTRA_CFLAGS += -DMPT_DEBUG_SCSI
 #EXTRA_CFLAGS += -DMPT_DEBUG
 #EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME
 #EXTRA_CFLAGS += -DMPT_DEBUG_SG
+
+# This is a temporary fix for the reply/request fifo
+# for some 64bit archs. Uncommenting this line
+# will place the fifo's in 32bit space
+#EXTRA_CFLAGS += -DMPTBASE_MEM_ALLOC_FIFO_FIX
+
 #
 # driver/module specifics...
 #
diff -Nru a/drivers/message/fusion/isense.c b/drivers/message/fusion/isense.c
--- a/drivers/message/fusion/isense.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/isense.c	Wed Mar 10 21:09:42 2004
@@ -5,7 +5,7 @@
  *      Error Report logging output.  This module implements SCSI-3
  *      Opcode lookup and a sorted table of SCSI-3 ASC/ASCQ strings.
  *
- *  Copyright (c) 1991-2003 Steven J. Ralston
+ *  Copyright (c) 1991-2004 Steven J. Ralston
  *  Written By: Steven J. Ralston
  *  (yes I wrote some of the orig. code back in 1991!)
  *  (mailto:sjralston1@netscape.net)
@@ -66,7 +66,7 @@
 #endif
 
 #define MODULEAUTHOR "Steven J. Ralston"
-#define COPYRIGHT "Copyright (c) 2001-2003 " MODULEAUTHOR
+#define COPYRIGHT "Copyright (c) 2001-2004 " MODULEAUTHOR
 #include "mptbase.h"
 
 #include "isense.h"
diff -Nru a/drivers/message/fusion/linux_compat.h b/drivers/message/fusion/linux_compat.h
--- a/drivers/message/fusion/linux_compat.h	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/linux_compat.h	Wed Mar 10 21:09:42 2004
@@ -15,25 +15,7 @@
 #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
 #endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-#define SET_NICE(current,x)	do {(current)->nice = (x);} while (0)
-#else
-#define SET_NICE(current,x)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-#define pci_enable_device(pdev)	(0)
-#define SCSI_DATA_UNKNOWN	0
-#define SCSI_DATA_WRITE		1
-#define SCSI_DATA_READ		2
-#define SCSI_DATA_NONE		3
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)
-#define pci_set_dma_mask(pdev, mask)	(0)
-#define scsi_set_pci_device(sh, pdev)	(0)
-#endif
+#define SET_NICE(current,x) do {(current)->nice = (x);} while (0)
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
 #	if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
@@ -147,31 +129,9 @@
 
 
 /* PCI/driver subsystem { */
-#if 0	/* FIXME Don't know what to use to check for the proper kernel version */
-#define DEVICE_COUNT_RESOURCE           6
-#define PCI_BASEADDR_FLAGS(idx)         base_address[idx]
-#define PCI_BASEADDR_START(idx)         base_address[idx] & ~0xFUL
-/*
- * We have to keep track of the original value using
- * a temporary, and not by just sticking pdev->base_address[x]
- * back.  pdev->base_address[x] is an opaque cookie that can
- * be used by the PCI implementation on a given Linux port
- * for any purpose. -DaveM
- */
-#define PCI_BASEADDR_SIZE(__pdev, __idx) \
-({	unsigned int size, tmp; \
-	pci_read_config_dword(__pdev, PCI_BASE_ADDRESS_0 + (4*(__idx)), &tmp); \
-	pci_write_config_dword(__pdev, PCI_BASE_ADDRESS_0 + (4*(__idx)), 0xffffffff); \
-	pci_read_config_dword(__pdev, PCI_BASE_ADDRESS_0 + (4*(__idx)), &size); \
-	pci_write_config_dword(__pdev, PCI_BASE_ADDRESS_0 + (4*(__idx)), tmp); \
-	(4 - size); \
-})
-#else
 #define PCI_BASEADDR_FLAGS(idx)         resource[idx].flags
 #define PCI_BASEADDR_START(idx)         resource[idx].start
 #define PCI_BASEADDR_SIZE(dev,idx)      (dev)->resource[idx].end - (dev)->resource[idx].start + 1
-#endif		/* } ifndef 0 */
-
 
 /* Compatability for the 2.3.x PCI DMA API. */
 #ifndef PCI_DMA_BIDIRECTIONAL
@@ -227,54 +187,10 @@
 /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #endif /* PCI_DMA_BIDIRECTIONAL */
 
-/*
- *  With the new command queuing code in the SCSI mid-layer we no longer have
- *  to hold the io_request_lock spin lock when calling the scsi_done routine.
- *  For now we only do this with the 2.5.1 kernel or newer.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1)
-        #define MPT_HOST_LOCK(flags)
-        #define MPT_HOST_UNLOCK(flags)
-#else
-        #define MPT_HOST_LOCK(flags) \
-                spin_lock_irqsave(&io_request_lock, flags)
-        #define MPT_HOST_UNLOCK(flags) \
-                spin_unlock_irqrestore(&io_request_lock, flags)
-#endif
-
-/*
- *  We use our new error handling code if the kernel version is 2.4.18 or newer.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,18)
-        #define MPT_SCSI_USE_NEW_EH
-#endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41)
 #define mpt_work_struct work_struct
 #define MPT_INIT_WORK(_task, _func, _data) INIT_WORK(_task, _func, _data)
-#else
-#define mpt_work_struct tq_struct
-#define MPT_INIT_WORK(_task, _func, _data) \
-({	(_task)->sync = 0; \
-	(_task)->routine = (_func); \
-	(_task)->data = (void *) (_data); \
-})
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28)
-#define mptscsih_sync_irq(_irq) synchronize_irq(_irq)
-#else
-#define mptscsih_sync_irq(_irq) synchronize_irq()
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,58)
-#define mpt_inc_use_count()
-#define mpt_dec_use_count()
-#else
-#define mpt_inc_use_count() MOD_INC_USE_COUNT
-#define mpt_dec_use_count() MOD_DEC_USE_COUNT
-#endif
-
+#define mpt_sync_irq(_irq) synchronize_irq(_irq)
 
 /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #endif /* _LINUX_COMPAT_H */
diff -Nru a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h
--- a/drivers/message/fusion/lsi/mpi.h	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/lsi/mpi.h	Wed Mar 10 21:09:42 2004
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2002 LSI Logic Corporation.
+ *  Copyright (c) 2000-2003 LSI Logic Corporation.
  *
  *
- *           Name:  MPI.H
+ *           Name:  mpi.h
  *          Title:  MPI Message independent structures and definitions
  *  Creation Date:  July 27, 2000
  *
- *    MPI.H Version:  01.02.07
+ *    mpi.h Version:  01.05.xx
  *
  *  Version History
  *  ---------------
@@ -48,6 +48,10 @@
  *  05-31-02  01.02.05  Bumped MPI_HEADER_VERSION_UNIT.
  *  07-12-02  01.02.06  Added define for MPI_FUNCTION_MAILBOX.
  *  09-16-02  01.02.07  Bumped value for MPI_HEADER_VERSION_UNIT.
+ *  11-15-02  01.02.08  Added define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX and
+ *                      obsoleted define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX.
+ *  04-01-03  01.02.09  New IOCStatus code: MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
+ *  06-26-03  01.02.10  Bumped MPI_HEADER_VERSION_UNIT value.
  *  --------------------------------------------------------------------------
  */
 
@@ -62,7 +66,7 @@
 *****************************************************************************/
 
 #define MPI_VERSION_MAJOR                   (0x01)
-#define MPI_VERSION_MINOR                   (0x02)
+#define MPI_VERSION_MINOR                   (0x05)
 #define MPI_VERSION_MAJOR_MASK              (0xFF00)
 #define MPI_VERSION_MAJOR_SHIFT             (8)
 #define MPI_VERSION_MINOR_MASK              (0x00FF)
@@ -73,10 +77,12 @@
 #define MPI_VERSION_01_00                   (0x0100)
 #define MPI_VERSION_01_01                   (0x0101)
 #define MPI_VERSION_01_02                   (0x0102)
+#define MPI_VERSION_01_03                   (0x0103)
+#define MPI_VERSION_01_05                   (0x0105)
 /* Note: The major versions of 0xe0 through 0xff are reserved */
 
 /* versioning for this MPI header set */
-#define MPI_HEADER_VERSION_UNIT             (0x09)
+#define MPI_HEADER_VERSION_UNIT             (0x00)
 #define MPI_HEADER_VERSION_DEV              (0x00)
 #define MPI_HEADER_VERSION_UNIT_MASK        (0xFF00)
 #define MPI_HEADER_VERSION_UNIT_SHIFT       (8)
@@ -171,6 +177,8 @@
 #define MPI_REPLY_POST_FIFO_OFFSET          (0x00000044)
 #define MPI_REPLY_FREE_FIFO_OFFSET          (0x00000044)
 
+#define MPI_HI_PRI_REQUEST_QUEUE_OFFSET     (0x00000048)
+
 
 
 /*****************************************************************************
@@ -230,10 +238,6 @@
 #define MPI_FUNCTION_TARGET_ASSIST                  (0x0B)
 #define MPI_FUNCTION_TARGET_STATUS_SEND             (0x0C)
 #define MPI_FUNCTION_TARGET_MODE_ABORT              (0x0D)
-#define MPI_FUNCTION_TARGET_FC_BUF_POST_LINK_SRVC   (0x0E) /* obsolete name */
-#define MPI_FUNCTION_TARGET_FC_RSP_LINK_SRVC        (0x0F) /* obsolete name */
-#define MPI_FUNCTION_TARGET_FC_EX_SEND_LINK_SRVC    (0x10) /* obsolete name */
-#define MPI_FUNCTION_TARGET_FC_ABORT                (0x11) /* obsolete name */
 #define MPI_FUNCTION_FC_LINK_SRVC_BUF_POST          (0x0E)
 #define MPI_FUNCTION_FC_LINK_SRVC_RSP               (0x0F)
 #define MPI_FUNCTION_FC_EX_LINK_SRVC_SEND           (0x10)
@@ -251,16 +255,46 @@
 
 #define MPI_FUNCTION_MAILBOX                        (0x19)
 
+#define MPI_FUNCTION_SMP_PASSTHROUGH                (0x1A)
+#define MPI_FUNCTION_SAS_IO_UNIT_CONTROL            (0x1B)
+
+#define MPI_DIAG_BUFFER_POST                        (0x1D)
+#define MPI_DIAG_RELEASE                            (0x1E)
+
+#define MPI_FUNCTION_SCSI_IO_32                     (0x1F)
+
 #define MPI_FUNCTION_LAN_SEND                       (0x20)
 #define MPI_FUNCTION_LAN_RECEIVE                    (0x21)
 #define MPI_FUNCTION_LAN_RESET                      (0x22)
 
+#define MPI_FUNCTION_INBAND_BUFFER_POST             (0x28)
+#define MPI_FUNCTION_INBAND_SEND                    (0x29)
+#define MPI_FUNCTION_INBAND_RSP                     (0x2A)
+#define MPI_FUNCTION_INBAND_ABORT                   (0x2B)
+
 #define MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET         (0x40)
 #define MPI_FUNCTION_IO_UNIT_RESET                  (0x41)
 #define MPI_FUNCTION_HANDSHAKE                      (0x42)
 #define MPI_FUNCTION_REPLY_FRAME_REMOVAL            (0x43)
 
 
+/* standard version format */
+typedef struct _MPI_VERSION_STRUCT
+{
+    U8                      Dev;                        /* 00h */
+    U8                      Unit;                       /* 01h */
+    U8                      Minor;                      /* 02h */
+    U8                      Major;                      /* 03h */
+} MPI_VERSION_STRUCT, MPI_POINTER PTR_MPI_VERSION_STRUCT,
+  MpiVersionStruct_t, MPI_POINTER pMpiVersionStruct;
+
+typedef union _MPI_VERSION_FORMAT
+{
+    MPI_VERSION_STRUCT      Struct;
+    U32                     Word;
+} MPI_VERSION_FORMAT, MPI_POINTER PTR_MPI_VERSION_FORMAT,
+  MpiVersionFormat_t, MPI_POINTER pMpiVersionFormat_t;
+
 
 /*****************************************************************************
 *
@@ -573,44 +607,54 @@
 /*  Common IOCStatus values for all replies                                 */
 /****************************************************************************/
 
-#define MPI_IOCSTATUS_SUCCESS                  (0x0000)
-#define MPI_IOCSTATUS_INVALID_FUNCTION         (0x0001)
-#define MPI_IOCSTATUS_BUSY                     (0x0002)
-#define MPI_IOCSTATUS_INVALID_SGL              (0x0003)
-#define MPI_IOCSTATUS_INTERNAL_ERROR           (0x0004)
-#define MPI_IOCSTATUS_RESERVED                 (0x0005)
-#define MPI_IOCSTATUS_INSUFFICIENT_RESOURCES   (0x0006)
-#define MPI_IOCSTATUS_INVALID_FIELD            (0x0007)
-#define MPI_IOCSTATUS_INVALID_STATE            (0x0008)
+#define MPI_IOCSTATUS_SUCCESS                   (0x0000)
+#define MPI_IOCSTATUS_INVALID_FUNCTION          (0x0001)
+#define MPI_IOCSTATUS_BUSY                      (0x0002)
+#define MPI_IOCSTATUS_INVALID_SGL               (0x0003)
+#define MPI_IOCSTATUS_INTERNAL_ERROR            (0x0004)
+#define MPI_IOCSTATUS_RESERVED                  (0x0005)
+#define MPI_IOCSTATUS_INSUFFICIENT_RESOURCES    (0x0006)
+#define MPI_IOCSTATUS_INVALID_FIELD             (0x0007)
+#define MPI_IOCSTATUS_INVALID_STATE             (0x0008)
+#define MPI_IOCSTATUS_OP_STATE_NOT_SUPPORTED    (0x0009)
 
 /****************************************************************************/
 /*  Config IOCStatus values                                                 */
 /****************************************************************************/
 
-#define MPI_IOCSTATUS_CONFIG_INVALID_ACTION    (0x0020)
-#define MPI_IOCSTATUS_CONFIG_INVALID_TYPE      (0x0021)
-#define MPI_IOCSTATUS_CONFIG_INVALID_PAGE      (0x0022)
-#define MPI_IOCSTATUS_CONFIG_INVALID_DATA      (0x0023)
-#define MPI_IOCSTATUS_CONFIG_NO_DEFAULTS       (0x0024)
-#define MPI_IOCSTATUS_CONFIG_CANT_COMMIT       (0x0025)
+#define MPI_IOCSTATUS_CONFIG_INVALID_ACTION     (0x0020)
+#define MPI_IOCSTATUS_CONFIG_INVALID_TYPE       (0x0021)
+#define MPI_IOCSTATUS_CONFIG_INVALID_PAGE       (0x0022)
+#define MPI_IOCSTATUS_CONFIG_INVALID_DATA       (0x0023)
+#define MPI_IOCSTATUS_CONFIG_NO_DEFAULTS        (0x0024)
+#define MPI_IOCSTATUS_CONFIG_CANT_COMMIT        (0x0025)
 
 /****************************************************************************/
 /*  SCSIIO Reply (SPI & FCP) initiator values                               */
 /****************************************************************************/
 
-#define MPI_IOCSTATUS_SCSI_RECOVERED_ERROR     (0x0040)
-#define MPI_IOCSTATUS_SCSI_INVALID_BUS         (0x0041)
-#define MPI_IOCSTATUS_SCSI_INVALID_TARGETID    (0x0042)
-#define MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE    (0x0043)
-#define MPI_IOCSTATUS_SCSI_DATA_OVERRUN        (0x0044)
-#define MPI_IOCSTATUS_SCSI_DATA_UNDERRUN       (0x0045)
-#define MPI_IOCSTATUS_SCSI_IO_DATA_ERROR       (0x0046)
-#define MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR      (0x0047)
-#define MPI_IOCSTATUS_SCSI_TASK_TERMINATED     (0x0048)
-#define MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH   (0x0049)
-#define MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED    (0x004A)
-#define MPI_IOCSTATUS_SCSI_IOC_TERMINATED      (0x004B)
-#define MPI_IOCSTATUS_SCSI_EXT_TERMINATED      (0x004C)
+#define MPI_IOCSTATUS_SCSI_RECOVERED_ERROR      (0x0040)
+#define MPI_IOCSTATUS_SCSI_INVALID_BUS          (0x0041)
+#define MPI_IOCSTATUS_SCSI_INVALID_TARGETID     (0x0042)
+#define MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE     (0x0043)
+#define MPI_IOCSTATUS_SCSI_DATA_OVERRUN         (0x0044)
+#define MPI_IOCSTATUS_SCSI_DATA_UNDERRUN        (0x0045)
+#define MPI_IOCSTATUS_SCSI_IO_DATA_ERROR        (0x0046)
+#define MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR       (0x0047)
+#define MPI_IOCSTATUS_SCSI_TASK_TERMINATED      (0x0048)
+#define MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH    (0x0049)
+#define MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED     (0x004A)
+#define MPI_IOCSTATUS_SCSI_IOC_TERMINATED       (0x004B)
+#define MPI_IOCSTATUS_SCSI_EXT_TERMINATED       (0x004C)
+
+/****************************************************************************/
+/*  For use by SCSI Initiator and SCSI Target end-to-end data protection    */
+/****************************************************************************/
+
+#define MPI_IOCSTATUS_EEDP_CRC_ERROR            (0x004D)
+#define MPI_IOCSTATUS_EEDP_LBA_TAG_ERROR        (0x004E)
+#define MPI_IOCSTATUS_EEDP_APP_TAG_ERROR        (0x004F)
+
 
 /****************************************************************************/
 /*  SCSI (SPI & FCP) target values                                          */
@@ -618,7 +662,8 @@
 
 #define MPI_IOCSTATUS_TARGET_PRIORITY_IO         (0x0060)
 #define MPI_IOCSTATUS_TARGET_INVALID_PORT        (0x0061)
-#define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX    (0x0062)
+#define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX    (0x0062)   /* obsolete */
+#define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX    (0x0062)
 #define MPI_IOCSTATUS_TARGET_ABORTED             (0x0063)
 #define MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE   (0x0064)
 #define MPI_IOCSTATUS_TARGET_NO_CONNECTION       (0x0065)
@@ -626,7 +671,7 @@
 #define MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT   (0x006B)
 
 /****************************************************************************/
-/*  Additional FCP target values                                            */
+/*  Additional FCP target values (obsolete)                                 */
 /****************************************************************************/
 
 #define MPI_IOCSTATUS_TARGET_FC_ABORTED         (0x0066)    /* obsolete */
@@ -642,6 +687,7 @@
 #define MPI_IOCSTATUS_FC_RX_ID_INVALID          (0x0067)
 #define MPI_IOCSTATUS_FC_DID_INVALID            (0x0068)
 #define MPI_IOCSTATUS_FC_NODE_LOGGED_OUT        (0x0069)
+#define MPI_IOCSTATUS_FC_EXCHANGE_CANCELED      (0x006C)
 
 /****************************************************************************/
 /*  LAN values                                                              */
@@ -656,6 +702,25 @@
 #define MPI_IOCSTATUS_LAN_PARTIAL_PACKET        (0x0086)
 #define MPI_IOCSTATUS_LAN_CANCELED              (0x0087)
 
+/****************************************************************************/
+/*  Serial Attached SCSI values                                                              */
+/****************************************************************************/
+
+#define MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED    (0x0090)
+
+/****************************************************************************/
+/*  Inband values                                                           */
+/****************************************************************************/
+
+#define MPI_IOCSTATUS_INBAND_ABORTED            (0x0098)
+#define MPI_IOCSTATUS_INBAND_NO_CONNECTION      (0x0099)
+
+/****************************************************************************/
+/*  Diagnostic Tools values                                                 */
+/****************************************************************************/
+
+#define MPI_IOCSTATUS_DIAGNOSTIC_RELEASED       (0x00A0)
+
 
 /****************************************************************************/
 /*  IOCStatus flag to indicate that log info is available                   */
@@ -669,9 +734,12 @@
 /****************************************************************************/
 
 #define MPI_IOCLOGINFO_TYPE_MASK                (0xF0000000)
+#define MPI_IOCLOGINFO_TYPE_SHIFT               (28)
 #define MPI_IOCLOGINFO_TYPE_NONE                (0x0)
 #define MPI_IOCLOGINFO_TYPE_SCSI                (0x1)
 #define MPI_IOCLOGINFO_TYPE_FC                  (0x2)
+#define MPI_IOCLOGINFO_TYPE_SAS                 (0x3)
+#define MPI_IOCLOGINFO_TYPE_ISCSI               (0x4)
 #define MPI_IOCLOGINFO_LOG_DATA_MASK            (0x0FFFFFFF)
 
 
diff -Nru a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h
--- a/drivers/message/fusion/lsi/mpi_cnfg.h	Wed Mar 10 21:09:43 2004
+++ b/drivers/message/fusion/lsi/mpi_cnfg.h	Wed Mar 10 21:09:43 2004
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2002 LSI Logic Corporation.
+ *  Copyright (c) 2000-2003 LSI Logic Corporation.
  *
  *
- *           Name:  MPI_CNFG.H
+ *           Name:  mpi_cnfg.h
  *          Title:  MPI Config message, structures, and Pages
  *  Creation Date:  July 27, 2000
  *
- *    MPI_CNFG.H Version:  01.02.09
+ *    mpi_cnfg.h Version:  01.05.xx
  *
  *  Version History
  *  ---------------
@@ -127,7 +127,24 @@
  *                      MPI_SCSIDEVPAGE1_CONF_EXTENDED_PARAMS_ENABLE.
  *                      Added new config page: CONFIG_PAGE_SCSI_DEVICE_3.
  *                      Modified MPI_FCPORTPAGE5_FLAGS_ defines.
- *  09-16-02 01.02.09   Added more MPI_SCSIDEVPAGE1_CONF_FORCE_PPR_MSG define.
+ *  09-16-02 01.02.09   Added MPI_SCSIDEVPAGE1_CONF_FORCE_PPR_MSG define.
+ *  11-15-02 01.02.10   Added ConnectedID defines for CONFIG_PAGE_SCSI_PORT_0.
+ *                      Added more Flags defines for CONFIG_PAGE_FC_PORT_1.
+ *                      Added more Flags defines for CONFIG_PAGE_FC_DEVICE_0.
+ *  04-01-03 01.02.11   Added RR_TOV field and additional Flags defines for
+ *                      CONFIG_PAGE_FC_PORT_1.
+ *                      Added define MPI_FCPORTPAGE5_FLAGS_DISABLE to disable
+ *                      an alias.
+ *                      Added more device id defines.
+ *  06-26-03 01.02.12   Added MPI_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID define.
+ *                      Added TargetConfig and IDConfig fields to
+ *                      CONFIG_PAGE_SCSI_PORT_1.
+ *                      Added more PortFlags defines for CONFIG_PAGE_SCSI_PORT_2
+ *                      to control DV.
+ *                      Added more Flags defines for CONFIG_PAGE_FC_PORT_1.
+ *                      In CONFIG_PAGE_FC_DEVICE_0, replaced Reserved1 field
+ *                      with ADISCHardALPA.
+ *                      Added MPI_FC_DEVICE_PAGE0_PROT_FCP_RETRY define.
  *  --------------------------------------------------------------------------
  */
 
@@ -159,6 +176,19 @@
 } ConfigPageHeaderUnion, MPI_POINTER pConfigPageHeaderUnion,
   fCONFIG_PAGE_HEADER_UNION, MPI_POINTER PTR_CONFIG_PAGE_HEADER_UNION;
 
+typedef struct _CONFIG_EXTENDED_PAGE_HEADER
+{
+    U8                  PageVersion;                /* 00h */
+    U8                  Reserved1;                  /* 01h */
+    U8                  PageNumber;                 /* 02h */
+    U8                  PageType;                   /* 03h */
+    U16                 ExtPageLength;              /* 04h */
+    U8                  ExtPageType;                /* 06h */
+    U8                  Reserved2;                  /* 07h */
+} fCONFIG_EXTENDED_PAGE_HEADER, MPI_POINTER PTR_CONFIG_EXTENDED_PAGE_HEADER,
+  ConfigExtendedPageHeader_t, MPI_POINTER pConfigExtendedPageHeader_t;
+
+
 
 /****************************************************************************
 *   PageType field values
@@ -180,12 +210,23 @@
 #define MPI_CONFIG_PAGETYPE_RAID_VOLUME             (0x08)
 #define MPI_CONFIG_PAGETYPE_MANUFACTURING           (0x09)
 #define MPI_CONFIG_PAGETYPE_RAID_PHYSDISK           (0x0A)
+#define MPI_CONFIG_PAGETYPE_INBAND                  (0x0B)
+#define MPI_CONFIG_PAGETYPE_EXTENDED                (0x0F)
 #define MPI_CONFIG_PAGETYPE_MASK                    (0x0F)
 
 #define MPI_CONFIG_TYPENUM_MASK                     (0x0FFF)
 
 
 /****************************************************************************
+*   ExtPageType field values
+****************************************************************************/
+#define MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT          (0x10)
+#define MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER         (0x11)
+#define MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE           (0x12)
+#define MPI_CONFIG_EXTPAGETYPE_SAS_PHY              (0x13)
+
+
+/****************************************************************************
 *   PageAddress field values
 ****************************************************************************/
 #define MPI_SCSI_PORT_PGAD_PORT_MASK                (0x000000FF)
@@ -219,6 +260,24 @@
 #define MPI_PHYSDISK_PGAD_PHYSDISKNUM_MASK          (0x000000FF)
 #define MPI_PHYSDISK_PGAD_PHYSDISKNUM_SHIFT         (0)
 
+#define MPI_SAS_DEVICE_PGAD_FORM_MASK               (0xF0000000)
+#define MPI_SAS_DEVICE_PGAD_FORM_SHIFT              (28)
+#define MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE    (0x00000000)
+#define MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID      (0x00000001)
+#define MPI_SAS_DEVICE_PGAD_FORM_HANDLE             (0x00000002)
+#define MPI_SAS_DEVICE_PGAD_GNH_HANDLE_MASK         (0x0000FFFF)
+#define MPI_SAS_DEVICE_PGAD_GNH_HANDLE_SHIFT        (0)
+#define MPI_SAS_DEVICE_PGAD_BT_BUS_MASK             (0x0000FF00)
+#define MPI_SAS_DEVICE_PGAD_BT_BUS_SHIFT            (8)
+#define MPI_SAS_DEVICE_PGAD_BT_TID_MASK             (0x000000FF)
+#define MPI_SAS_DEVICE_PGAD_BT_TID_SHIFT            (0)
+#define MPI_SAS_DEVICE_PGAD_H_HANDLE_MASK           (0x0000FFFF)
+#define MPI_SAS_DEVICE_PGAD_H_HANDLE_SHIFT          (0)
+
+#define MPI_SAS_PHY_PGAD_PHY_NUMBER_MASK            (0x00FF0000)
+#define MPI_SAS_PHY_PGAD_PHY_NUMBER_SHIFT           (16)
+#define MPI_SAS_PHY_PGAD_DEVHANDLE_MASK             (0x0000FFFF)
+#define MPI_SAS_PHY_PGAD_DEVHANDLE_SHIFT            (0)
 
 
 /****************************************************************************
@@ -230,7 +289,8 @@
     U8                      Reserved;                   /* 01h */
     U8                      ChainOffset;                /* 02h */
     U8                      Function;                   /* 03h */
-    U8                      Reserved1[3];               /* 04h */
+    U16                     ExtPageLength;              /* 04h */
+    U8                      ExtPageType;                /* 06h */
     U8                      MsgFlags;                   /* 07h */
     U32                     MsgContext;                 /* 08h */
     U8                      Reserved2[8];               /* 0Ch */
@@ -260,7 +320,8 @@
     U8                      Reserved;                   /* 01h */
     U8                      MsgLength;                  /* 02h */
     U8                      Function;                   /* 03h */
-    U8                      Reserved1[3];               /* 04h */
+    U16                     ExtPageLength;              /* 04h */
+    U8                      ExtPageType;                /* 06h */
     U8                      MsgFlags;                   /* 07h */
     U32                     MsgContext;                 /* 08h */
     U8                      Reserved2[2];               /* 0Ch */
@@ -281,23 +342,22 @@
 /****************************************************************************
 *   Manufacturing Config pages
 ****************************************************************************/
+#define MPI_MANUFACTPAGE_VENDORID_LSILOGIC          (0x1000)
+/* Fibre Channel */
 #define MPI_MANUFACTPAGE_DEVICEID_FC909             (0x0621)
 #define MPI_MANUFACTPAGE_DEVICEID_FC919             (0x0624)
 #define MPI_MANUFACTPAGE_DEVICEID_FC929             (0x0622)
 #define MPI_MANUFACTPAGE_DEVICEID_FC919X            (0x0628)
 #define MPI_MANUFACTPAGE_DEVICEID_FC929X            (0x0626)
-
+/* SCSI */
 #define MPI_MANUFACTPAGE_DEVID_53C1030              (0x0030)
 #define MPI_MANUFACTPAGE_DEVID_53C1030ZC            (0x0031)
 #define MPI_MANUFACTPAGE_DEVID_1030_53C1035         (0x0032)
 #define MPI_MANUFACTPAGE_DEVID_1030ZC_53C1035       (0x0033)
 #define MPI_MANUFACTPAGE_DEVID_53C1035              (0x0040)
 #define MPI_MANUFACTPAGE_DEVID_53C1035ZC            (0x0041)
-
-#define MPI_MANUFACTPAGE_DEVID_SA2010               (0x0804)
-#define MPI_MANUFACTPAGE_DEVID_SA2010ZC             (0x0805)
-#define MPI_MANUFACTPAGE_DEVID_SA2020               (0x0806)
-#define MPI_MANUFACTPAGE_DEVID_SA2020ZC             (0x0807)
+/* SAS */
+#define MPI_MANUFACTPAGE_DEVID_SAS1064              (0x0050)
 
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_0
@@ -381,8 +441,8 @@
     U8                              InfoOffset1;        /* 0Ah */
     U8                              InfoSize1;          /* 0Bh */
     U8                              InquirySize;        /* 0Ch */
-    U8                              Reserved2;          /* 0Dh */
-    U16                             Reserved3;          /* 0Eh */
+    U8                              Flags;              /* 0Dh */
+    U16                             Reserved2;          /* 0Eh */
     U8                              InquiryData[56];    /* 10h */
     U32                             ISVolumeSettings;   /* 48h */
     U32                             IMEVolumeSettings;  /* 4Ch */
@@ -390,7 +450,30 @@
 } fCONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,
   ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t;
 
-#define MPI_MANUFACTURING4_PAGEVERSION                  (0x00)
+#define MPI_MANUFACTURING4_PAGEVERSION                  (0x01)
+
+/* defines for the Flags field */
+#define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA                 (0x01)
+
+
+typedef struct _CONFIG_PAGE_MANUFACTURING_5
+{
+    fCONFIG_PAGE_HEADER              Header;             /* 00h */
+    U64                             BaseWWID;           /* 04h */
+} fCONFIG_PAGE_MANUFACTURING_5, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_5,
+  ManufacturingPage5_t, MPI_POINTER pManufacturingPage5_t;
+
+#define MPI_MANUFACTURING5_PAGEVERSION                  (0x00)
+
+
+typedef struct _CONFIG_PAGE_MANUFACTURING_6
+{
+    fCONFIG_PAGE_HEADER              Header;             /* 00h */
+    U32                             ProductSpecificInfo;/* 04h */
+} fCONFIG_PAGE_MANUFACTURING_6, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_6,
+  ManufacturingPage6_t, MPI_POINTER pManufacturingPage6_t;
+
+#define MPI_MANUFACTURING6_PAGEVERSION                  (0x00)
 
 
 /****************************************************************************
@@ -414,16 +497,18 @@
 } fCONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1,
   IOUnitPage1_t, MPI_POINTER pIOUnitPage1_t;
 
-#define MPI_IOUNITPAGE1_PAGEVERSION                     (0x00)
+#define MPI_IOUNITPAGE1_PAGEVERSION                     (0x01)
 
 /* IO Unit Page 1 Flags defines */
-
 #define MPI_IOUNITPAGE1_MULTI_FUNCTION                  (0x00000000)
 #define MPI_IOUNITPAGE1_SINGLE_FUNCTION                 (0x00000001)
 #define MPI_IOUNITPAGE1_MULTI_PATHING                   (0x00000002)
 #define MPI_IOUNITPAGE1_SINGLE_PATHING                  (0x00000000)
+#define MPI_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID         (0x00000004)
+#define MPI_IOUNITPAGE1_DISABLE_QUEUE_FULL_HANDLING     (0x00000020)
 #define MPI_IOUNITPAGE1_DISABLE_IR                      (0x00000040)
 #define MPI_IOUNITPAGE1_FORCE_32                        (0x00000080)
+#define MPI_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE        (0x00000100)
 
 
 typedef struct _MPI_ADAPTER_INFO
@@ -453,6 +538,11 @@
 #define MPI_IOUNITPAGE2_FLAGS_COLOR_VIDEO_DISABLE       (0x00000008)
 #define MPI_IOUNITPAGE2_FLAGS_DONT_HOOK_INT_40          (0x00000010)
 
+#define MPI_IOUNITPAGE2_FLAGS_DEV_LIST_DISPLAY_MASK     (0x000000E0)
+#define MPI_IOUNITPAGE2_FLAGS_INSTALLED_DEV_DISPLAY     (0x00000000)
+#define MPI_IOUNITPAGE2_FLAGS_ADAPTER_DISPLAY           (0x00000020)
+#define MPI_IOUNITPAGE2_FLAGS_ADAPTER_DEV_DISPLAY       (0x00000040)
+
 
 /*
  * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
@@ -515,6 +605,12 @@
 
 #define MPI_IOCPAGE1_PAGEVERSION                        (0x01)
 
+/* defines for the Flags field */
+#define MPI_IOCPAGE1_EEDP_HOST_SUPPORTS_DIF             (0x08000000)
+#define MPI_IOCPAGE1_EEDP_MODE_MASK                     (0x07000000)
+#define MPI_IOCPAGE1_EEDP_MODE_OFF                      (0x00000000)
+#define MPI_IOCPAGE1_EEDP_MODE_T10                      (0x01000000)
+#define MPI_IOCPAGE1_EEDP_MODE_LSI_1                    (0x02000000)
 #define MPI_IOCPAGE1_REPLY_COALESCING                   (0x00000001)
 
 #define MPI_IOCPAGE1_PCISLOTNUM_UNKNOWN                 (0xFF)
@@ -655,7 +751,7 @@
 
 typedef struct _CONFIG_PAGE_IOC_5
 {
-    fCONFIG_PAGE_HEADER         Header;                         /* 00h */
+    fCONFIG_PAGE_HEADER          Header;                         /* 00h */
     U32                         Reserved1;                      /* 04h */
     U8                          NumHotSpares;                   /* 08h */
     U8                          Reserved2;                      /* 09h */
@@ -667,6 +763,57 @@
 #define MPI_IOCPAGE5_PAGEVERSION                        (0x00)
 
 
+/****************************************************************************
+*   BIOS Port Config Pages
+****************************************************************************/
+
+typedef struct _CONFIG_PAGE_BIOS_1
+{
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     BiosOptions;                /* 04h */
+    U32                     IOCSettings;                /* 08h */
+    U32                     Reserved1;                  /* 0Ch */
+    U32                     DeviceSettings;             /* 10h */
+    U16                     NumberOfDevices;            /* 14h */
+    U16                     Reserved2;                  /* 16h */
+    U16                     IOTimeoutBlockDevicesNonRM; /* 18h */
+    U16                     IOTimeoutSequential;        /* 1Ah */
+    U16                     IOTimeoutOther;             /* 1Ch */
+    U16                     IOTimeoutBlockDevicesRM;    /* 1Eh */
+} fCONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1,
+  BIOSPage1_t, MPI_POINTER pBIOSPage1_t;
+
+#define MPI_BIOSPAGE1_PAGEVERSION                       (0x00)
+
+/* values for the BiosOptions field */
+#define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE                (0x00000400)
+#define MPI_BIOSPAGE1_OPTIONS_FC_ENABLE                 (0x00000200)
+#define MPI_BIOSPAGE1_OPTIONS_SAS_ENABLE                (0x00000100)
+#define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS              (0x00000001)
+
+/* values for the IOCSettings field */
+#define MPI_BIOSPAGE1_IOCSET_MASK_SPINUP_DELAY          (0x00000F00)
+#define MPI_BIOSPAGE1_IOCSET_SHIFT_SPINUP_DELAY         (8)
+
+#define MPI_BIOSPAGE1_IOCSET_MASK_RM_SETTING            (0x000000C0)
+#define MPI_BIOSPAGE1_IOCSET_NONE_RM_SETTING            (0x00000000)
+#define MPI_BIOSPAGE1_IOCSET_BOOT_RM_SETTING            (0x00000040)
+#define MPI_BIOSPAGE1_IOCSET_MEDIA_RM_SETTING           (0x00000080)
+
+#define MPI_BIOSPAGE1_IOCSET_MASK_ADAPTER_SUPPORT       (0x00000030)
+#define MPI_BIOSPAGE1_IOCSET_NO_SUPPORT                 (0x00000000)
+#define MPI_BIOSPAGE1_IOCSET_BIOS_SUPPORT               (0x00000010)
+#define MPI_BIOSPAGE1_IOCSET_OS_SUPPORT                 (0x00000020)
+#define MPI_BIOSPAGE1_IOCSET_ALL_SUPPORT                (0x00000030)
+
+#define MPI_BIOSPAGE1_IOCSET_ALTERNATE_CHS              (0x00000008)
+
+/* values for the DeviceSettings field */
+#define MPI_BIOSPAGE1_DEVSET_DISABLE_SEQ_LUN            (0x00000008)
+#define MPI_BIOSPAGE1_DEVSET_DISABLE_RM_LUN             (0x00000004)
+#define MPI_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN         (0x00000002)
+#define MPI_BIOSPAGE1_DEVSET_DISABLE_OTHER_LUN          (0x00000001)
+
 
 /****************************************************************************
 *   SCSI Port Config Pages
@@ -686,7 +833,27 @@
 #define MPI_SCSIPORTPAGE0_CAP_DT                        (0x00000002)
 #define MPI_SCSIPORTPAGE0_CAP_QAS                       (0x00000004)
 #define MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK      (0x0000FF00)
+#define MPI_SCSIPORTPAGE0_SYNC_ASYNC                    (0x00)
+#define MPI_SCSIPORTPAGE0_SYNC_5                        (0x32)
+#define MPI_SCSIPORTPAGE0_SYNC_10                       (0x19)
+#define MPI_SCSIPORTPAGE0_SYNC_20                       (0x0C)
+#define MPI_SCSIPORTPAGE0_SYNC_33_33                    (0x0B)
+#define MPI_SCSIPORTPAGE0_SYNC_40                       (0x0A)
+#define MPI_SCSIPORTPAGE0_SYNC_80                       (0x09)
+#define MPI_SCSIPORTPAGE0_SYNC_160                      (0x08)
+#define MPI_SCSIPORTPAGE0_SYNC_UNKNOWN                  (0xFF)
+
+#define MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD     (8)
+#define MPI_SCSIPORTPAGE0_CAP_GET_MIN_SYNC_PERIOD(Cap)      \
+    (  ((Cap) & MPI_SCSIPORTPAGE0_CAP_MASK_MIN_SYNC_PERIOD) \
+    >> MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD          \
+    )
 #define MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK      (0x00FF0000)
+#define MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET     (16)
+#define MPI_SCSIPORTPAGE0_CAP_GET_MAX_SYNC_OFFSET(Cap)      \
+    (  ((Cap) & MPI_SCSIPORTPAGE0_CAP_MASK_MAX_SYNC_OFFSET) \
+    >> MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET          \
+    )
 #define MPI_SCSIPORTPAGE0_CAP_WIDE                      (0x20000000)
 #define MPI_SCSIPORTPAGE0_CAP_AIP                       (0x80000000)
 
@@ -694,6 +861,10 @@
 #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD                (0x01)
 #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE                 (0x02)
 #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_LVD                (0x03)
+#define MPI_SCSIPORTPAGE0_PHY_MASK_CONNECTED_ID         (0xFF000000)
+#define MPI_SCSIPORTPAGE0_PHY_SHIFT_CONNECTED_ID        (24)
+#define MPI_SCSIPORTPAGE0_PHY_BUS_FREE_CONNECTED_ID     (0xFE)
+#define MPI_SCSIPORTPAGE0_PHY_UNKNOWN_CONNECTED_ID      (0xFF)
 
 
 typedef struct _CONFIG_PAGE_SCSI_PORT_1
@@ -701,13 +872,22 @@
     fCONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Configuration;              /* 04h */
     U32                     OnBusTimerValue;            /* 08h */
+    U8                      TargetConfig;               /* 0Ch */
+    U8                      Reserved1;                  /* 0Dh */
+    U16                     IDConfig;                   /* 0Eh */
 } fCONFIG_PAGE_SCSI_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_1,
   SCSIPortPage1_t, MPI_POINTER pSCSIPortPage1_t;
 
-#define MPI_SCSIPORTPAGE1_PAGEVERSION                   (0x02)
+#define MPI_SCSIPORTPAGE1_PAGEVERSION                   (0x03)
 
+/* Configuration values */
 #define MPI_SCSIPORTPAGE1_CFG_PORT_SCSI_ID_MASK         (0x000000FF)
 #define MPI_SCSIPORTPAGE1_CFG_PORT_RESPONSE_ID_MASK     (0xFFFF0000)
+#define MPI_SCSIPORTPAGE1_CFG_SHIFT_PORT_RESPONSE_ID    (16)
+
+/* TargetConfig values */
+#define MPI_SCSIPORTPAGE1_TARGCONFIG_TARG_ONLY        (0x01)
+#define MPI_SCSIPORTPAGE1_TARGCONFIG_INIT_TARG        (0x02)
 
 
 typedef struct _MPI_DEVICE_INFO
@@ -727,13 +907,21 @@
 } fCONFIG_PAGE_SCSI_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_2,
   SCSIPortPage2_t, MPI_POINTER pSCSIPortPage2_t;
 
-#define MPI_SCSIPORTPAGE2_PAGEVERSION                       (0x01)
+#define MPI_SCSIPORTPAGE2_PAGEVERSION                       (0x02)
 
+/* PortFlags values */
 #define MPI_SCSIPORTPAGE2_PORT_FLAGS_SCAN_HIGH_TO_LOW       (0x00000001)
 #define MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET       (0x00000004)
 #define MPI_SCSIPORTPAGE2_PORT_FLAGS_ALTERNATE_CHS          (0x00000008)
 #define MPI_SCSIPORTPAGE2_PORT_FLAGS_TERMINATION_DISABLE    (0x00000010)
 
+#define MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK                (0x00000060)
+#define MPI_SCSIPORTPAGE2_PORT_FLAGS_FULL_DV                (0x00000000)
+#define MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY          (0x00000020)
+#define MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV                 (0x00000060)
+
+
+/* PortSettings values */
 #define MPI_SCSIPORTPAGE2_PORT_HOST_ID_MASK                 (0x0000000F)
 #define MPI_SCSIPORTPAGE2_PORT_MASK_INIT_HBA                (0x00000030)
 #define MPI_SCSIPORTPAGE2_PORT_DISABLE_INIT_HBA             (0x00000000)
@@ -741,7 +929,11 @@
 #define MPI_SCSIPORTPAGE2_PORT_OS_INIT_HBA                  (0x00000020)
 #define MPI_SCSIPORTPAGE2_PORT_BIOS_OS_INIT_HBA             (0x00000030)
 #define MPI_SCSIPORTPAGE2_PORT_REMOVABLE_MEDIA              (0x000000C0)
+#define MPI_SCSIPORTPAGE2_PORT_RM_NONE                      (0x00000000)
+#define MPI_SCSIPORTPAGE2_PORT_RM_BOOT_ONLY                 (0x00000040)
+#define MPI_SCSIPORTPAGE2_PORT_RM_WITH_MEDIA                (0x00000080)
 #define MPI_SCSIPORTPAGE2_PORT_SPINUP_DELAY_MASK            (0x00000F00)
+#define MPI_SCSIPORTPAGE2_PORT_SHIFT_SPINUP_DELAY           (8)
 #define MPI_SCSIPORTPAGE2_PORT_MASK_NEGO_MASTER_SETTINGS    (0x00003000)
 #define MPI_SCSIPORTPAGE2_PORT_NEGO_MASTER_SETTINGS         (0x00000000)
 #define MPI_SCSIPORTPAGE2_PORT_NONE_MASTER_SETTINGS         (0x00001000)
@@ -778,7 +970,9 @@
 #define MPI_SCSIDEVPAGE0_NP_RTI                         (0x00000040)
 #define MPI_SCSIDEVPAGE0_NP_PCOMP_EN                    (0x00000080)
 #define MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK        (0x0000FF00)
+#define MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_PERIOD           (8)
 #define MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK        (0x00FF0000)
+#define MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_OFFSET           (16)
 #define MPI_SCSIDEVPAGE0_NP_WIDE                        (0x20000000)
 #define MPI_SCSIDEVPAGE0_NP_AIP                         (0x80000000)
 
@@ -808,7 +1002,9 @@
 #define MPI_SCSIDEVPAGE1_RP_RTI                         (0x00000040)
 #define MPI_SCSIDEVPAGE1_RP_PCOMP_EN                    (0x00000080)
 #define MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK        (0x0000FF00)
+#define MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD       (8)
 #define MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK        (0x00FF0000)
+#define MPI_SCSIDEVPAGE1_RP_SHIFT_MAX_SYNC_OFFSET       (16)
 #define MPI_SCSIDEVPAGE1_RP_WIDE                        (0x20000000)
 #define MPI_SCSIDEVPAGE1_RP_AIP                         (0x80000000)
 
@@ -915,7 +1111,7 @@
 
 #define MPI_FCPORTPAGE0_FLAGS_ALIAS_ALPA_SUPPORTED      (0x00000010)
 #define MPI_FCPORTPAGE0_FLAGS_ALIAS_WWN_SUPPORTED       (0x00000020)
-#define MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID          (0x00000030)
+#define MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID          (0x00000040)
 
 #define MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK          (0x00000F00)
 #define MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT            (0x00000000)
@@ -954,13 +1150,19 @@
 #define MPI_FCPORTPAGE0_SUPPORT_CLASS_2                 (0x00000002)
 #define MPI_FCPORTPAGE0_SUPPORT_CLASS_3                 (0x00000004)
 
-#define MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED             (0x00000001) /* (SNIA)HBA_PORTSPEED_1GBIT 1  1 GBit/sec  */
-#define MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED             (0x00000002) /* (SNIA)HBA_PORTSPEED_2GBIT 2  2 GBit/sec  */
-#define MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED            (0x00000004) /* (SNIA)HBA_PORTSPEED_10GBIT 4 10 GBit/sec */
+#define MPI_FCPORTPAGE0_SUPPORT_SPEED_UKNOWN            (0x00000000) /* (SNIA)HBA_PORTSPEED_UNKNOWN 0   Unknown - transceiver incapable of reporting */
+#define MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED             (0x00000001) /* (SNIA)HBA_PORTSPEED_1GBIT   1   1 GBit/sec */
+#define MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED             (0x00000002) /* (SNIA)HBA_PORTSPEED_2GBIT   2   2 GBit/sec */
+#define MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED            (0x00000004) /* (SNIA)HBA_PORTSPEED_10GBIT  4  10 GBit/sec */
+#define MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED             (0x00000008) /* (SNIA)HBA_PORTSPEED_4GBIT   8   4 GBit/sec */
 
+#define MPI_FCPORTPAGE0_CURRENT_SPEED_UKNOWN            MPI_FCPORTPAGE0_SUPPORT_SPEED_UKNOWN
 #define MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT             MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED
 #define MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT             MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED
 #define MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT            MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED
+#define MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT             MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED
+#define MPI_FCPORTPAGE0_CURRENT_SPEED_NOT_NEGOTIATED    (0x00008000)        /* (SNIA)HBA_PORTSPEED_NOT_NEGOTIATED (1<<15) Speed not established */
+
 
 
 typedef struct _CONFIG_PAGE_FC_PORT_1
@@ -974,15 +1176,25 @@
     U8                      TopologyConfig;             /* 1Ah */
     U8                      AltConnector;               /* 1Bh */
     U8                      NumRequestedAliases;        /* 1Ch */
-    U8                      Reserved1;                  /* 1Dh */
-    U16                     Reserved2;                  /* 1Eh */
+    U8                      RR_TOV;                     /* 1Dh */
+    U8                      InitiatorDeviceTimeout;     /* 1Eh */
+    U8                      InitiatorIoPendTimeout;     /* 1Fh */
 } fCONFIG_PAGE_FC_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_1,
   FCPortPage1_t, MPI_POINTER pFCPortPage1_t;
 
-#define MPI_FCPORTPAGE1_PAGEVERSION                     (0x04)
+#define MPI_FCPORTPAGE1_PAGEVERSION                     (0x06)
 
 #define MPI_FCPORTPAGE1_FLAGS_EXT_FCP_STATUS_EN         (0x08000000)
 #define MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY     (0x04000000)
+#define MPI_FCPORTPAGE1_FLAGS_FORCE_USE_NOSEEPROM_WWNS  (0x02000000)
+#define MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS     (0x01000000)
+#define MPI_FCPORTPAGE1_FLAGS_TARGET_MODE_OXID          (0x00800000)
+#define MPI_FCPORTPAGE1_FLAGS_PORT_OFFLINE              (0x00400000)
+#define MPI_FCPORTPAGE1_FLAGS_SOFT_ALPA_FALLBACK        (0x00200000)
+#define MPI_FCPORTPAGE1_FLAGS_MASK_RR_TOV_UNITS         (0x00000070)
+#define MPI_FCPORTPAGE1_FLAGS_SUPPRESS_PROT_REG         (0x00000008)
+#define MPI_FCPORTPAGE1_FLAGS_PLOGI_ON_LOGO             (0x00000004)
+#define MPI_FCPORTPAGE1_FLAGS_MAINTAIN_LOGINS           (0x00000002)
 #define MPI_FCPORTPAGE1_FLAGS_SORT_BY_DID               (0x00000001)
 #define MPI_FCPORTPAGE1_FLAGS_SORT_BY_WWN               (0x00000000)
 
@@ -993,6 +1205,11 @@
 #define MPI_FCPORTPAGE1_FLAGS_PROT_LAN                  ((U32)MPI_PORTFACTS_PROTOCOL_LAN << MPI_FCPORTPAGE1_FLAGS_PROT_SHIFT)
 #define MPI_FCPORTPAGE1_FLAGS_PROT_LOGBUSADDR           ((U32)MPI_PORTFACTS_PROTOCOL_LOGBUSADDR << MPI_FCPORTPAGE1_FLAGS_PROT_SHIFT)
 
+#define MPI_FCPORTPAGE1_FLAGS_NONE_RR_TOV_UNITS         (0x00000000)
+#define MPI_FCPORTPAGE1_FLAGS_THOUSANDTH_RR_TOV_UNITS   (0x00000010)
+#define MPI_FCPORTPAGE1_FLAGS_TENTH_RR_TOV_UNITS        (0x00000030)
+#define MPI_FCPORTPAGE1_FLAGS_TEN_RR_TOV_UNITS          (0x00000050)
+
 #define MPI_FCPORTPAGE1_HARD_ALPA_NOT_USED              (0xFF)
 
 #define MPI_FCPORTPAGE1_LCONFIG_SPEED_MASK              (0x0F)
@@ -1009,6 +1226,8 @@
 
 #define MPI_FCPORTPAGE1_ALT_CONN_UNKNOWN                (0x00)
 
+#define MPI_FCPORTPAGE1_INITIATOR_DEV_TIMEOUT_MASK      (0x7F)
+
 
 typedef struct _CONFIG_PAGE_FC_PORT_2
 {
@@ -1108,12 +1327,13 @@
 } fCONFIG_PAGE_FC_PORT_5, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5,
   FCPortPage5_t, MPI_POINTER pFCPortPage5_t;
 
-#define MPI_FCPORTPAGE5_PAGEVERSION                     (0x01)
+#define MPI_FCPORTPAGE5_PAGEVERSION                     (0x02)
 
 #define MPI_FCPORTPAGE5_FLAGS_ALPA_ACQUIRED             (0x01)
 #define MPI_FCPORTPAGE5_FLAGS_HARD_ALPA                 (0x02)
 #define MPI_FCPORTPAGE5_FLAGS_HARD_WWNN                 (0x04)
 #define MPI_FCPORTPAGE5_FLAGS_HARD_WWPN                 (0x08)
+#define MPI_FCPORTPAGE5_FLAGS_DISABLE                   (0x10)
 
 typedef struct _CONFIG_PAGE_FC_PORT_6
 {
@@ -1322,7 +1542,7 @@
     U8                      Flags;                      /* 19h */
     U16                     BBCredit;                   /* 1Ah */
     U16                     MaxRxFrameSize;             /* 1Ch */
-    U8                      Reserved1;                  /* 1Eh */
+    U8                      ADISCHardALPA;              /* 1Eh */
     U8                      PortNumber;                 /* 1Fh */
     U8                      FcPhLowestVersion;          /* 20h */
     U8                      FcPhHighestVersion;         /* 21h */
@@ -1331,13 +1551,16 @@
 } fCONFIG_PAGE_FC_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_FC_DEVICE_0,
   FCDevicePage0_t, MPI_POINTER pFCDevicePage0_t;
 
-#define MPI_FC_DEVICE_PAGE0_PAGEVERSION                 (0x02)
+#define MPI_FC_DEVICE_PAGE0_PAGEVERSION                 (0x03)
 
 #define MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID    (0x01)
+#define MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID         (0x02)
+#define MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID          (0x04)
 
 #define MPI_FC_DEVICE_PAGE0_PROT_IP                     (0x01)
 #define MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET             (0x02)
 #define MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR          (0x04)
+#define MPI_FC_DEVICE_PAGE0_PROT_FCP_RETRY              (0x08)
 
 #define MPI_FC_DEVICE_PAGE0_PGAD_PORT_MASK      (MPI_FC_DEVICE_PGAD_PORT_MASK)
 #define MPI_FC_DEVICE_PAGE0_PGAD_FORM_MASK      (MPI_FC_DEVICE_PGAD_FORM_MASK)
@@ -1348,6 +1571,7 @@
 #define MPI_FC_DEVICE_PAGE0_PGAD_BUS_SHIFT      (MPI_FC_DEVICE_PGAD_BT_BUS_SHIFT)
 #define MPI_FC_DEVICE_PAGE0_PGAD_TID_MASK       (MPI_FC_DEVICE_PGAD_BT_TID_MASK)
 
+#define MPI_FC_DEVICE_PAGE0_HARD_ALPA_UNKNOWN   (0xFF)
 
 /****************************************************************************
 *   RAID Volume Config Pages
@@ -1564,6 +1788,318 @@
 
 #define MPI_LAN_PAGE1_DEV_STATE_RESET                   (0x00)
 #define MPI_LAN_PAGE1_DEV_STATE_OPERATIONAL             (0x01)
+
+
+/****************************************************************************
+*   Inband Config Pages
+****************************************************************************/
+
+typedef struct _CONFIG_PAGE_INBAND_0
+{
+    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    MPI_VERSION_FORMAT      InbandVersion;              /* 04h */
+    U16                     MaximumBuffers;             /* 08h */
+    U16                     Reserved1;                  /* 0Ah */
+} fCONFIG_PAGE_INBAND_0, MPI_POINTER PTR_CONFIG_PAGE_INBAND_0,
+  InbandPage0_t, MPI_POINTER pInbandPage0_t;
+
+#define MPI_INBAND_PAGEVERSION          (0x00)
+
+
+
+/****************************************************************************
+*   SAS IO Unit Config Pages
+****************************************************************************/
+
+typedef struct _MPI_SAS_IO_UNIT0_PHY_DATA
+{
+    U8          Port;                   /* 00h */
+    U8          PortFlags;              /* 01h */
+    U8          PhyFlags;               /* 02h */
+    U8          NegotiatedLinkRate;     /* 03h */
+    U32         ControllerPhyDeviceInfo;/* 04h */
+    U16         AttachedDeviceHandle;   /* 08h */
+    U16         ControllerDevHandle;    /* 0Ah */
+    U32         Reserved2;              /* 0Ch */
+} MPI_SAS_IO_UNIT0_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT0_PHY_DATA,
+  SasIOUnit0PhyData, MPI_POINTER pSasIOUnit0PhyData;
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.PageLength at runtime.
+ */
+#ifndef MPI_SAS_IOUNIT0_PHY_MAX
+#define MPI_SAS_IOUNIT0_PHY_MAX         (1)
+#endif
+
+typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
+{
+    fCONFIG_EXTENDED_PAGE_HEADER     Header;                             /* 00h */
+    U32                             Reserved1;                          /* 08h */
+    U8                              NumPhys;                            /* 0Ch */
+    U8                              Reserved2;                          /* 0Dh */
+    U16                             Reserved3;                          /* 0Eh */
+    MPI_SAS_IO_UNIT0_PHY_DATA       PhyData[MPI_SAS_IOUNIT0_PHY_MAX];   /* 10h */
+} fCONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0,
+  SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t;
+
+#define MPI_SASIOUNITPAGE0_PAGEVERSION      (0x00)
+
+/* values for SAS IO Unit Page 0 PortFlags */
+#define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS    (0x08)
+#define MPI_SAS_IOUNIT0_PORT_FLAGS_0_TARGET_IOC_NUM         (0x00)
+#define MPI_SAS_IOUNIT0_PORT_FLAGS_1_TARGET_IOC_NUM         (0x04)
+#define MPI_SAS_IOUNIT0_PORT_FLAGS_WAIT_FOR_PORTENABLE      (0x02)
+#define MPI_SAS_IOUNIT0_PORT_FLAGS_AUTO_PORT_CONFIG         (0x01)
+
+/* values for SAS IO Unit Page 0 PhyFlags */
+#define MPI_SAS_IOUNIT0_PHY_FLAGS_PHY_DISABLED              (0x04)
+#define MPI_SAS_IOUNIT0_PHY_FLAGS_TX_INVERT                 (0x02)
+#define MPI_SAS_IOUNIT0_PHY_FLAGS_RX_INVERT                 (0x01)
+
+/* values for SAS IO Unit Page 0 NegotiatedLinkRate */
+#define MPI_SAS_IOUNIT0_RATE_UNKNOWN                        (0x00)
+#define MPI_SAS_IOUNIT0_RATE_PHY_DISABLED                   (0x01)
+#define MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION       (0x02)
+#define MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE              (0x03)
+#define MPI_SAS_IOUNIT0_RATE_1_5                            (0x08)
+#define MPI_SAS_IOUNIT0_RATE_3_0                            (0x09)
+
+/* see mpi_sas.h for values for SAS IO Unit Page 0 ControllerPhyDeviceInfo values */
+
+
+typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA
+{
+    U8          Port;                   /* 00h */
+    U8          PortFlags;              /* 01h */
+    U8          PhyFlags;               /* 02h */
+    U8          MaxMinLinkRate;         /* 03h */
+    U32         ControllerPhyDeviceInfo;/* 04h */
+    U32         Reserved1;              /* 08h */
+} MPI_SAS_IO_UNIT1_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT1_PHY_DATA,
+  SasIOUnit1PhyData, MPI_POINTER pSasIOUnit1PhyData;
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.PageLength at runtime.
+ */
+#ifndef MPI_SAS_IOUNIT1_PHY_MAX
+#define MPI_SAS_IOUNIT1_PHY_MAX         (1)
+#endif
+
+typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
+{
+    fCONFIG_EXTENDED_PAGE_HEADER Header;                             /* 00h */
+    U32                         Reserved1;                          /* 08h */
+    U8                          NumPhys;                            /* 0Ch */
+    U8                          Reserved2;                          /* 0Dh */
+    U16                         Reserved3;                          /* 0Eh */
+    MPI_SAS_IO_UNIT1_PHY_DATA   PhyData[MPI_SAS_IOUNIT1_PHY_MAX];   /* 10h */
+} fCONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1,
+  SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t;
+
+#define MPI_SASIOUNITPAGE1_PAGEVERSION      (0x00)
+
+/* values for SAS IO Unit Page 0 PortFlags */
+#define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM         (0x00)
+#define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM         (0x04)
+#define MPI_SAS_IOUNIT1_PORT_FLAGS_WAIT_FOR_PORTENABLE      (0x02)
+#define MPI_SAS_IOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG         (0x01)
+
+/* values for SAS IO Unit Page 0 PhyFlags */
+#define MPI_SAS_IOUNIT1_PHY_FLAGS_PHY_DISABLE               (0x04)
+#define MPI_SAS_IOUNIT1_PHY_FLAGS_TX_INVERT                 (0x02)
+#define MPI_SAS_IOUNIT1_PHY_FLAGS_RX_INVERT                 (0x01)
+
+/* values for SAS IO Unit Page 0 MaxMinLinkRate */
+#define MPI_SAS_IOUNIT1_MAX_RATE_MASK                       (0xF0)
+#define MPI_SAS_IOUNIT1_MAX_RATE_1_5                        (0x80)
+#define MPI_SAS_IOUNIT1_MAX_RATE_3_0                        (0x90)
+#define MPI_SAS_IOUNIT1_MIN_RATE_MASK                       (0x0F)
+#define MPI_SAS_IOUNIT1_MIN_RATE_1_5                        (0x08)
+#define MPI_SAS_IOUNIT1_MIN_RATE_3_0                        (0x09)
+
+/* see mpi_sas.h for values for SAS IO Unit Page 1 ControllerPhyDeviceInfo values */
+
+
+typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
+{
+    fCONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
+    U32                                 Reserved1;              /* 08h */
+    U16                                 MaxPersistentIDs;       /* 0Ch */
+    U16                                 NumPersistentIDsUsed;   /* 0Eh */
+    U8                                  Status;                 /* 10h */
+    U8                                  Flags;                  /* 11h */
+    U16                                 Reserved2;              /* 12h */
+} fCONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2,
+  SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t;
+
+#define MPI_SASIOUNITPAGE2_PAGEVERSION      (0x00)
+
+/* values for SAS IO Unit Page 2 Status field */
+#define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02)
+#define MPI_SAS_IOUNIT2_STATUS_FULL_PERSISTENT_MAPPINGS     (0x01)
+
+/* values for SAS IO Unit Page 2 Flags field */
+#define MPI_SAS_IOUNIT2_FLAGS_DISABLE_PERSISTENT_MAPPINGS   (0x01)
+
+
+typedef struct _CONFIG_PAGE_SAS_IO_UNIT_3
+{
+    fCONFIG_EXTENDED_PAGE_HEADER Header;                         /* 00h */
+    U32                         Reserved1;                      /* 08h */
+    U32                         MaxInvalidDwordCount;           /* 0Ch */
+    U32                         InvalidDwordCountTime;          /* 10h */
+    U32                         MaxRunningDisparityErrorCount;  /* 14h */
+    U32                         RunningDisparityErrorTime;      /* 18h */
+    U32                         MaxLossDwordSynchCount;         /* 1Ch */
+    U32                         LossDwordSynchCountTime;        /* 20h */
+    U32                         MaxPhyResetProblemCount;        /* 24h */
+    U32                         PhyResetProblemTime;            /* 28h */
+} fCONFIG_PAGE_SAS_IO_UNIT_3, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_3,
+  SasIOUnitPage3_t, MPI_POINTER pSasIOUnitPage3_t;
+
+#define MPI_SASIOUNITPAGE3_PAGEVERSION      (0x00)
+
+
+typedef struct _CONFIG_PAGE_SAS_EXPANDER_0
+{
+    fCONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
+    U32                                 Reserved1;              /* 08h */
+    U64                                 SASAddress;             /* 0Ch */
+    U32                                 Reserved2;              /* 14h */
+    U16                                 DevHandle;              /* 18h */
+    U16                                 ParentDevHandle;        /* 1Ah */
+    U16                                 ExpanderChangeCount;    /* 1Ch */
+    U16                                 ExpanderRouteIndexes;   /* 1Eh */
+    U8                                  NumPhys;                /* 20h */
+    U8                                  SASLevel;               /* 21h */
+    U8                                  Flags;                  /* 22h */
+    U8                                  Reserved3;              /* 23h */
+} fCONFIG_PAGE_SAS_EXPANDER_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_0,
+  SasExpanderPage0_t, MPI_POINTER pSasExpanderPage0_t;
+
+#define MPI_SASEXPANDER0_PAGEVERSION        (0x00)
+
+/* values for SAS Expander Page 0 Flags field */
+#define MPI_SAS_EXPANDER0_FLAGS_ROUTE_TABLE_CONFIG      (0x02)
+#define MPI_SAS_EXPANDER0_FLAGS_CONFIG_IN_PROGRESS      (0x01)
+
+
+typedef struct _CONFIG_PAGE_SAS_DEVICE_0
+{
+    fCONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
+    U32                                 Reserved1;              /* 08h */
+    U64                                 SASAddress;             /* 0Ch */
+    U32                                 Reserved2;              /* 14h */
+    U16                                 DevHandle;              /* 18h */
+    U8                                  TargetID;               /* 1Ah */
+    U8                                  Bus;                    /* 1Bh */
+    U32                                 DeviceInfo;             /* 1Ch */
+    U16                                 Flags;                  /* 20h */
+    U8                                  PhysicalPort;           /* 22h */
+    U8                                  Reserved3;              /* 23h */
+} fCONFIG_PAGE_SAS_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_0,
+  SasDevicePage0_t, MPI_POINTER pSasDevicePage0_t;
+
+#define MPI_SASDEVICE0_PAGEVERSION          (0x00)
+
+/* values for SAS Device Page 0 Flags field */
+#define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT    (0x04)
+#define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED         (0x02)
+#define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT        (0x01)
+
+/* see mpi_sas.h for values for SAS Device Page 0 DeviceInfo values */
+
+
+typedef struct _CONFIG_PAGE_SAS_DEVICE_1
+{
+    fCONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
+    U32                                 Reserved1;              /* 08h */
+    U64                                 SASAddress;             /* 0Ch */
+    U32                                 Reserved2;              /* 14h */
+    U16                                 DevHandle;              /* 18h */
+    U8                                  TargetID;               /* 1Ah */
+    U8                                  Bus;                    /* 1Bh */
+    U8                                  InitialRegDeviceFIS[20];/* 1Ch */
+} fCONFIG_PAGE_SAS_DEVICE_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_1,
+  SasDevicePage1_t, MPI_POINTER pSasDevicePage1_t;
+
+#define MPI_SASDEVICE1_PAGEVERSION          (0x00)
+
+
+typedef struct _CONFIG_PAGE_SAS_PHY_0
+{
+    fCONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
+    U32                                 Reserved1;              /* 08h */
+    U64                                 SASAddress;             /* 0Ch */
+    U16                                 AttachedDevHandle;      /* 14h */
+    U8                                  AttachedPhyIdentifier;  /* 16h */
+    U8                                  Reserved2;              /* 17h */
+    U32                                 AttachedDeviceInfo;     /* 18h */
+    U8                                  ProgrammedLinkRate;     /* 20h */
+    U8                                  HwLinkRate;             /* 21h */
+    U8                                  ChangeCount;            /* 22h */
+    U8                                  Reserved3;              /* 23h */
+    U32                                 PhyInfo;                /* 24h */
+} fCONFIG_PAGE_SAS_PHY_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_0,
+  SasPhyPage0_t, MPI_POINTER pSasPhyPage0_t;
+
+#define MPI_SASPHY0_PAGEVERSION             (0x00)
+
+/* values for SAS PHY Page 0 ProgrammedLinkRate field */
+#define MPI_SAS_PHY0_PRATE_MAX_RATE_MASK                        (0xF0)
+#define MPI_SAS_PHY0_PRATE_MAX_RATE_NOT_PROGRAMMABLE            (0x00)
+#define MPI_SAS_PHY0_PRATE_MAX_RATE_1_5                         (0x80)
+#define MPI_SAS_PHY0_PRATE_MAX_RATE_3_0                         (0x90)
+#define MPI_SAS_PHY0_PRATE_MIN_RATE_MASK                        (0x0F)
+#define MPI_SAS_PHY0_PRATE_MIN_RATE_NOT_PROGRAMMABLE            (0x00)
+#define MPI_SAS_PHY0_PRATE_MIN_RATE_1_5                         (0x08)
+#define MPI_SAS_PHY0_PRATE_MIN_RATE_3_0                         (0x09)
+
+/* values for SAS PHY Page 0 HwLinkRate field */
+#define MPI_SAS_PHY0_HWRATE_MAX_RATE_MASK                       (0xF0)
+#define MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5                        (0x80)
+#define MPI_SAS_PHY0_HWRATE_MAX_RATE_3_0                        (0x90)
+#define MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK                       (0x0F)
+#define MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5                        (0x08)
+#define MPI_SAS_PHY0_HWRATE_MIN_RATE_3_0                        (0x09)
+
+/* values for SAS PHY Page 0 PhyInfo field */
+#define MPI_SAS_PHY0_PHYINFO_SATA_PORT_ACTIVE                   (0x00004000)
+#define MPI_SAS_PHY0_PHYINFO_SATA_PORT_SELECTOR                 (0x00002000)
+#define MPI_SAS_PHY0_PHYINFO_VIRTUAL_PHY                        (0x00001000)
+
+#define MPI_SAS_PHY0_PHYINFO_MASK_PARTIAL_PATHWAY_TIME          (0x00000F00)
+#define MPI_SAS_PHY0_PHYINFO_SHIFT_PARTIAL_PATHWAY_TIME         (8)
+
+#define MPI_SAS_PHY0_PHYINFO_MASK_ROUTING_ATTRIBUTE             (0x000000F0)
+#define MPI_SAS_PHY0_PHYINFO_DIRECT_ROUTING                     (0x00000000)
+#define MPI_SAS_PHY0_PHYINFO_SUBTRACTIVE_ROUTING                (0x00000010)
+#define MPI_SAS_PHY0_PHYINFO_TABLE_ROUTING                      (0x00000020)
+
+#define MPI_SAS_PHY0_PHYINFO_MASK_LINK_RATE                     (0x0000000F)
+#define MPI_SAS_PHY0_PHYINFO_UNKNOWN_LINK_RATE                  (0x00000000)
+#define MPI_SAS_PHY0_PHYINFO_PHY_DISABLED                       (0x00000001)
+#define MPI_SAS_PHY0_PHYINFO_NEGOTIATION_FAILED                 (0x00000002)
+#define MPI_SAS_PHY0_PHYINFO_SATA_OOB_COMPLETE                  (0x00000003)
+#define MPI_SAS_PHY0_PHYINFO_RATE_1_5                           (0x00000008)
+#define MPI_SAS_PHY0_PHYINFO_RATE_3_0                           (0x00000009)
+
+
+typedef struct _CONFIG_PAGE_SAS_PHY_1
+{
+    fCONFIG_EXTENDED_PAGE_HEADER Header;                     /* 00h */
+    U32                         Reserved1;                  /* 08h */
+    U32                         InvalidDwordCount;          /* 0Ch */
+    U32                         RunningDisparityErrorCount; /* 10h */
+    U32                         LossDwordSynchCount;        /* 14h */
+    U32                         PhyResetProblemCount;       /* 18h */
+} fCONFIG_PAGE_SAS_PHY_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_1,
+  SasPhyPage1_t, MPI_POINTER pSasPhyPage1_t;
+
+#define MPI_SASPHY1_PAGEVERSION             (0x00)
+
 
 #endif
 
diff -Nru a/drivers/message/fusion/lsi/mpi_fc.h b/drivers/message/fusion/lsi/mpi_fc.h
--- a/drivers/message/fusion/lsi/mpi_fc.h	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/lsi/mpi_fc.h	Wed Mar 10 21:09:42 2004
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2002 LSI Logic Corporation.
+ *  Copyright (c) 2000-2003 LSI Logic Corporation.
  *
  *
- *           Name:  MPI_FC.H
+ *           Name:  mpi_fc.h
  *          Title:  MPI Fibre Channel messages and structures
  *  Creation Date:  June 12, 2000
  *
- *    MPI_FC.H Version:  01.02.03
+ *    mpi_fc.h Version:  01.05.xx
  *
  *  Version History
  *  ---------------
@@ -45,7 +45,7 @@
 
 /*****************************************************************************
 *
-*        F C    T a r g e t    M o d e    M e s s a g e s
+*        F C    D i r e c t    A c c e s s     M e s s a g e s
 *
 *****************************************************************************/
 
@@ -334,6 +334,7 @@
   FcPrimitiveSendRequest_t, MPI_POINTER pFcPrimitiveSendRequest_t;
 
 #define MPI_FC_PRIM_SEND_FLAGS_PORT_MASK       (0x01)
+#define MPI_FC_PRIM_SEND_FLAGS_ML_RESET_LINK   (0x02)
 #define MPI_FC_PRIM_SEND_FLAGS_RESET_LINK      (0x04)
 #define MPI_FC_PRIM_SEND_FLAGS_STOP_SEND       (0x08)
 #define MPI_FC_PRIM_SEND_FLAGS_SEND_ONCE       (0x10)
diff -Nru a/drivers/message/fusion/lsi/mpi_inb.h b/drivers/message/fusion/lsi/mpi_inb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/message/fusion/lsi/mpi_inb.h	Wed Mar 10 21:09:43 2004
@@ -0,0 +1,220 @@
+/*
+ *  Copyright (c) 2003 LSI Logic Corporation.
+ *
+ *
+ *           Name:  mpi_inb.h
+ *          Title:  MPI Inband structures and definitions
+ *  Creation Date:  September 30, 2003
+ *
+ *    mpi_inb.h Version:  01.03.xx
+ *
+ *  Version History
+ *  ---------------
+ *
+ *  Date      Version   Description
+ *  --------  --------  ------------------------------------------------------
+ *  ??-??-??  01.03.01  Original release.
+ *  --------------------------------------------------------------------------
+ */
+
+#ifndef MPI_INB_H
+#define MPI_INB_H
+
+/******************************************************************************
+*
+*        I n b a n d    M e s s a g e s
+*
+*******************************************************************************/
+
+
+/****************************************************************************/
+/* Inband Buffer Post Request                                               */
+/****************************************************************************/
+
+typedef struct _MSG_INBAND_BUFFER_POST_REQUEST
+{
+    U8                      Reserved1;          /* 00h */
+    U8                      BufferCount;        /* 01h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      Reserved3;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U32                     Reserved4;          /* 0Ch */
+    SGE_TRANS_SIMPLE_UNION  SGL;                /* 10h */
+} MSG_INBAND_BUFFER_POST_REQUEST, MPI_POINTER PTR_MSG_INBAND_BUFFER_POST_REQUEST,
+  MpiInbandBufferPostRequest_t , MPI_POINTER pMpiInbandBufferPostRequest_t;
+
+
+typedef struct _WWN_FC_FORMAT
+{
+    U64                     NodeName;           /* 00h */
+    U64                     PortName;           /* 08h */
+} WWN_FC_FORMAT, MPI_POINTER PTR_WWN_FC_FORMAT,
+  WwnFcFormat_t, MPI_POINTER pWwnFcFormat_t;
+
+typedef struct _WWN_SAS_FORMAT
+{
+    U64                     WorldWideID;        /* 00h */
+    U32                     Reserved1;          /* 08h */
+    U32                     Reserved2;          /* 0Ch */
+} WWN_SAS_FORMAT, MPI_POINTER PTR_WWN_SAS_FORMAT,
+  WwnSasFormat_t, MPI_POINTER pWwnSasFormat_t;
+
+typedef union _WWN_INBAND_FORMAT
+{
+    WWN_FC_FORMAT           Fc;
+    WWN_SAS_FORMAT          Sas;
+} WWN_INBAND_FORMAT, MPI_POINTER PTR_WWN_INBAND_FORMAT,
+  WwnInbandFormat, MPI_POINTER pWwnInbandFormat;
+
+
+/* Inband Buffer Post reply message */
+
+typedef struct _MSG_INBAND_BUFFER_POST_REPLY
+{
+    U16                     Reserved1;          /* 00h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      Reserved3;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U16                     Reserved4;          /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     TransferLength;     /* 14h */
+    U32                     TransactionContext; /* 18h */
+    WWN_INBAND_FORMAT       Wwn;                /* 1Ch */
+    U32                     IOCIdentifier[4];   /* 2Ch */
+} MSG_INBAND_BUFFER_POST_REPLY, MPI_POINTER PTR_MSG_INBAND_BUFFER_POST_REPLY,
+  MpiInbandBufferPostReply_t, MPI_POINTER pMpiInbandBufferPostReply_t;
+
+
+/****************************************************************************/
+/* Inband Send Request                                                      */
+/****************************************************************************/
+
+typedef struct _MSG_INBAND_SEND_REQUEST
+{
+    U16                     Reserved1;          /* 00h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      Reserved3;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U32                     Reserved4;          /* 0Ch */
+    WWN_INBAND_FORMAT       Wwn;                /* 10h */
+    U32                     Reserved5;          /* 20h */
+    SGE_IO_UNION            SGL;                /* 24h */
+} MSG_INBAND_SEND_REQUEST, MPI_POINTER PTR_MSG_INBAND_SEND_REQUEST,
+  MpiInbandSendRequest_t , MPI_POINTER pMpiInbandSendRequest_t;
+
+
+/* Inband Send reply message */
+
+typedef struct _MSG_INBAND_SEND_REPLY
+{
+    U16                     Reserved1;          /* 00h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      Reserved3;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U16                     Reserved4;          /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     ResponseLength;     /* 14h */
+} MSG_INBAND_SEND_REPLY, MPI_POINTER PTR_MSG_INBAND_SEND_REPLY,
+  MpiInbandSendReply_t, MPI_POINTER pMpiInbandSendReply_t;
+
+
+/****************************************************************************/
+/* Inband Response Request                                                  */
+/****************************************************************************/
+
+typedef struct _MSG_INBAND_RSP_REQUEST
+{
+    U16                     Reserved1;          /* 00h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      Reserved3;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U32                     Reserved4;          /* 0Ch */
+    WWN_INBAND_FORMAT       Wwn;                /* 10h */
+    U32                     IOCIdentifier[4];   /* 20h */
+    U32                     ResponseLength;     /* 30h */
+    SGE_IO_UNION            SGL;                /* 34h */
+} MSG_INBAND_RSP_REQUEST, MPI_POINTER PTR_MSG_INBAND_RSP_REQUEST,
+  MpiInbandRspRequest_t , MPI_POINTER pMpiInbandRspRequest_t;
+
+
+/* Inband Response reply message */
+
+typedef struct _MSG_INBAND_RSP_REPLY
+{
+    U16                     Reserved1;          /* 00h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      Reserved3;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U16                     Reserved4;          /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+} MSG_INBAND_RSP_REPLY, MPI_POINTER PTR_MSG_INBAND_RSP_REPLY,
+  MpiInbandRspReply_t, MPI_POINTER pMpiInbandRspReply_t;
+
+
+/****************************************************************************/
+/* Inband Abort Request                                                     */
+/****************************************************************************/
+
+typedef struct _MSG_INBAND_ABORT_REQUEST
+{
+    U8                      Reserved1;          /* 00h */
+    U8                      AbortType;          /* 01h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      Reserved3;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U32                     Reserved4;          /* 0Ch */
+    U32                     ContextToAbort;     /* 10h */
+} MSG_INBAND_ABORT_REQUEST, MPI_POINTER PTR_MSG_INBAND_ABORT_REQUEST,
+  MpiInbandAbortRequest_t , MPI_POINTER pMpiInbandAbortRequest_t;
+
+#define MPI_INBAND_ABORT_TYPE_ALL_BUFFERS       (0x00)
+#define MPI_INBAND_ABORT_TYPE_EXACT_BUFFER      (0x01)
+#define MPI_INBAND_ABORT_TYPE_SEND_REQUEST      (0x02)
+#define MPI_INBAND_ABORT_TYPE_RESPONSE_REQUEST  (0x03)
+
+
+/* Inband Abort reply message */
+
+typedef struct _MSG_INBAND_ABORT_REPLY
+{
+    U8                      Reserved1;          /* 00h */
+    U8                      AbortType;          /* 01h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      Reserved3;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U16                     Reserved4;          /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+} MSG_INBAND_ABORT_REPLY, MPI_POINTER PTR_MSG_INBAND_ABORT_REPLY,
+  MpiInbandAbortReply_t, MPI_POINTER pMpiInbandAbortReply_t;
+
+
+#endif
+
diff -Nru a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h
--- a/drivers/message/fusion/lsi/mpi_init.h	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/lsi/mpi_init.h	Wed Mar 10 21:09:42 2004
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2002 LSI Logic Corporation.
+ *  Copyright (c) 2000-2003 LSI Logic Corporation.
  *
  *
- *           Name:  MPI_INIT.H
+ *           Name:  mpi_init.h
  *          Title:  MPI initiator mode messages and structures
  *  Creation Date:  June 8, 2000
  *
- *    MPI_INIT.H Version:  01.02.05
+ *    mpi_init.h Version:  01.05.xx
  *
  *  Version History
  *  ---------------
@@ -31,6 +31,8 @@
  *  10-04-01  01.02.04  Added defines for SEP request Action field.
  *  05-31-02  01.02.05  Added MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR define
  *                      for SCSI IO requests.
+ *  11-15-02  01.02.06  Added special extended SCSI Status defines for FCP.
+ *  06-26-03  01.02.07  Added MPI_SCSI_STATUS_FCPEXT_UNASSIGNED define.
  *  --------------------------------------------------------------------------
  */
 
@@ -45,7 +47,7 @@
 *****************************************************************************/
 
 /****************************************************************************/
-/*  SCSI IO messages and assocaited structures                              */
+/*  SCSI IO messages and associated structures                              */
 /****************************************************************************/
 
 typedef struct _MSG_SCSI_IO_REQUEST
@@ -78,6 +80,16 @@
 #define MPI_SCSIIO_MSGFLGS_SENSE_LOC_HOST           (0x00)
 #define MPI_SCSIIO_MSGFLGS_SENSE_LOC_IOC            (0x02)
 #define MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR  (0x04)
+#define MPI_SCSIIO_MSGFLGS_EEDP_TYPE_MASK           (0xE0)
+#define MPI_SCSIIO_MSGFLGS_EEDP_NONE                (0x00)
+#define MPI_SCSIIO_MSGFLGS_EEDP_RDPROTECT_T10       (0x20)
+#define MPI_SCSIIO_MSGFLGS_EEDP_VRPROTECT_T10       (0x40)
+#define MPI_SCSIIO_MSGFLGS_EEDP_WRPROTECT_T10       (0x60)
+#define MPI_SCSIIO_MSGFLGS_EEDP_520_READ_MODE1      (0x20)
+#define MPI_SCSIIO_MSGFLGS_EEDP_520_WRITE_MODE1     (0x40)
+#define MPI_SCSIIO_MSGFLGS_EEDP_8_9_READ_MODE1      (0x60)
+#define MPI_SCSIIO_MSGFLGS_EEDP_8_9_WRITE_MODE1     (0x80)
+
 
 /* SCSI IO LUN fields */
 
@@ -153,6 +165,10 @@
 #define MPI_SCSI_STATUS_TASK_SET_FULL           (0x28)
 #define MPI_SCSI_STATUS_ACA_ACTIVE              (0x30)
 
+#define MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT    (0x80)
+#define MPI_SCSI_STATUS_FCPEXT_NO_LINK              (0x81)
+#define MPI_SCSI_STATUS_FCPEXT_UNASSIGNED           (0x82)
+
 
 /* SCSI IO Reply SCSIState values */
 
@@ -176,6 +192,33 @@
 
 
 /****************************************************************************/
+/*  SCSI IO 32 Request message structure                                    */
+/****************************************************************************/
+
+typedef struct _MSG_SCSI_IO32_REQUEST
+{
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      CDBLength;          /* 04h */
+    U8                      SenseBufferLength;  /* 05h */
+    U8                      Reserved;           /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      LUN[8];             /* 0Ch */
+    U32                     Control;            /* 14h */
+    U8                      CDB[32];            /* 18h */
+    U32                     DataLength;         /* 38h */
+    U32                     SenseBufferLowAddr; /* 3Ch */
+    SGE_IO_UNION            SGL;                /* 40h */
+} MSG_SCSI_IO32_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO32_REQUEST,
+  SCSIIO32Request_t, MPI_POINTER pSCSIIO32Request_t;
+
+/* SCSI IO 32 uses the same defines as above for SCSI IO */
+
+
+/****************************************************************************/
 /*  SCSI Task Management messages                                           */
 /****************************************************************************/
 
@@ -203,6 +246,7 @@
 #define MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET          (0x03)
 #define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS             (0x04)
 #define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET    (0x05)
+#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET        (0x06)
 
 /* MsgFlags bits */
 #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION   (0x00)
diff -Nru a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h
--- a/drivers/message/fusion/lsi/mpi_ioc.h	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/lsi/mpi_ioc.h	Wed Mar 10 21:09:42 2004
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2002 LSI Logic Corporation.
+ *  Copyright (c) 2000-2003 LSI Logic Corporation.
  *
  *
- *           Name:  MPI_IOC.H
+ *           Name:  mpi_ioc.h
  *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  *  Creation Date:  August 11, 2000
  *
- *    MPI_IOC.H Version:  01.02.06
+ *    mpi_ioc.h Version:  01.05.xx
  *
  *  Version History
  *  ---------------
@@ -55,6 +55,8 @@
  *  05-31-02  01.02.06  Added define for
  *                      MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID.
  *                      Added AliasIndex to EVENT_DATA_LOGOUT structure.
+ *  04-01-03  01.02.07  Added defines for MPI_FW_HEADER_SIGNATURE_.
+ *  06-26-03  01.02.08  Added new values to the product family defines.
  *  --------------------------------------------------------------------------
  */
 
@@ -87,19 +89,21 @@
     U8                      Reserved1[2];               /* 0Eh */
     U32                     HostMfaHighAddr;            /* 10h */
     U32                     SenseBufferHighAddr;        /* 14h */
+    U32                     ReplyFifoHostSignalingAddr; /* 18h */
 } MSG_IOC_INIT, MPI_POINTER PTR_MSG_IOC_INIT,
   IOCInit_t, MPI_POINTER pIOCInit_t;
 
 /* WhoInit values */
-#define MPI_WHOINIT_NO_ONE                      (0x00)
-#define MPI_WHOINIT_SYSTEM_BIOS                 (0x01)
-#define MPI_WHOINIT_ROM_BIOS                    (0x02)
-#define MPI_WHOINIT_PCI_PEER                    (0x03)
-#define MPI_WHOINIT_HOST_DRIVER                 (0x04)
-#define MPI_WHOINIT_MANUFACTURER                (0x05)
+#define MPI_WHOINIT_NO_ONE                          (0x00)
+#define MPI_WHOINIT_SYSTEM_BIOS                     (0x01)
+#define MPI_WHOINIT_ROM_BIOS                        (0x02)
+#define MPI_WHOINIT_PCI_PEER                        (0x03)
+#define MPI_WHOINIT_HOST_DRIVER                     (0x04)
+#define MPI_WHOINIT_MANUFACTURER                    (0x05)
 
 /* Flags values */
-#define MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE      (0x01)
+#define MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE          (0x01)
+#define MPI_IOCINIT_FLAGS_REPLY_FIFO_HOST_SIGNAL    (0x02)
 
 typedef struct _MSG_IOC_INIT_REPLY
 {
@@ -179,8 +183,10 @@
     U8                      MaxDevices;                 /* 2Eh */
     U8                      MaxBuses;                   /* 2Fh */
     U32                     FWImageSize;                /* 30h */
-    U32                     Reserved4;                  /* 34h */
+    U32                     IOCCapabilities;            /* 34h */
     MPI_FW_VERSION          FWVersion;                  /* 38h */
+    U16                     HighPriorityQueueDepth;     /* 3Ch */
+    U16                     Reserved2;                  /* 3Eh */
 } MSG_IOC_FACTS_REPLY, MPI_POINTER PTR_MSG_IOC_FACTS_REPLY,
   IOCFactsReply_t, MPI_POINTER pIOCFactsReply_t;
 
@@ -192,12 +198,22 @@
 
 #define MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL    (0x0001)
 #define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID     (0x0002)
+#define MPI_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL        (0x0004)
+#define MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL   (0x0008)
 
 #define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT         (0x01)
 
 #define MPI_IOCFACTS_EVENTSTATE_DISABLED            (0x00)
 #define MPI_IOCFACTS_EVENTSTATE_ENABLED             (0x01)
 
+#define MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q          (0x00000001)
+#define MPI_IOCFACTS_CAPABILITY_REPLY_HOST_SIGNAL   (0x00000002)
+#define MPI_IOCFACTS_CAPABILITY_QUEUE_FULL_HANDLING (0x00000004)
+#define MPI_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER   (0x00000008)
+#define MPI_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER     (0x00000010)
+#define MPI_IOCFACTS_CAPABILITY_EXTENDED_BUFFER     (0x00000020)
+#define MPI_IOCFACTS_CAPABILITY_EEDP                (0x00000040)
+
 
 
 /*****************************************************************************
@@ -253,6 +269,8 @@
 #define MPI_PORTFACTS_PORTTYPE_INACTIVE         (0x00)
 #define MPI_PORTFACTS_PORTTYPE_SCSI             (0x01)
 #define MPI_PORTFACTS_PORTTYPE_FC               (0x10)
+#define MPI_PORTFACTS_PORTTYPE_ISCSI            (0x20)
+#define MPI_PORTFACTS_PORTTYPE_SAS              (0x30)
 
 /* ProtocolFlags values */
 
@@ -386,6 +404,10 @@
 #define MPI_EVENT_INTEGRATED_RAID           (0x0000000B)
 #define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C)
 #define MPI_EVENT_ON_BUS_TIMER_EXPIRED      (0x0000000D)
+#define MPI_EVENT_QUEUE_FULL                (0x0000000E)
+#define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE  (0x0000000F)
+#define MPI_EVENT_SAS_SES                   (0x00000010)
+#define MPI_EVENT_PERSISTENT_TABLE_FULL     (0x00000011)
 
 /* AckRequired field values */
 
@@ -433,6 +455,39 @@
 #define MPI_EVENT_SCSI_DEV_STAT_RC_NOT_RESPONDING       (0x04)
 #define MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA           (0x05)
 
+/* SAS Device Status Change Event data */
+
+typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
+{
+    U8                      TargetID;                   /* 00h */
+    U8                      Bus;                        /* 01h */
+    U8                      ReasonCode;                 /* 02h */
+    U8                      Reserved;                   /* 03h */
+    U8                      ASC;                        /* 04h */
+    U8                      ASCQ;                       /* 05h */
+    U16                     DevHandle;                  /* 06h */
+    U32                     DeviceInfo;                 /* 08h */
+} EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
+  MPI_POINTER PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
+  MpiEventDataSasDeviceStatusChange_t,
+  MPI_POINTER pMpiEventDataSasDeviceStatusChange_t;
+
+/* MPI SAS Device Status Change Event data ReasonCode values */
+#define MPI_EVENT_SAS_DEV_STAT_RC_ADDED                 (0x03)
+#define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING        (0x04)
+#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA            (0x05)
+#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED      (0x06)
+
+/* SCSI Event data for Queue Full event */
+
+typedef struct _EVENT_DATA_QUEUE_FULL
+{
+    U8                      TargetID;                   /* 00h */
+    U8                      Bus;                        /* 01h */
+    U16                     CurrentDepth;               /* 02h */
+} EVENT_DATA_QUEUE_FULL, MPI_POINTER PTR_EVENT_DATA_QUEUE_FULL,
+  EventDataQueueFull_t, MPI_POINTER pEventDataQueueFull_t;
+
 /* MPI Link Status Change Event data */
 
 typedef struct _EVENT_DATA_LINK_STATUS
@@ -538,6 +593,7 @@
 #define MPI_FW_DOWNLOAD_ITYPE_FW            (0x01)
 #define MPI_FW_DOWNLOAD_ITYPE_BIOS          (0x02)
 #define MPI_FW_DOWNLOAD_ITYPE_NVDATA        (0x03)
+#define MPI_FW_DOWNLOAD_ITYPE_BOOTLOADER    (0x04)
 
 
 typedef struct _FWDownloadTCSGE
@@ -590,6 +646,7 @@
 #define MPI_FW_UPLOAD_ITYPE_FW_FLASH        (0x01)
 #define MPI_FW_UPLOAD_ITYPE_BIOS_FLASH      (0x02)
 #define MPI_FW_UPLOAD_ITYPE_NVDATA          (0x03)
+#define MPI_FW_UPLOAD_ITYPE_BOOTLOADER      (0x04)
 
 typedef struct _FWUploadTCSGE
 {
@@ -653,6 +710,11 @@
 #define MPI_FW_HEADER_PID_TYPE_MASK             (0xF000)
 #define MPI_FW_HEADER_PID_TYPE_SCSI             (0x0000)
 #define MPI_FW_HEADER_PID_TYPE_FC               (0x1000)
+#define MPI_FW_HEADER_PID_TYPE_SAS              (0x2000)
+
+#define MPI_FW_HEADER_SIGNATURE_0               (0x5AEAA55A)
+#define MPI_FW_HEADER_SIGNATURE_1               (0xA55AEAA5)
+#define MPI_FW_HEADER_SIGNATURE_2               (0x5AA55AEA)
 
 #define MPI_FW_HEADER_PID_PROD_MASK                     (0x0F00)
 #define MPI_FW_HEADER_PID_PROD_INITIATOR_SCSI           (0x0100)
@@ -663,6 +725,7 @@
 #define MPI_FW_HEADER_PID_PROD_CTX_SCSI                 (0x0600)
 
 #define MPI_FW_HEADER_PID_FAMILY_MASK           (0x00FF)
+/* SCSI */
 #define MPI_FW_HEADER_PID_FAMILY_1030A0_SCSI    (0x0001)
 #define MPI_FW_HEADER_PID_FAMILY_1030B0_SCSI    (0x0002)
 #define MPI_FW_HEADER_PID_FAMILY_1030B1_SCSI    (0x0003)
@@ -673,9 +736,17 @@
 #define MPI_FW_HEADER_PID_FAMILY_1020C0_SCSI    (0x0008)
 #define MPI_FW_HEADER_PID_FAMILY_1035A0_SCSI    (0x0009)
 #define MPI_FW_HEADER_PID_FAMILY_1035B0_SCSI    (0x000A)
+#define MPI_FW_HEADER_PID_FAMILY_1030TA0_SCSI   (0x000B)
+#define MPI_FW_HEADER_PID_FAMILY_1020TA0_SCSI   (0x000C)
+/* Fibre Channel */
 #define MPI_FW_HEADER_PID_FAMILY_909_FC         (0x0000)
 #define MPI_FW_HEADER_PID_FAMILY_919_FC         (0x0001)
 #define MPI_FW_HEADER_PID_FAMILY_919X_FC        (0x0002)
+#define MPI_FW_HEADER_PID_FAMILY_919XL_FC       (0x0003)
+#define MPI_FW_HEADER_PID_FAMILY_949_FC         (0x0004)
+#define MPI_FW_HEADER_PID_FAMILY_959_FC         (0x0005)
+/* SAS */
+#define MPI_FW_HEADER_PID_FAMILY_1064_SAS       (0x0001)
 
 typedef struct _MPI_EXT_IMAGE_HEADER
 {
@@ -694,5 +765,6 @@
 #define MPI_EXT_IMAGE_TYPE_UNSPECIFIED          (0x00)
 #define MPI_EXT_IMAGE_TYPE_FW                   (0x01)
 #define MPI_EXT_IMAGE_TYPE_NVDATA               (0x03)
+#define MPI_EXT_IMAGE_TYPE_BOOTLOADER           (0x04)
 
 #endif
diff -Nru a/drivers/message/fusion/lsi/mpi_lan.h b/drivers/message/fusion/lsi/mpi_lan.h
--- a/drivers/message/fusion/lsi/mpi_lan.h	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/lsi/mpi_lan.h	Wed Mar 10 21:09:42 2004
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2002 LSI Logic Corporation.
+ *  Copyright (c) 2000-2003 LSI Logic Corporation.
  *
  *
- *           Name:  MPI_LAN.H
+ *           Name:  mpi_lan.h
  *          Title:  MPI LAN messages and structures
  *  Creation Date:  June 30, 2000
  *
- *    MPI_LAN.H Version:  01.02.01
+ *    mpi_lan.h Version:  01.05.xx
  *
  *  Version History
  *  ---------------
diff -Nru a/drivers/message/fusion/lsi/mpi_raid.h b/drivers/message/fusion/lsi/mpi_raid.h
--- a/drivers/message/fusion/lsi/mpi_raid.h	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/lsi/mpi_raid.h	Wed Mar 10 21:09:42 2004
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2001-2002 LSI Logic Corporation.
+ *  Copyright (c) 2001-2003 LSI Logic Corporation.
  *
  *
- *           Name:  MPI_RAID.H
+ *           Name:  mpi_raid.h
  *          Title:  MPI RAID message and structures
  *  Creation Date:  February 27, 2001
  *
- *    MPI_RAID.H Version:  01.02.07
+ *    mpi_raid.h Version:  01.05.xx
  *
  *  Version History
  *  ---------------
@@ -25,6 +25,9 @@
  *                      MPI_RAID_ACTION_INACTIVATE_VOLUME, and
  *                      MPI_RAID_ACTION_ADATA_INACTIVATE_ALL.
  *  07-12-02  01.02.07  Added structures for Mailbox request and reply.
+ *  11-15-02  01.02.08  Added missing MsgContext field to MSG_MAILBOX_REQUEST.
+ *  04-01-03  01.02.09  New action data option flag for
+ *                      MPI_RAID_ACTION_DELETE_VOLUME.
  *  --------------------------------------------------------------------------
  */
 
@@ -40,7 +43,7 @@
 
 
 /****************************************************************************/
-/* RAID Volume Request                                                      */
+/* RAID Action Request                                                      */
 /****************************************************************************/
 
 typedef struct _MSG_RAID_ACTION
@@ -90,6 +93,9 @@
 #define MPI_RAID_ACTION_ADATA_KEEP_PHYS_DISKS       (0x00000000)
 #define MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS        (0x00000001)
 
+#define MPI_RAID_ACTION_ADATA_KEEP_LBA0             (0x00000000)
+#define MPI_RAID_ACTION_ADATA_ZERO_LBA0             (0x00000002)
+
 /* ActionDataWord defines for use with MPI_RAID_ACTION_ACTIVATE_VOLUME action */
 #define MPI_RAID_ACTION_ADATA_INACTIVATE_ALL        (0x00000001)
 
@@ -184,7 +190,7 @@
 
 
 /****************************************************************************/
-/* Mailbox request structure */
+/* Mailbox reqeust structure */
 /****************************************************************************/
 
 typedef struct _MSG_MAILBOX_REQUEST
@@ -195,6 +201,7 @@
     U16                     Reserved2;
     U8                      Reserved3;
     U8                      MsgFlags;
+    U32                     MsgContext;
     U8                      Command[10];
     U16                     Reserved4;
     SGE_IO_UNION            SGL;
diff -Nru a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/message/fusion/lsi/mpi_sas.h	Wed Mar 10 21:09:43 2004
@@ -0,0 +1,181 @@
+/*
+ *  Copyright (c) 2003 LSI Logic Corporation.
+ *
+ *
+ *           Name:  mpi_sas.h
+ *          Title:  MPI Serial Attached SCSI structures and definitions
+ *  Creation Date:  April 23, 2003
+ *
+ *    mpi_sas.h Version:  01.05.xx
+ *
+ *  Version History
+ *  ---------------
+ *
+ *  Date      Version   Description
+ *  --------  --------  ------------------------------------------------------
+ *  xx-yy-zz  01.05.01  Original release.
+ *  --------------------------------------------------------------------------
+ */
+
+#ifndef MPI_SAS_H
+#define MPI_SAS_H
+
+/*****************************************************************************
+*
+*        S e r i a l    A t t a c h e d    S C S I     M e s s a g e s
+*
+*****************************************************************************/
+
+/****************************************************************************/
+/* Serial Management Protocol Passthrough Request                           */
+/****************************************************************************/
+
+typedef struct _MSG_SMP_PASSTHROUGH_REQUEST
+{
+    U8                      PassthroughFlags;   /* 00h */
+    U8                      PhysicalPort;       /* 01h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     RequestDataLength;  /* 04h */
+    U8                      ConnectionRate;     /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U32                     Reserved1;          /* 0Ch */
+    U64                     SASAddress;         /* 10h */
+    U32                     Reserved2;          /* 18h */
+    U32                     Reserved3;          /* 1Ch */
+    SGE_SIMPLE_UNION        SGL;                /* 20h */
+} MSG_SMP_PASSTHROUGH_REQUEST, MPI_POINTER PTR_MSG_SMP_PASSTHROUGH_REQUEST,
+  SmpPassthroughRequest_t, MPI_POINTER pSmpPassthroughRequest_t;
+
+#define MPI_SMP_PT_REQ_PT_FLAGS_IMMEDIATE       (0x80)
+
+#define MPI_SMP_PT_REQ_CONNECT_RATE_NEGOTIATED  (0x00)
+#define MPI_SMP_PT_REQ_CONNECT_RATE_1_5         (0x08)
+#define MPI_SMP_PT_REQ_CONNECT_RATE_3_0         (0x09)
+
+
+/* Serial Management Protocol Passthrough Reply */
+typedef struct _MSG_SMP_PASSTHROUGH_REPLY
+{
+    U8                      PassthroughFlags;   /* 00h */
+    U8                      PhysicalPort;       /* 01h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     ResponseDataLength; /* 04h */
+    U8                      Reserved1;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      Reserved2;          /* 0Ch */
+    U8                      SASStatus;          /* 0Dh */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     Reserved3;          /* 14h */
+    U8                      ResponseData[4];    /* 18h */
+} MSG_SMP_PASSTHROUGH_REPLY, MPI_POINTER PTR_MSG_SMP_PASSTHROUGH_REPLY,
+  SmpPassthroughReply_t, MPI_POINTER pSmpPassthroughReply_t;
+
+#define MPI_SMP_PT_REPLY_PT_FLAGS_IMMEDIATE     (0x80)
+
+/* values for the SASStatus field */
+#define MPI_SASSTATUS_SUCCESS                           (0x00)
+#define MPI_SASSTATUS_UNKNOWN_ERROR                     (0x01)
+#define MPI_SASSTATUS_INVALID_FRAME                     (0x02)
+#define MPI_SASSTATUS_UTC_BAD_DEST                      (0x03)
+#define MPI_SASSTATUS_UTC_BREAK_RECEIVED                (0x04)
+#define MPI_SASSTATUS_UTC_CONNECT_RATE_NOT_SUPPORTED    (0x05)
+#define MPI_SASSTATUS_UTC_PORT_LAYER_REQUEST            (0x06)
+#define MPI_SASSTATUS_UTC_PROTOCOL_NOT_SUPPORTED        (0x07)
+#define MPI_SASSTATUS_UTC_STP_RESOURCES_BUSY            (0x08)
+#define MPI_SASSTATUS_UTC_WRONG_DESTINATION             (0x09)
+#define MPI_SASSTATUS_SHORT_INFORMATION_UNIT            (0x0A)
+#define MPI_SASSTATUS_LONG_INFORMATION_UNIT             (0x0B)
+#define MPI_SASSTATUS_XFER_RDY_INCORRECT_WRITE_DATA     (0x0C)
+#define MPI_SASSTATUS_XFER_RDY_REQUEST_OFFSET_ERROR     (0x0D)
+#define MPI_SASSTATUS_XFER_RDY_NOT_EXPECTED             (0x0E)
+#define MPI_SASSTATUS_DATA_INCORRECT_DATA_LENGTH        (0x0F)
+#define MPI_SASSTATUS_DATA_TOO_MUCH_READ_DATA           (0x10)
+#define MPI_SASSTATUS_DATA_OFFSET_ERROR                 (0x11)
+#define MPI_SASSTATUS_SDSF_NAK_RECEIVED                 (0x12)
+#define MPI_SASSTATUS_SDSF_CONNECTION_FAILED            (0x13)
+#define MPI_SASSTATUS_INITIATOR_RESPONSE_TIMEOUT        (0x14)
+
+
+/*
+ * Values for the SAS DeviceInfo field used in SAS Device Status Change Event
+ * data and SAS IO Unit Configuration pages.
+ */
+#define MPI_SAS_DEVICE_INFO_ATAPI_DEVICE        (0x00002000)
+#define MPI_SAS_DEVICE_INFO_LSI_DEVICE          (0x00001000)
+#define MPI_SAS_DEVICE_INFO_DIRECT_ATTACH       (0x00000800)
+#define MPI_SAS_DEVICE_INFO_SSP_TARGET          (0x00000400)
+#define MPI_SAS_DEVICE_INFO_STP_TARGET          (0x00000200)
+#define MPI_SAS_DEVICE_INFO_SMP_TARGET          (0x00000100)
+#define MPI_SAS_DEVICE_INFO_SATA_DEVICE         (0x00000080)
+#define MPI_SAS_DEVICE_INFO_SSP_INITIATOR       (0x00000040)
+#define MPI_SAS_DEVICE_INFO_STP_INITIATOR       (0x00000020)
+#define MPI_SAS_DEVICE_INFO_SMP_INITIATOR       (0x00000010)
+#define MPI_SAS_DEVICE_INFO_SATA_HOST           (0x00000008)
+
+#define MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE    (0x00000007)
+#define MPI_SAS_DEVICE_INFO_NO_DEVICE           (0x00000000)
+#define MPI_SAS_DEVICE_INFO_END_DEVICE          (0x00000001)
+#define MPI_SAS_DEVICE_INFO_EDGE_EXPANDER       (0x00000002)
+#define MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER     (0x00000003)
+
+
+/****************************************************************************/
+/* SAS IO Unit Control Request                                              */
+/****************************************************************************/
+
+typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
+{
+    U8                      Operation;          /* 00h */
+    U8                      Reserved1;          /* 01h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      Reserved3;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      TargetID;           /* 0Ch */
+    U8                      Bus;                /* 0Dh */
+    U8                      PhyNum;             /* 0Eh */
+    U8                      Reserved4;          /* 0Fh */
+    U32                     Reserved5;          /* 10h */
+    U64                     SASAddress;         /* 14h */
+    U32                     Reserved6;          /* 1Ch */
+} MSG_SAS_IOUNIT_CONTROL_REQUEST, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REQUEST,
+  SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t;
+
+/* values for the ... field */
+#define MPI_SAS_OP_CLEAR_NOT_PRESENT             (0x01)
+#define MPI_SAS_OP_CLEAR_ALL                     (0x02)
+#define MPI_SAS_OP_MAP                           (0x03)
+#define MPI_SAS_OP_MOVE                          (0x04)
+#define MPI_SAS_OP_CLEAR                         (0x05)
+#define MPI_SAS_OP_PHY_LINK_RESET                (0x06)
+#define MPI_SAS_OP_PHY_HARD_RESET                (0x07)
+#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG           (0x08)
+
+
+/* SAS IO Unit Control Reply */
+typedef struct _MSG_SAS_IOUNIT_CONTROL_REPLY
+{
+    U8                      Operation;          /* 00h */
+    U8                      Reserved1;          /* 01h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      Reserved3;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U16                     Reserved4;          /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+} MSG_SAS_IOUNIT_CONTROL_REPLY, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REPLY,
+  SasIoUnitControlReply_t, MPI_POINTER pSasIoUnitControlReply_t;
+
+#endif
+
+
diff -Nru a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h
--- a/drivers/message/fusion/lsi/mpi_targ.h	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/lsi/mpi_targ.h	Wed Mar 10 21:09:42 2004
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2002 LSI Logic Corporation.
+ *  Copyright (c) 2000-2003 LSI Logic Corporation.
  *
  *
- *           Name:  MPI_TARG.H
+ *           Name:  mpi_targ.h
  *          Title:  MPI Target mode messages and structures
  *  Creation Date:  June 22, 2000
  *
- *    MPI_TARG.H Version:  01.02.07
+ *    mpi_targ.h Version:  01.05.xx
  *
  *  Version History
  *  ---------------
@@ -41,6 +41,8 @@
  *                      Added AliasIndex field to MPI_TARGET_FCP_CMD_BUFFER.
  *  09-16-02  01.02.07  Added flags for confirmed completion.
  *                      Added PRIORITY_REASON_TARGET_BUSY.
+ *  11-15-02  01.02.08  Added AliasID field to MPI_TARGET_SCSI_SPI_CMD_BUFFER.
+ *  04-01-03  01.02.09  Added OptionalOxid field to MPI_TARGET_FCP_CMD_BUFFER.
  *  --------------------------------------------------------------------------
  */
 
@@ -171,7 +173,7 @@
     U32     FcpDl;                                      /* 1Ch */
     U8      AliasIndex;                                 /* 20h */
     U8      Reserved1;                                  /* 21h */
-    U16     Reserved2;                                  /* 22h */
+    U16     OptionalOxid;                               /* 22h */
 } MPI_TARGET_FCP_CMD_BUFFER, MPI_POINTER PTR_MPI_TARGET_FCP_CMD_BUFFER,
   MpiTargetFcpCmdBuffer, MPI_POINTER pMpiTargetFcpCmdBuffer;
 
@@ -190,6 +192,10 @@
     U8      TaskManagementFlags;                        /* 12h */
     U8      AdditionalCDBLength;                        /* 13h */
     U8      CDB[16];                                    /* 14h */
+    /* Alias ID */
+    U8      AliasID;                                    /* 24h */
+    U8      Reserved1;                                  /* 25h */
+    U16     Reserved2;                                  /* 26h */
 } MPI_TARGET_SCSI_SPI_CMD_BUFFER,
   MPI_POINTER PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER,
   MpiTargetScsiSpiCmdBuffer, MPI_POINTER pMpiTargetScsiSpiCmdBuffer;
diff -Nru a/drivers/message/fusion/lsi/mpi_tool.h b/drivers/message/fusion/lsi/mpi_tool.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/message/fusion/lsi/mpi_tool.h	Wed Mar 10 21:09:43 2004
@@ -0,0 +1,305 @@
+/*
+ *  Copyright (c) 2001-2003 LSI Logic Corporation.
+ *
+ *
+ *           Name:  mpi_tool.h
+ *          Title:  MPI Toolbox structures and definitions
+ *  Creation Date:  July 30, 2001
+ *
+ *    mpi_tool.h Version:  01.05.xx
+ *
+ *  Version History
+ *  ---------------
+ *
+ *  Date      Version   Description
+ *  --------  --------  ------------------------------------------------------
+ *  08-08-01  01.02.01  Original release.
+ *  08-29-01  01.02.02  Added DIAG_DATA_UPLOAD_HEADER and related defines.
+ *  --------------------------------------------------------------------------
+ */
+
+#ifndef MPI_TOOL_H
+#define MPI_TOOL_H
+
+#define MPI_TOOLBOX_CLEAN_TOOL                      (0x00)
+#define MPI_TOOLBOX_MEMORY_MOVE_TOOL                (0x01)
+#define MPI_TOOLBOX_DIAG_DATA_UPLOAD_TOOL           (0x02)
+#define MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL           (0x03)
+#define MPI_TOOLBOX_FC_MANAGEMENT_TOOL              (0x04)
+
+
+/****************************************************************************/
+/* Toolbox reply                                                            */
+/****************************************************************************/
+
+typedef struct _MSG_TOOLBOX_REPLY
+{
+    U8                      Tool;                       /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved3;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+} MSG_TOOLBOX_REPLY, MPI_POINTER PTR_MSG_TOOLBOX_REPLY,
+  ToolboxReply_t, MPI_POINTER pToolboxReply_t;
+
+
+/****************************************************************************/
+/* Toolbox Clean Tool request                                               */
+/****************************************************************************/
+
+typedef struct _MSG_TOOLBOX_CLEAN_REQUEST
+{
+    U8                      Tool;                       /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     Flags;                      /* 0Ch */
+} MSG_TOOLBOX_CLEAN_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_CLEAN_REQUEST,
+  ToolboxCleanRequest_t, MPI_POINTER pToolboxCleanRequest_t;
+
+#define MPI_TOOLBOX_CLEAN_NVSRAM                    (0x00000001)
+#define MPI_TOOLBOX_CLEAN_SEEPROM                   (0x00000002)
+#define MPI_TOOLBOX_CLEAN_FLASH                     (0x00000004)
+#define MPI_TOOLBOX_CLEAN_BOOTLOADER                (0x04000000)
+#define MPI_TOOLBOX_CLEAN_FW_BACKUP                 (0x08000000)
+#define MPI_TOOLBOX_CLEAN_FW_CURRENT                (0x10000000)
+#define MPI_TOOLBOX_CLEAN_OTHER_PERSIST_PAGES       (0x20000000)
+#define MPI_TOOLBOX_CLEAN_PERSIST_MANUFACT_PAGES    (0x40000000)
+#define MPI_TOOLBOX_CLEAN_BOOT_SERVICES             (0x80000000)
+
+
+/****************************************************************************/
+/* Toolbox Memory Move request                                              */
+/****************************************************************************/
+
+typedef struct _MSG_TOOLBOX_MEM_MOVE_REQUEST
+{
+    U8                      Tool;                       /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    SGE_SIMPLE_UNION        SGL;                        /* 0Ch */
+} MSG_TOOLBOX_MEM_MOVE_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_MEM_MOVE_REQUEST,
+  ToolboxMemMoveRequest_t, MPI_POINTER pToolboxMemMoveRequest_t;
+
+
+/****************************************************************************/
+/* Toolbox Diagnostic Data Upload request                                   */
+/****************************************************************************/
+
+typedef struct _MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST
+{
+    U8                      Tool;                       /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     Flags;                      /* 0Ch */
+    U32                     Reserved3;                  /* 10h */
+    SGE_SIMPLE_UNION        SGL;                        /* 14h */
+} MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST,
+  ToolboxDiagDataUploadRequest_t, MPI_POINTER pToolboxDiagDataUploadRequest_t;
+
+typedef struct _DIAG_DATA_UPLOAD_HEADER
+{
+    U32                     DiagDataLength;             /* 00h */
+    U8                      FormatCode;                 /* 04h */
+    U8                      Reserved;                   /* 05h */
+    U16                     Reserved1;                  /* 06h */
+} DIAG_DATA_UPLOAD_HEADER, MPI_POINTER PTR_DIAG_DATA_UPLOAD_HEADER,
+  DiagDataUploadHeader_t, MPI_POINTER pDiagDataUploadHeader_t;
+
+#define MPI_TB_DIAG_FORMAT_SCSI_PRINTF_1            (0x01)
+#define MPI_TB_DIAG_FORMAT_SCSI_2                   (0x02)
+#define MPI_TB_DIAG_FORMAT_SCSI_3                   (0x03)
+#define MPI_TB_DIAG_FORMAT_FC_TRACE_1               (0x04)
+
+
+/****************************************************************************/
+/* Toolbox ISTWI Read Write request                                         */
+/****************************************************************************/
+
+typedef struct _MSG_TOOLBOX_ISTWI_READ_WRITE_REQUEST
+{
+    U8                      Tool;                       /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U8                      Flags;                      /* 0Ch */
+    U8                      BusNum;                     /* 0Dh */
+    U16                     Reserved3;                  /* 0Eh */
+    U8                      NumAddressBytes;            /* 10h */
+    U8                      Reserved4;                  /* 11h */
+    U16                     DataLength;                 /* 12h */
+    U8                      DeviceAddr;                 /* 14h */
+    U8                      Addr1;                      /* 15h */
+    U8                      Addr2;                      /* 16h */
+    U8                      Addr3;                      /* 17h */
+    U32                     Reserved5;                  /* 18h */
+    SGE_SIMPLE_UNION        SGL;                        /* 1Ch */
+} MSG_TOOLBOX_ISTWI_READ_WRITE_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_ISTWI_READ_WRITE_REQUEST,
+  ToolboxIstwiReadWriteRequest_t, MPI_POINTER pToolboxIstwiReadWriteRequest_t;
+
+#define MPI_TB_ISTWI_FLAGS_WRITE                    (0x00)
+#define MPI_TB_ISTWI_FLAGS_READ                     (0x01)
+
+
+/****************************************************************************/
+/* Toolbox FC Management request                                            */
+/****************************************************************************/
+
+/* ActionInfo for Bus and TargetId */
+typedef struct _MPI_TB_FC_MANAGE_BUS_TID_AI
+{
+    U16                     Reserved;                   /* 00h */
+    U8                      Bus;                        /* 02h */
+    U8                      TargetId;                   /* 03h */
+} MPI_TB_FC_MANAGE_BUS_TID_AI, MPI_POINTER PTR_MPI_TB_FC_MANAGE_BUS_TID_AI,
+  MpiTbFcManageBusTidAi_t, MPI_POINTER pMpiTbFcManageBusTidAi_t;
+
+/* ActionInfo for port identifier */
+typedef struct _MPI_TB_FC_MANAGE_PID_AI
+{
+    U32                     PortIdentifier;             /* 00h */
+} MPI_TB_FC_MANAGE_PID_AI, MPI_POINTER PTR_MPI_TB_FC_MANAGE_PID_AI,
+  MpiTbFcManagePidAi_t, MPI_POINTER pMpiTbFcManagePidAi_t;
+
+/* union of ActionInfo */
+typedef union _MPI_TB_FC_MANAGE_AI_UNION
+{
+    MPI_TB_FC_MANAGE_BUS_TID_AI     BusTid;
+    MPI_TB_FC_MANAGE_PID_AI         Port;
+} MPI_TB_FC_MANAGE_AI_UNION, MPI_POINTER PTR_MPI_TB_FC_MANAGE_AI_UNION,
+  MpiTbFcManageAiUnion_t, MPI_POINTER pMpiTbFcManageAiUnion_t;
+
+typedef struct _MSG_TOOLBOX_FC_MANAGE_REQUEST
+{
+    U8                          Tool;                   /* 00h */
+    U8                          Reserved;               /* 01h */
+    U8                          ChainOffset;            /* 02h */
+    U8                          Function;               /* 03h */
+    U16                         Reserved1;              /* 04h */
+    U8                          Reserved2;              /* 06h */
+    U8                          MsgFlags;               /* 07h */
+    U32                         MsgContext;             /* 08h */
+    U8                          Action;                 /* 0Ch */
+    U8                          Reserved3;              /* 0Dh */
+    U16                         Reserved4;              /* 0Eh */
+    MPI_TB_FC_MANAGE_AI_UNION   ActionInfo;             /* 10h */
+} MSG_TOOLBOX_FC_MANAGE_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_FC_MANAGE_REQUEST,
+  ToolboxFcManageRequest_t, MPI_POINTER pToolboxFcManageRequest_t;
+
+/* defines for the Action field */
+#define MPI_TB_FC_MANAGE_ACTION_DISC_ALL            (0x00)
+#define MPI_TB_FC_MANAGE_ACTION_DISC_PID            (0x01)
+#define MPI_TB_FC_MANAGE_ACTION_DISC_BUS_TID        (0x02)
+
+
+/****************************************************************************/
+/* Diagnostic Buffer Post request                                           */
+/****************************************************************************/
+
+typedef struct _MSG_DIAG_BUFFER_POST_REQUEST
+{
+    U8                      TraceLevel;                 /* 00h */
+    U8                      BufferType;                 /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     ExtendedType;               /* 0Ch */
+    U32                     BufferLength;               /* 10h */
+    U32                     ProductSpecific[4];         /* 14h */
+    U32                     Reserved3;                  /* 18h */
+    SGE_SIMPLE_UNION        SGL;                        /* 28h */
+} MSG_DIAG_BUFFER_POST_REQUEST, MPI_POINTER PTR_MSG_DIAG_BUFFER_POST_REQUEST,
+  DiagBufferPostRequest_t, MPI_POINTER pDiagBufferPostRequest_t;
+
+#define MPI_DIAG_BUF_TYPE_TRACE                     (0x00)
+#define MPI_DIAG_BUF_TYPE_SNAPSHOT                  (0x01)
+#define MPI_DIAG_BUF_TYPE_EXTENDED                  (0x02)
+
+#define MPI_DIAG_EXTENDED_QTAG                      (0x00000001)
+
+
+/* Diagnostic Buffer Post reply */
+typedef struct _MSG_DIAG_BUFFER_POST_REPLY
+{
+    U8                      Reserved1;                  /* 00h */
+    U8                      BufferType;                 /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved2;                  /* 04h */
+    U8                      Reserved3;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved4;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U32                     TransferLength;             /* 14h */
+} MSG_DIAG_BUFFER_POST_REPLY, MPI_POINTER PTR_MSG_DIAG_BUFFER_POST_REPLY,
+  DiagBufferPostReply_t, MPI_POINTER pDiagBufferPostReply_t;
+
+
+/****************************************************************************/
+/* Diagnostic Release request                                               */
+/****************************************************************************/
+
+typedef struct _MSG_DIAG_RELEASE_REQUEST
+{
+    U8                      Reserved1;                  /* 00h */
+    U8                      BufferType;                 /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved2;                  /* 04h */
+    U8                      Reserved3;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+} MSG_DIAG_RELEASE_REQUEST, MPI_POINTER PTR_MSG_DIAG_RELEASE_REQUEST,
+  DiagReleaseRequest_t, MPI_POINTER pDiagReleaseRequest_t;
+
+
+/* Diagnostic Release reply */
+typedef struct _MSG_DIAG_RELEASE_REPLY
+{
+    U8                      Reserved1;                  /* 00h */
+    U8                      BufferType;                 /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved2;                  /* 04h */
+    U8                      Reserved3;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved4;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+} MSG_DIAG_RELEASE_REPLY, MPI_POINTER PTR_MSG_DIAG_RELEASE_REPLY,
+  DiagReleaseReply_t, MPI_POINTER pDiagReleaseReply_t;
+
+
+#endif
+
+
diff -Nru a/drivers/message/fusion/lsi/mpi_type.h b/drivers/message/fusion/lsi/mpi_type.h
--- a/drivers/message/fusion/lsi/mpi_type.h	Wed Mar 10 21:09:43 2004
+++ b/drivers/message/fusion/lsi/mpi_type.h	Wed Mar 10 21:09:43 2004
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2002 LSI Logic Corporation.
+ *  Copyright (c) 2000-2003 LSI Logic Corporation.
  *
  *
- *           Name:  MPI_TYPE.H
+ *           Name:  mpi_type.h
  *          Title:  MPI Basic type definitions
  *  Creation Date:  June 6, 2000
  *
- *    MPI Version:  01.02.01
+ *    mpi_type.h Version:  01.05.xx
  *
  *  Version History
  *  ---------------
diff -Nru a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
--- a/drivers/message/fusion/mptbase.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/mptbase.c	Wed Mar 10 21:09:42 2004
@@ -44,7 +44,7 @@
  *      for gobs of hard work fixing and optimizing LAN code.
  *      THANK YOU!
  *
- *  Copyright (c) 1999-2003 LSI Logic Corporation
+ *  Copyright (c) 1999-2004 LSI Logic Corporation
  *  Originally By: Steven J. Ralston
  *  (mailto:sjralston1@netscape.net)
  *  (mailto:mpt_linux_developer@lsil.com)
@@ -209,8 +209,8 @@
 static int	GetIoUnitPage2(MPT_ADAPTER *ioc);
 static int	mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
 static int	mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
-static int	mpt_findImVolumes(MPT_ADAPTER *ioc);
 static void 	mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
+static void 	mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
 static void	mpt_timer_expired(unsigned long data);
 static int	SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
 static int	SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
@@ -347,14 +347,14 @@
 	MPT_FRAME_HDR	*mf;
 	MPT_FRAME_HDR	*mr;
 	u32		 pa;
-	int		 req_idx = -1;
+	int		 req_idx;
 	int		 cb_idx;
 	int		 type;
 	int		 freeme;
-	int		 count = 0;
 
 	ioc = bus_id;
 
+#ifdef MPT_DEBUG_IRQ
 	/*
 	 * Verify ioc pointer is ok
 	 */
@@ -369,6 +369,7 @@
 			return IRQ_NONE;
 		}
 	}
+#endif
 
 	/*
 	 *  Drain the reply FIFO!
@@ -521,17 +522,7 @@
 			spin_unlock_irqrestore(&ioc->FreeQlock, flags);
 		}
 
-		count++;
-		dirqprintk((MYIOC_s_INFO_FMT "ISR processed frame #%d\n", ioc->name, count));
 		mb();
-
-		if (count >= MPT_MAX_REPLIES_PER_ISR) {
-			dirqprintk((MYIOC_s_INFO_FMT "ISR processed %d replies.",
-					ioc->name, count));
-			dirqprintk((" Giving this ISR a break!\n"));
-			return IRQ_HANDLED;
-		}
-
 	}	/* drain reply FIFO */
 
 	return IRQ_HANDLED;
@@ -605,7 +596,8 @@
 	} else if (func == MPI_FUNCTION_EVENT_ACK) {
 		dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
 				ioc->name));
-	} else if (func == MPI_FUNCTION_CONFIG) {
+	} else if (func == MPI_FUNCTION_CONFIG ||
+		   func == MPI_FUNCTION_TOOLBOX) {
 		CONFIGPARMS *pCfg;
 		unsigned long flags;
 
@@ -714,11 +706,7 @@
 			MptCallbacks[i] = cbfunc;
 			MptDriverClass[i] = dclass;
 			MptEvHandlers[i] = NULL;
-			MptDeviceDriverHandlers[i] = NULL;
 			last_drv_idx = i;
-			if (cbfunc != mpt_base_reply) {
-				mpt_inc_use_count();
-			}
 			break;
 		}
 	}
@@ -745,10 +733,6 @@
 		last_drv_idx++;
 		if (isense_idx != -1 && isense_idx <= cb_idx)
 			isense_idx++;
-
-		if (cb_idx != mpt_base_index) {
-			mpt_dec_use_count();
-		}
 	}
 }
 
@@ -890,7 +874,7 @@
 MPT_FRAME_HDR*
 mpt_get_msg_frame(int handle, int iocid)
 {
-	MPT_FRAME_HDR *mf = NULL;
+	MPT_FRAME_HDR *mf;
 	MPT_ADAPTER *iocp;
 	unsigned long flags;
 
@@ -922,6 +906,8 @@
 		iocp->mfcnt++;
 #endif
 	}
+	else
+		mf = NULL;
 	spin_unlock_irqrestore(&iocp->FreeQlock, flags);
 
 #ifdef MFCNT
@@ -986,7 +972,11 @@
 
 		mf_dma_addr = iocp->req_frames_low_dma + req_offset;
 		CHIPREG_WRITE32(&iocp->chip->RequestFifo, mf_dma_addr);
+	} else {
+		printk (KERN_ERR
+		    "mpt_put_msg_frame: Invalid iocid=%d\n", iocid);
 	}
+
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1135,7 +1125,7 @@
 				 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
 
 		/* Wait for IOC doorbell int */
-		if ((ii = WaitForDoorbellInt(iocp, 2, sleepFlag)) < 0) {
+		if ((ii = WaitForDoorbellInt(iocp, 5, sleepFlag)) < 0) {
 			return ii;
 		}
 
@@ -1148,7 +1138,7 @@
 
 		CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
 
-		if ((r = WaitForDoorbellAck(iocp, 1, sleepFlag)) < 0) {
+		if ((r = WaitForDoorbellAck(iocp, 5, sleepFlag)) < 0) {
 			return -2;
 		}
 
@@ -1162,7 +1152,7 @@
 				(req_as_bytes[(ii*4) + 2] << 16) |
 				(req_as_bytes[(ii*4) + 3] << 24));
 			CHIPREG_WRITE32(&iocp->chip->Doorbell, word);
-			if ((r = WaitForDoorbellAck(iocp, 1, sleepFlag)) < 0) {
+			if ((r = WaitForDoorbellAck(iocp, 5, sleepFlag)) < 0) {
 				r = -3;
 				break;
 			}
@@ -1190,10 +1180,12 @@
 MPT_ADAPTER *
 mpt_adapter_find_first(void)
 {
-	MPT_ADAPTER *this = NULL;
+	MPT_ADAPTER *this;
 
 	if (! Q_IS_EMPTY(&MptAdapters))
 		this = MptAdapters.head;
+	else
+		this = NULL;
 
 	return this;
 }
@@ -1208,10 +1200,12 @@
 MPT_ADAPTER *
 mpt_adapter_find_next(MPT_ADAPTER *prev)
 {
-	MPT_ADAPTER *next = NULL;
+	MPT_ADAPTER *next;
 
 	if (prev && (prev->forw != (MPT_ADAPTER*)&MptAdapters.head))
 		next = prev->forw;
+	else
+		next = NULL;
 
 	return next;
 }
@@ -1272,10 +1266,12 @@
 	int		 ii;
 	int		 r = -ENODEV;
 	u64		 mask = 0xffffffffffffffffULL;
+	u8		 revision;
+	u8		 pcixcmd;
 
 	if (pci_enable_device(pdev))
 		return r;
-
+	
 	if (!pci_set_dma_mask(pdev, mask)) {
 		dprintk((KERN_INFO MYNAM
 			": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
@@ -1296,12 +1292,30 @@
 		printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
 		return -ENOMEM;
 	}
-	memset(ioc, 0, sizeof(*ioc));
+	memset(ioc, 0, sizeof(MPT_ADAPTER));
 	ioc->alloc_total = sizeof(MPT_ADAPTER);
 	ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;		/* avoid div by zero! */
-	ioc->reply_sz = ioc->req_sz;
+	ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
 
 	ioc->pcidev = pdev;
+
+#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX)
+	memcpy(&ioc->pcidev32,ioc->pcidev,sizeof(struct pci_dev));
+	if (pci_set_dma_mask(&ioc->pcidev32, 0xFFFFFFFF)) {
+		dprintk((KERN_INFO MYNAM
+			": error setting 32bit mask\n"));
+		kfree(ioc);
+		return -ENODEV;
+	}
+
+	if (pci_set_consistent_dma_mask(&ioc->pcidev32, 0xFFFFFFFF)) {
+		dprintk((KERN_INFO MYNAM
+			": error setting 32bit mask\n"));
+		kfree(ioc);
+		return -ENODEV;
+	}
+#endif
+
 	ioc->diagPending = 0;
 	spin_lock_init(&ioc->diagLock);
 
@@ -1412,48 +1426,45 @@
 	}
 	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
 		ioc->chip_type = FC929X;
-		ioc->prod_name = "LSIFC929X";
-		{
+		pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
+		if (revision < XL_929) {
+			ioc->prod_name = "LSIFC929X";
 			/* 929X Chip Fix. Set Split transactions level
-			 * for PCIX. Set bits 5 - 6 to zero, turn on bit 4.
-			 */
-			u16 pcixcmd = 0;
-			pci_read_config_word(pdev, 0x6a, &pcixcmd);
-			pcixcmd &= 0xFF9F;
-			pcixcmd |= 0x0010;
-			pci_write_config_word(pdev, 0x6a, pcixcmd);
+		 	* for PCIX. Set MOST bits to zero.
+		 	*/
+			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
+			pcixcmd &= 0x8F;
+			pci_write_config_byte(pdev, 0x6a, pcixcmd);
+		} else {
+			ioc->prod_name = "LSIFC929XL";
+			/* 929XL Chip Fix. Set MMRBC to 0x08.
+		 	*/
+			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
+			pcixcmd |= 0x08;
+			pci_write_config_byte(pdev, 0x6a, pcixcmd);
 		}
 	}
 	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
 		ioc->chip_type = FC919X;
 		ioc->prod_name = "LSIFC919X";
-		{
-			/* 919X Chip Fix. Set Split transactions level
-			 * for PCIX. Set bits 5 - 6 to zero, turn on bit 4.
-			 */
-			u16 pcixcmd = 0;
-			pci_read_config_word(pdev, 0x6a, &pcixcmd);
-			pcixcmd &= 0xFF9F;
-			pcixcmd |= 0x0010;
-			pci_write_config_word(pdev, 0x6a, pcixcmd);
-		}
+		/* 919X Chip Fix. Set Split transactions level
+		 * for PCIX. Set MOST bits to zero.
+		 */
+		pci_read_config_byte(pdev, 0x6a, &pcixcmd);
+		pcixcmd &= 0x8F;
+		pci_write_config_byte(pdev, 0x6a, pcixcmd);
 	}
 	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
 		ioc->chip_type = C1030;
 		ioc->prod_name = "LSI53C1030";
-		{
-			u8 revision;
-
-			/* 1030 Chip Fix. Disable Split transactions
-			 * for PCIX. Set bits 4 - 6 to zero if Rev < C0( = 8)
-			 */
-			pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
-			if (revision < 0x08) {
-				u16 pcixcmd = 0;
-				pci_read_config_word(pdev, 0x6a, &pcixcmd);
-				pcixcmd &= 0xFF8F;
-				pci_write_config_word(pdev, 0x6a, pcixcmd);
-			}
+		/* 1030 Chip Fix. Disable Split transactions
+		 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
+		 */
+		pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
+		if (revision < C0_1030) {
+			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
+			pcixcmd &= 0x8F;
+			pci_write_config_byte(pdev, 0x6a, pcixcmd);
 		}
 	}
 	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
@@ -1515,17 +1526,18 @@
 			|| (ioc->chip_type == C1035) || (ioc->chip_type == FC929X))
 		mpt_detect_bound_ports(ioc, pdev);
 
-	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
-		printk(KERN_WARNING MYNAM ": WARNING - %s did not initialize properly! (%d)\n",
-				ioc->name, r);
-	}
+	if ((r = mpt_do_ioc_recovery(ioc,
+	  MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
+		printk(KERN_WARNING MYNAM
+		  ": WARNING - %s did not initialize properly! (%d)\n",
+		  ioc->name, r);
 
-	if(r != 0 ) {
 		Q_DEL_ITEM(ioc);
 		mpt_adapters[ioc->id] = NULL;
 		free_irq(ioc->pci_irq, ioc);
 		iounmap(mem);
 		kfree(ioc);
+		pci_set_drvdata(pdev, NULL);
 		return r;
 	}
 
@@ -1565,6 +1577,7 @@
 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
 
 	ioc->active = 0;
+	mpt_sync_irq(pdev->irq);
 
 	/* Clear any lingering interrupt */
 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
@@ -1574,7 +1587,6 @@
 	Q_DEL_ITEM(ioc);
 	mpt_adapter_dispose(ioc);
 
-	mptscsih_sync_irq(pdev->irq);
 	pci_set_drvdata(pdev, NULL);
 }
 
@@ -1755,20 +1767,23 @@
 	int	 r;
 	int	 ii;
 	int	 handlers;
+	int	 ret = 0;
+	int	 reset_alt_ioc_active = 0;
 
 	printk(KERN_INFO MYNAM ": Initiating %s %s\n",
 			ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
 
-	/* Disable reply interrupts */
+	/* Disable reply interrupts (also blocks FreeQ) */
 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
 	ioc->active = 0;
-	/* NOTE: Access to IOC's request FreeQ is now blocked! */
 
 	if (ioc->alt_ioc) {
-		/* Disable alt-IOC's reply interrupts for a bit ... */
+		if (ioc->alt_ioc->active)
+			reset_alt_ioc_active = 1;
+
+		/* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
 		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
 		ioc->alt_ioc->active = 0;
-		/* NOTE: Access to alt-IOC's request FreeQ is now blocked! */
 	}
 
 	hard = 1;
@@ -1776,15 +1791,29 @@
 		hard = 0;
 
 	if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
-		printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
-				ioc->name);
+		if (hard_reset_done == -4) {
+			printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
+					ioc->name);
+
+			if (reset_alt_ioc_active && ioc->alt_ioc) {
+				/* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
+				dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
+						ioc->alt_ioc->name));
+				CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
+				ioc->alt_ioc->active = 1;
+			}
+
+		} else {
+			printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
+					ioc->name);
+		}
 		return -1;
 	}
 
 	/* hard_reset_done = 0 if a soft reset was performed
 	 * and 1 if a hard reset was performed.
 	 */
-	if (hard_reset_done && ioc->alt_ioc) {
+	if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
 		if ((r = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
 			alt_ioc_ready = 1;
 		else
@@ -1793,42 +1822,55 @@
 					ioc->alt_ioc->name, r);
 	}
 
-	/* Get IOC facts! */
+	/* Get IOC facts! Allow 1 retry */
 	if ((r = GetIocFacts(ioc, sleepFlag, reason)) != 0)
-		return -2;
-	if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
+		r = GetIocFacts(ioc, sleepFlag, reason);
+
+	if (r) {
+		ret = -2;
+	} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
 		MptDisplayIocCapabilities(ioc);
 	}
 
 	if (alt_ioc_ready) {
-		if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0)
-			return -2;
-		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
+		if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
+			/* Retry - alt IOC was initialized once
+			 */
+			r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
+		}
+		if (r) {
+			alt_ioc_ready = 0;
+			reset_alt_ioc_active = 0;
+		} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
 			MptDisplayIocCapabilities(ioc->alt_ioc);
 		}
 	}
 
-	/*
-	 * Prime reply & request queues!
+	/* Prime reply & request queues!
 	 * (mucho alloc's) Must be done prior to
 	 * init as upper addresses are needed for init.
+	 * If fails, continue with alt-ioc processing
 	 */
-	if ((r = PrimeIocFifos(ioc)) != 0)
-		return -3;
+	if ((ret == 0) && ((r = PrimeIocFifos(ioc)) != 0))
+		ret = -3;
 
-	// May need to check/upload firmware & data here!
-	if ((r = SendIocInit(ioc, sleepFlag)) != 0)
-		return -4;
+	/* May need to check/upload firmware & data here!
+	 * If fails, continue with alt-ioc processing
+	 */
+	if ((ret == 0) && ((r = SendIocInit(ioc, sleepFlag)) != 0))
+		ret = -4;
 // NEW!
 	if (alt_ioc_ready && ((r = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
 		printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
 				ioc->alt_ioc->name, r);
 		alt_ioc_ready = 0;
+		reset_alt_ioc_active = 0;
 	}
 
 	if (alt_ioc_ready) {
 		if ((r = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
 			alt_ioc_ready = 0;
+			reset_alt_ioc_active = 0;
 			printk(KERN_WARNING MYNAM
 				": alt-%s: (%d) init failure WARNING!\n",
 					ioc->alt_ioc->name, r);
@@ -1840,9 +1882,14 @@
 			ddlprintk((MYIOC_s_INFO_FMT
 				"firmware upload required!\n", ioc->name));
 
-			r = mpt_do_upload(ioc, sleepFlag);
-			if (r != 0)
-				printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
+			/* Controller is not operational, cannot do upload
+			 */
+			if (ret == 0) {
+				r = mpt_do_upload(ioc, sleepFlag);
+				if (r != 0)
+					printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
+			}
+
 			/* Handle the alt IOC too */
 			if ((alt_ioc_ready) && (ioc->alt_ioc->upload_fw)){
 				ddlprintk((MYIOC_s_INFO_FMT
@@ -1855,12 +1902,13 @@
 		}
 	}
 
+	if (ret == 0) {
+		/* Enable! (reply interrupt) */
+		CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
+		ioc->active = 1;
+	}
 
-	/* Enable! (reply interrupt) */
-	CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
-	ioc->active = 1;
-
-	if (ioc->alt_ioc) {
+	if (reset_alt_ioc_active && ioc->alt_ioc) {
 		/* (re)Enable alt-IOC! (reply interrupt) */
 		dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
 				ioc->alt_ioc->name));
@@ -1872,7 +1920,7 @@
 	 *  Enable MPT base driver management of EventNotification
 	 *  and EventAck handling.
 	 */
-	if (!ioc->facts.EventState)
+	if ((ret == 0) && (!ioc->facts.EventState))
 		(void) SendEventNotification(ioc, 1);	/* 1=Enable EventNotification */
 
 	if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
@@ -1886,7 +1934,7 @@
 	 *	routine calls HardResetHandler, which calls into here again,
 	 *	and we try GetLanConfigPages again...
 	 */
-	if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
+	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
 		if ((int)ioc->chip_type <= (int)FC929) {
 			/*
 			 *  Pre-fetch FC port WWN and stuff...
@@ -1928,6 +1976,8 @@
 			/* Check, and possibly reset, the coalescing value
 			 */
 			mpt_read_ioc_pg_1(ioc);
+
+			mpt_read_ioc_pg_4(ioc);
 		}
 
 		GetIoUnitPage2(ioc);
@@ -1942,24 +1992,24 @@
 	if (hard_reset_done) {
 		r = handlers = 0;
 		for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
-			if (MptResetHandlers[ii]) {
+			if ((ret == 0) && MptResetHandlers[ii]) {
 				dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
 						ioc->name, ii));
 				r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
 				handlers++;
+			}
 
-				if (alt_ioc_ready) {
-					dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
-							ioc->name, ioc->alt_ioc->name, ii));
-					r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
-					handlers++;
-				}
+			if (alt_ioc_ready && MptResetHandlers[ii]) {
+				dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
+						ioc->name, ioc->alt_ioc->name, ii));
+				r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
+				handlers++;
 			}
 		}
 		/* FIXME?  Examine results here? */
 	}
 
-	return 0;
+	return ret;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2114,6 +2164,15 @@
 			kfree(this->spi_data.pIocPg3);
 			this->spi_data.pIocPg3 = NULL;
 		}
+
+		if (freeup && this->spi_data.pIocPg4 != NULL) {
+			sz = this->spi_data.IocPg4Sz;
+			pci_free_consistent(this->pcidev, sz,
+				this->spi_data.pIocPg4,
+				this->spi_data.IocPg4_dma);
+			this->spi_data.pIocPg4 = NULL;
+			this->alloc_total -= sz;
+		}
 	}
 }
 
@@ -2429,7 +2488,7 @@
 	 * 1 byte in size, so we can just fire it off as is.
 	 */
 	r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
-			reply_sz, (u16*)facts, 3 /*seconds*/, sleepFlag);
+			reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
 	if (r != 0)
 		return r;
 
@@ -2510,7 +2569,7 @@
 			 */
 			ioc->req_sz = MIN(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
 			ioc->req_depth = MIN(MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
-			ioc->reply_sz = ioc->req_sz;
+			ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
 			ioc->reply_depth = MIN(MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
 
 			dprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
@@ -2578,7 +2637,7 @@
 	 * 1 byte in size, so we can just fire it off as is.
 	 */
 	ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
-				reply_sz, (u16*)pfacts, 3 /*seconds*/, sleepFlag);
+				reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
 	if (ii != 0)
 		return ii;
 
@@ -2651,6 +2710,8 @@
 /*	ioc_init.MsgFlags = 0;				*/
 /*	ioc_init.MsgContext = cpu_to_le32(0x00000000);	*/
 	ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);	/* in BYTES */
+		
+	ioc->facts.RequestFrameSize = ioc_init.ReplyFrameSize;
 
 	if (sizeof(dma_addr_t) == sizeof(u64)) {
 		/* Save the upper 32-bits of the request
@@ -2663,6 +2724,9 @@
 		ioc_init.HostMfaHighAddr = cpu_to_le32(0);
 		ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
 	}
+		
+	ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
+	ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
 
 	dprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
 			ioc->name, &ioc_init));
@@ -2773,8 +2837,8 @@
 void *
 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz)
 {
-	fw_image_t	**cached_fw = NULL;
-	u8		*mem = NULL;
+	fw_image_t	**cached_fw;
+	u8		*mem;
 	dma_addr_t	fw_dma;
 	int		alloc_total = 0;
 	int		bytes_left, bytes, num_frags;
@@ -2922,7 +2986,7 @@
 	u8			 reply[sizeof(FWUploadReply_t)];
 	FWUpload_t		*prequest;
 	FWUploadReply_t		*preply;
-	FWUploadTCSGE_t		*ptcsge = NULL;
+	FWUploadTCSGE_t		*ptcsge;
 	int			 sgeoffset;
 	int			 ii, sz, reply_sz;
 	int			 cmdStatus, freeMem = 0;
@@ -3054,16 +3118,16 @@
 static int
 mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
 {
-	MpiFwHeader_t		*FwHdr = NULL;
+	MpiFwHeader_t		*FwHdr;
 	MpiExtImageHeader_t 	*ExtHdr;
-	fw_image_t		**pCached = NULL;
+	fw_image_t		**pCached=NULL;
 	int			 fw_sz;
 	u32			 diag0val;
 #ifdef MPT_DEBUG
 	u32			 diag1val = 0;
 #endif
 	int			 count = 0;
-	u32			*ptru32 = NULL;
+	u32			*ptru32;
 	u32			 diagRwData;
 	u32			 nextImage;
 	u32			 ext_offset;
@@ -3097,11 +3161,11 @@
 		pCached = (fw_image_t **)ioc->cached_fw;
 	else if (ioc->alt_ioc && (ioc->alt_ioc->cached_fw != NULL))
 		pCached = (fw_image_t **)ioc->alt_ioc->cached_fw;
+	else
+		return -2;
 
 	ddlprintk((MYIOC_s_INFO_FMT "DbGb2: FW Image @ %p\n",
 			ioc->name, pCached));
-	if (!pCached)
-		return -2;
 
 	/* Write magic sequence to WriteSequence register
 	 * until enter diagnostic mode
@@ -3351,6 +3415,7 @@
 		SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
 
 		if (sleepFlag == CAN_SLEEP) {
+			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(HZ);
 		} else {
 			mdelay (1000);
@@ -3551,11 +3616,11 @@
 		} else {
 			/* Wait for FW to reload and for board
 			 * to go to the READY state.
-			 * Maximum wait is 30 seconds.
+			 * Maximum wait is 60 seconds.
 			 * If fail, no error will check again
 			 * with calling program.
 			 */
-			for (count = 0; count < 30; count ++) {
+			for (count = 0; count < 60; count ++) {
 				doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
 				doorbell &= MPI_IOC_STATE_MASK;
 
@@ -3673,7 +3738,7 @@
 	dprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
 			ioc->name, reset_type));
 	CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
-	if ((r = WaitForDoorbellAck(ioc, 2, sleepFlag)) < 0)
+	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
 		return r;
 
 	/* FW ACK'd request, wait for READY state
@@ -3736,7 +3801,11 @@
 
 	if (ioc->reply_frames == NULL) {
 		sz = (ioc->reply_sz * ioc->reply_depth) + 128;
+#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX)
+		mem = pci_alloc_consistent(&ioc->pcidev32, sz, &ioc->reply_alloc_dma);
+#else		
 		mem = pci_alloc_consistent(ioc->pcidev, sz, &ioc->reply_alloc_dma);
+#endif		
 		if (mem == NULL)
 			goto out_fail;
 
@@ -3778,7 +3847,11 @@
 		 */
 		sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
 
+#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX)
+		mem = pci_alloc_consistent(&ioc->pcidev32, sz, &ioc->req_alloc_dma);
+#else
 		mem = pci_alloc_consistent(ioc->pcidev, sz, &ioc->req_alloc_dma);
+#endif		
 		if (mem == NULL)
 			goto out_fail;
 
@@ -3894,8 +3967,8 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *	mpt_handshake_req_reply_wait - Send MPT request to and receive reply from
- *	IOC via doorbell handshake method.
+ *	mpt_handshake_req_reply_wait - Send MPT request to and receive reply
+ *	from IOC via doorbell handshake method.
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@reqBytes: Size of the request in bytes
  *	@req: Pointer to MPT request frame
@@ -3955,7 +4028,7 @@
 	 * our handshake request.
 	 */
 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-	if (!failcnt && (t = WaitForDoorbellAck(ioc, 2, sleepFlag)) < 0)
+	if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
 		failcnt++;
 
 	if (!failcnt) {
@@ -3973,7 +4046,7 @@
 				    (req_as_bytes[(ii*4) + 3] << 24));
 
 			CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
-			if ((t = WaitForDoorbellAck(ioc, 2, sleepFlag)) < 0)
+			if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
 				failcnt++;
 		}
 
@@ -4137,7 +4210,7 @@
 	} else {
 		hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-		if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
+		if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
 			failcnt++;
 		else {
 			hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
@@ -4154,7 +4227,7 @@
 	 * reply 16 bits at a time.
 	 */
 	for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
-		if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
+		if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
 			failcnt++;
 		hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
 		/* don't overflow our IOC hs_reply[] buffer! */
@@ -4163,7 +4236,7 @@
 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 	}
 
-	if (!failcnt && (t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
+	if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
 		failcnt++;
 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 
@@ -4466,7 +4539,7 @@
 static int
 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
 {
-	u8			*pbuf = NULL;
+	u8			*pbuf;
 	dma_addr_t		 buf_dma;
 	CONFIGPARMS		 cfg;
 	ConfigPageHeader_t	 header;
@@ -4528,6 +4601,9 @@
 				pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
 				pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
 
+				if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 )
+					ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
+
 				ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
 				data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
 				if (data) {
@@ -4552,7 +4628,6 @@
 			}
 			if (pbuf) {
 				pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
-				pbuf = NULL;
 			}
 		}
 	}
@@ -4589,6 +4664,8 @@
 				/* Save the Port Page 2 data
 				 * (reformat into a 32bit quantity)
 				 */
+				data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
+				ioc->spi_data.PortFlags = data;
 				for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
 					pdevice = &pPP2->DeviceSettings[ii];
 					data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
@@ -4598,7 +4675,6 @@
 			}
 
 			pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
-			pbuf = NULL;
 		}
 	}
 
@@ -4671,11 +4747,12 @@
  *	-EFAULT if read of config page header fails or data pointer not NULL
  *	-ENOMEM if pci_alloc failed
  */
-static int
+int
 mpt_findImVolumes(MPT_ADAPTER *ioc)
 {
-	IOCPage2_t		*pIoc2 = NULL;
-	ConfigPageIoc2RaidVol_t	*pIocRv = NULL;
+	IOCPage2_t		*pIoc2;
+	u8			*mem;
+	ConfigPageIoc2RaidVol_t	*pIocRv;
 	dma_addr_t		 ioc2_dma;
 	CONFIGPARMS		 cfg;
 	ConfigPageHeader_t	 header;
@@ -4685,9 +4762,6 @@
 	u8			 nVols, nPhys;
 	u8			 vid, vbus, vioc;
 
-	if (ioc->spi_data.pIocPg3)
-		return -EFAULT;	
-
 	/* Read IOCP2 header then the page.
 	 */
 	header.PageVersion = 0;
@@ -4716,11 +4790,22 @@
 	if (mpt_config(ioc, &cfg) != 0)
 		goto done_and_free;
 
+	if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
+		mem = kmalloc(iocpage2sz, GFP_ATOMIC);
+		if (mem) {
+			ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
+		} else {
+			goto done_and_free;
+		}
+	}
+	memcpy(mem, (u8 *)pIoc2, iocpage2sz);
+
 	/* Identify RAID Volume Id's */
 	nVols = pIoc2->NumActiveVolumes;
 	if ( nVols == 0) {
-		/* No RAID Volumes.  Done.
+		/* No RAID Volume.
 		 */
+		goto done_and_free;
 	} else {
 		/* At least 1 RAID Volume
 		 */
@@ -4745,17 +4830,14 @@
 	/* Identify Hidden Physical Disk Id's */
 	nPhys = pIoc2->NumActivePhysDisks;
 	if (nPhys == 0) {
-		/* No physical disks. Done.
+		/* No physical disks.
 		 */
 	} else {
 		mpt_read_ioc_pg_3(ioc);
 	}
 
 done_and_free:
-	if (pIoc2) {
-		pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
-		pIoc2 = NULL;
-	}
+	pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
 
 	return rc;
 }
@@ -4763,7 +4845,7 @@
 int
 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
 {
-	IOCPage3_t		*pIoc3 = NULL;
+	IOCPage3_t		*pIoc3;
 	u8			*mem;
 	CONFIGPARMS		 cfg;
 	ConfigPageHeader_t	 header;
@@ -4816,18 +4898,66 @@
 		}
 	}
 
-	if (pIoc3) {
-		pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
-		pIoc3 = NULL;
-	}
+	pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
 
 	return 0;
 }
 
 static void
+mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
+{
+	IOCPage4_t		*pIoc4;
+	CONFIGPARMS		 cfg;
+	ConfigPageHeader_t	 header;
+	dma_addr_t		 ioc4_dma;
+	int			 iocpage4sz;
+
+	/* Read and save IOC Page 4
+	 */
+	header.PageVersion = 0;
+	header.PageLength = 0;
+	header.PageNumber = 4;
+	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
+	cfg.hdr = &header;
+	cfg.physAddr = -1;
+	cfg.pageAddr = 0;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+	cfg.dir = 0;
+	cfg.timeout = 0;
+	if (mpt_config(ioc, &cfg) != 0)
+		return;
+
+	if (header.PageLength == 0)
+		return;
+
+	if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
+		iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
+		pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
+		if (!pIoc4)
+			return;
+	} else {
+		ioc4_dma = ioc->spi_data.IocPg4_dma;
+		iocpage4sz = ioc->spi_data.IocPg4Sz;
+	}
+
+	/* Read the Page into dma memory.
+	 */
+	cfg.physAddr = ioc4_dma;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+	if (mpt_config(ioc, &cfg) == 0) {
+		ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
+		ioc->spi_data.IocPg4_dma = ioc4_dma;
+		ioc->spi_data.IocPg4Sz = iocpage4sz;
+	} else {
+		pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
+		ioc->spi_data.pIocPg4 = NULL;
+	}
+}
+
+static void
 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
 {
-	IOCPage1_t		*pIoc1 = NULL;
+	IOCPage1_t		*pIoc1;
 	CONFIGPARMS		 cfg;
 	ConfigPageHeader_t	 header;
 	dma_addr_t		 ioc1_dma;
@@ -4903,10 +5033,7 @@
 		}
 	}
 
-	if (pIoc1) {
-		pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
-		pIoc1 = NULL;
-	}
+	pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
 
 	return;
 }
@@ -5022,9 +5149,8 @@
 	pReq->Reserved = 0;
 	pReq->ChainOffset = 0;
 	pReq->Function = MPI_FUNCTION_CONFIG;
-	pReq->Reserved1[0] = 0;
-	pReq->Reserved1[1] = 0;
-	pReq->Reserved1[2] = 0;
+	pReq->ExtPageLength = 0;
+	pReq->ExtPageType = 0;
 	pReq->MsgFlags = 0;
 	for (ii=0; ii < 8; ii++)
 		pReq->Reserved2[ii] = 0;
@@ -5083,6 +5209,112 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mpt_toolbox - Generic function to issue toolbox message
+ *	@ioc - Pointer to an adapter structure
+ *	@cfg - Pointer to a toolbox structure. Struct contains
+ *		action, page address, direction, physical address
+ *		and pointer to a configuration page header
+ *		Page header is updated.
+ *
+ *	Returns 0 for success
+ *	-EPERM if not allowed due to ISR context
+ *	-EAGAIN if no msg frames currently available
+ *	-EFAULT for non-successful reply or no reply (timeout)
+ */
+int
+mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
+{
+	ToolboxIstwiReadWriteRequest_t	*pReq;
+	MPT_FRAME_HDR	*mf;
+	unsigned long	 flags;
+	int		 rc;
+	int		 flagsLength;
+	int		 in_isr;
+
+	/* (Bugzilla:fibrebugs, #513)
+	 * Bug fix (part 1)!  20010905 -sralston
+	 *	Prevent calling wait_event() (below), if caller happens
+	 *	to be in ISR context, because that is fatal!
+	 */
+	in_isr = in_interrupt();
+	if (in_isr) {
+		dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
+				ioc->name));
+		return -EPERM;
+	}
+
+	/* Get and Populate a free Frame
+	 */
+	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) {
+		dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
+				ioc->name));
+		return -EAGAIN;
+	}
+	pReq = (ToolboxIstwiReadWriteRequest_t	*)mf;
+	pReq->Tool = pCfg->action;
+	pReq->Reserved = 0;
+	pReq->ChainOffset = 0;
+	pReq->Function = MPI_FUNCTION_TOOLBOX;
+	pReq->Reserved1 = 0;
+	pReq->Reserved2 = 0;
+	pReq->MsgFlags = 0;
+	pReq->Flags = pCfg->dir;
+	pReq->BusNum = 0;
+	pReq->Reserved3 = 0;
+	pReq->NumAddressBytes = 0x01;
+	pReq->Reserved4 = 0;
+	pReq->DataLength = 0x04;
+	pReq->DeviceAddr = 0xB0;
+	pReq->Addr1 = 0;
+	pReq->Addr2 = 0;
+	pReq->Addr3 = 0;
+	pReq->Reserved5 = 0;
+
+	/* Add a SGE to the config request.
+	 */
+
+	flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
+
+	mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
+
+	dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
+		ioc->name, pReq->Tool));
+
+	/* Append pCfg pointer to end of mf
+	 */
+	*((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) =  (void *) pCfg;
+
+	/* Initalize the timer
+	 */
+	init_timer(&pCfg->timer);
+	pCfg->timer.data = (unsigned long) ioc;
+	pCfg->timer.function = mpt_timer_expired;
+	pCfg->wait_done = 0;
+
+	/* Set the timer; ensure 10 second minimum */
+	if (pCfg->timeout < 10)
+		pCfg->timer.expires = jiffies + HZ*10;
+	else
+		pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
+
+	/* Add to end of Q, set timer and then issue this command */
+	spin_lock_irqsave(&ioc->FreeQlock, flags);
+	Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM);
+	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+
+	add_timer(&pCfg->timer);
+	mpt_put_msg_frame(mpt_base_index, ioc->id, mf);
+	wait_event(mpt_waitq, pCfg->wait_done);
+
+	/* mf has been freed - do not access */
+
+	rc = pCfg->status;
+
+	return rc;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	mpt_timer_expired - Call back for timer process.
  *	Used only internal config functionality.
@@ -5124,9 +5356,12 @@
 
 	dprintk((KERN_WARNING MYNAM
 			": IOC %s_reset routed to MPT base driver!\n",
-			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+			reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
+			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
 
-	if (reset_phase == MPT_IOC_PRE_RESET) {
+	if (reset_phase == MPT_IOC_SETUP_RESET) {
+		;
+	} else if (reset_phase == MPT_IOC_PRE_RESET) {
 		/* If the internal config Q is not empty -
 		 * delete timer. MF resources will be freed when
 		 * the FIFO's are primed.
@@ -5590,7 +5825,7 @@
 	int		 rc;
 	unsigned long	 flags;
 
-	dprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
+	dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
 #ifdef MFCNT
 	printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
 	printk("MF count 0x%x !\n", ioc->mfcnt);
@@ -5611,6 +5846,29 @@
 	/* FIXME: If do_ioc_recovery fails, repeat....
 	 */
 
+	/* The SCSI driver needs to adjust timeouts on all current
+	 * commands prior to the diagnostic reset being issued.
+	 * Prevents timeouts occuring during a diagnostic reset...very bad.
+	 * For all other protocol drivers, this is a no-op.
+	 */
+	{
+		int	 ii;
+		int	 r = 0;
+
+		for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
+			if (MptResetHandlers[ii]) {
+				dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
+						ioc->name, ii));
+				r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
+				if (ioc->alt_ioc) {
+					dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
+							ioc->name, ioc->alt_ioc->name, ii));
+					r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
+				}
+			}
+		}
+	}
+
 	if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
 		printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
 			rc, ioc->name);
@@ -5625,7 +5883,7 @@
 		ioc->alt_ioc->diagPending = 0;
 	spin_unlock_irqrestore(&ioc->diagLock, flags);
 
-	dprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
+	dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
 
 	return rc;
 }
@@ -5634,7 +5892,7 @@
 static char *
 EventDescriptionStr(u8 event, u32 evData0)
 {
-	char *ds = NULL;
+	char *ds;
 
 	switch(event) {
 	case MPI_EVENT_NONE:
@@ -5839,109 +6097,11 @@
 		"FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
 		"FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
 	};
-	char *desc = "unknown";
 	u8 subcl = (log_info >> 24) & 0x7;
-	u32 SubCl = log_info & 0x27000000;
-
-	switch(log_info) {
-/* FCP Initiator */
-	case MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME:
-		desc = "Received an out of order frame - unsupported";
-		break;
-	case MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME:
-		desc = "Bad start of frame primative";
-		break;
-	case MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME:
-		desc = "Bad end of frame primative";
-		break;
-	case MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN:
-		desc = "Receiver hardware detected overrun";
-		break;
-	case MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER:
-		desc = "Other errors caught by IOC which require retries";
-		break;
-	case MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD:
-		desc = "Main processor could not initialize sub-processor";
-		break;
-/* FC Target */
-	case MPI_IOCLOGINFO_FC_TARGET_NO_PDISC:
-		desc = "Not sent because we are waiting for a PDISC from the initiator";
-		break;
-	case MPI_IOCLOGINFO_FC_TARGET_NO_LOGIN:
-		desc = "Not sent because we are not logged in to the remote node";
-		break;
-	case MPI_IOCLOGINFO_FC_TARGET_DOAR_KILLED_BY_LIP:
-		desc = "Data Out, Auto Response, not sent due to a LIP";
-		break;
-	case MPI_IOCLOGINFO_FC_TARGET_DIAR_KILLED_BY_LIP:
-		desc = "Data In, Auto Response, not sent due to a LIP";
-		break;
-	case MPI_IOCLOGINFO_FC_TARGET_DIAR_MISSING_DATA:
-		desc = "Data In, Auto Response, missing data frames";
-		break;
-	case MPI_IOCLOGINFO_FC_TARGET_DONR_KILLED_BY_LIP:
-		desc = "Data Out, No Response, not sent due to a LIP";
-		break;
-	case MPI_IOCLOGINFO_FC_TARGET_WRSP_KILLED_BY_LIP:
-		desc = "Auto-response after a write not sent due to a LIP";
-		break;
-	case MPI_IOCLOGINFO_FC_TARGET_DINR_KILLED_BY_LIP:
-		desc = "Data In, No Response, not completed due to a LIP";
-		break;
-	case MPI_IOCLOGINFO_FC_TARGET_DINR_MISSING_DATA:
-		desc = "Data In, No Response, missing data frames";
-		break;
-	case MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP:
-		desc = "Manual Response not sent due to a LIP";
-		break;
-	case MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3:
-		desc = "Not sent because remote node does not support Class 3";
-		break;
-	case MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID:
-		desc = "Not sent because login to remote node not validated";
-		break;
-	case MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND:
-		desc = "Cleared from the outbound queue after a logout";
-		break;
-	case MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN:
-		desc = "Cleared waiting for data after a logout";
-		break;
-/* LAN */
-	case MPI_IOCLOGINFO_FC_LAN_TRANS_SGL_MISSING:
-		desc = "Transaction Context Sgl Missing";
-		break;
-	case MPI_IOCLOGINFO_FC_LAN_TRANS_WRONG_PLACE:
-		desc = "Transaction Context found before an EOB";
-		break;
-	case MPI_IOCLOGINFO_FC_LAN_TRANS_RES_BITS_SET:
-		desc = "Transaction Context value has reserved bits set";
-		break;
-	case MPI_IOCLOGINFO_FC_LAN_WRONG_SGL_FLAG:
-		desc = "Invalid SGL Flags";
-		break;
-/* FC Link */
-	case MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT:
-		desc = "Loop initialization timed out";
-		break;
-	case MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED:
-		desc = "Another system controller already initialized the loop";
-		break;
-	case MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED:
-		desc = "Not synchronized to signal or still negotiating (possible cable problem)";
-		break;
-	case MPI_IOCLOGINFO_FC_LINK_CRC_ERROR:
-		desc = "CRC check detected error on received frame";
-		break;
-	}
+//	u32 SubCl = log_info & 0x27000000;
 
 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}",
 			ioc->name, log_info, subcl_str[subcl]);
-	if (SubCl == MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET)
-		printk(", byte_offset=%d\n", log_info & MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET);
-	else if (SubCl == MPI_IOCLOGINFO_FC_STATE_CHANGE)
-		printk("\n");		/* StateChg in LogInfo & 0x00FFFFFF, above */
-	else
-		printk("\n" KERN_INFO " %s\n", desc);
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -6021,7 +6181,6 @@
 		isense_idx = last_drv_idx;
 		r = 1;
 	}
-	mpt_inc_use_count();
 	return r;
 }
 
@@ -6040,7 +6199,6 @@
 	mpt_ScsiOpcodesPtr = NULL;
 	printk(KERN_INFO MYNAM ": English readable SCSI-3 strings disabled)-:\n");
 	isense_idx = -1;
-	mpt_dec_use_count();
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -6072,6 +6230,8 @@
 EXPORT_SYMBOL(mpt_stm_index);
 EXPORT_SYMBOL(mpt_HardResetHandler);
 EXPORT_SYMBOL(mpt_config);
+EXPORT_SYMBOL(mpt_toolbox);
+EXPORT_SYMBOL(mpt_findImVolumes);
 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
 EXPORT_SYMBOL(mpt_alloc_fw_memory);
 EXPORT_SYMBOL(mpt_free_fw_memory);
diff -Nru a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
--- a/drivers/message/fusion/mptbase.h	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/mptbase.h	Wed Mar 10 21:09:42 2004
@@ -8,7 +8,7 @@
  *  Credits:
  *     (see mptbase.c)
  *
- *  Copyright (c) 1999-2003 LSI Logic Corporation
+ *  Copyright (c) 1999-2004 LSI Logic Corporation
  *  Originally By: Steven J. Ralston
  *  (mailto:sjralston1@netscape.net)
  *  (mailto:mpt_linux_developer@lsil.com)
@@ -68,6 +68,7 @@
 
 #include "lsi/mpi_fc.h"		/* Fibre Channel (lowlevel) support */
 #include "lsi/mpi_targ.h"	/* SCSI/FCP Target protcol support */
+#include "lsi/mpi_tool.h"	/* Tools support */
 #include "lsi/fc_log.h"
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -77,11 +78,11 @@
 #endif
 
 #ifndef COPYRIGHT
-#define COPYRIGHT	"Copyright (c) 1999-2003 " MODULEAUTHOR
+#define COPYRIGHT	"Copyright (c) 1999-2004 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"3.00.03"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.00.03"
+#define MPT_LINUX_VERSION_COMMON	"3.01.00"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.01.00"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -93,10 +94,10 @@
  */
 #define MPT_MAX_ADAPTERS		18
 #define MPT_MAX_PROTOCOL_DRIVERS	16
-#define MPT_MAX_BUS			1
+#define MPT_MAX_BUS			1	/* Do not change */
 #define MPT_MAX_FC_DEVICES		255
 #define MPT_MAX_SCSI_DEVICES		16
-#define MPT_LAST_LUN			31
+#define MPT_LAST_LUN			255
 #define MPT_SENSE_BUFFER_ALLOC		64
 	/* allow for 256 max sense alloc, but only 255 max request */
 #if MPT_SENSE_BUFFER_ALLOC >= 256
@@ -127,6 +128,8 @@
 #define  MPT_MAX_FRAME_SIZE		128
 #define  MPT_DEFAULT_FRAME_SIZE		128
 
+#define  MPT_REPLY_FRAME_SIZE		0x40  /* Must be a multiple of 8 */
+
 #define  MPT_SG_REQ_128_SCALE		1
 #define  MPT_SG_REQ_96_SCALE		2
 #define  MPT_SG_REQ_64_SCALE		4
@@ -150,6 +153,9 @@
 #define MPT_NARROW			0
 #define MPT_WIDE			1
 
+#define C0_1030				0x08
+#define XL_929				0x01
+
 #ifdef __KERNEL__	/* { */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
@@ -185,8 +191,8 @@
 	void (*remove) (struct pci_dev *dev);
 	void (*shutdown) (struct device * dev);
 #ifdef CONFIG_PM
-	int  (*suspend) (struct pci_dev *dev, u32 state);
 	int  (*resume) (struct pci_dev *dev);
+	int  (*suspend) (struct pci_dev *dev, u32 state);
 #endif
 };
 
@@ -201,9 +207,6 @@
 		u32			 arg1;
 		u32			 pad;
 		void			*argp1;
-#ifndef MPT_SCSI_USE_NEW_EH
-		void			*argp2;
-#endif
 	} linkage;
 	/*
 	 * NOTE: When request frames are free, on the linkage structure
@@ -255,6 +258,7 @@
 		MPIHeader_t		hdr;
 		SCSIIORequest_t		scsireq;
 		SCSIIOReply_t		sreply;
+		ConfigReply_t		configreply;
 		MPIDefaultReply_t	reply;
 		MPT_FRAME_TRACKER	frame;
 	} u;
@@ -408,12 +412,9 @@
 	ScsiCmndTracker		 SentQ;
 	ScsiCmndTracker		 DoneQ;
 	u32			 num_luns;
-//--- LUN split here?
-	u32			 luns;		/* Max LUNs is 32 */
-	u8			 inq_data[SCSI_STD_INQUIRY_BYTES];	/* 36 */
-	u8			 pad0[4];
-	u8			 inq00_data[20];
-	u8			 pad1[4];
+	u32			 luns[8];		/* Max LUNs is 256 */
+	u8			 pad[4];
+	u8			 inq_data[8];
 		/* IEEE Registered Extended Identifier
 		   obtained via INQUIRY VPD page 0x83 */
 		/* NOTE: Do not separate uniq_prepad and uniq_data
@@ -421,26 +422,17 @@
 	u8			 uniq_prepad[8];
 	u8			 uniq_data[20];
 	u8			 pad2[4];
-	u8			 inqC3_data[12];
-	u8			 pad3[4];
-	u8			 inqC9_data[12];
-	u8			 pad4[4];
-	u8			 dev_vol_name[64];
 } VirtDevice;
 
 /*
  *  Fibre Channel (SCSI) target device and associated defines...
  */
-#define MPT_TARGET_DEFAULT_DV_STATUS	0
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,55)
-#define MPT_TARGET_FLAGS_CONFIGURED	0x02
-#define MPT_TARGET_FLAGS_Q_YES		0x08
-#else
+#define MPT_TARGET_DEFAULT_DV_STATUS	0x00
 #define MPT_TARGET_FLAGS_VALID_NEGO	0x01
 #define MPT_TARGET_FLAGS_VALID_INQUIRY	0x02
 #define MPT_TARGET_FLAGS_Q_YES		0x08
 #define MPT_TARGET_FLAGS_VALID_56	0x10
-#endif
+#define MPT_TARGET_FLAGS_SAF_TE_ISSUED	0x20
 
 #define MPT_TARGET_NO_NEGO_WIDE		0x01
 #define MPT_TARGET_NO_NEGO_SYNC		0x02
@@ -539,8 +531,13 @@
 /* #define MPT_SCSICFG_BLK_NEGO		0x10	   WriteSDP1 with WDTR and SDTR disabled */
 
 typedef	struct _ScsiCfgData {
+	u32		 PortFlags;
 	int		*nvram;			/* table of device NVRAM values */
+	IOCPage2_t	*pIocPg2;		/* table of Raid Volumes */
 	IOCPage3_t	*pIocPg3;		/* table of physical disks */
+	IOCPage4_t	*pIocPg4;		/* SEP devices addressing */
+	dma_addr_t	 IocPg4_dma;		/* Phys Addr of IOCPage4 data */
+	int		 IocPg4Sz;		/* IOCPage4 size */
 	u8		 dvStatus[MPT_MAX_SCSI_DEVICES];
 	int		 isRaid;		/* bit field, 1 if RAID */
 	u8		 minSyncFactor;		/* 0xFF if async */
@@ -554,7 +551,8 @@
 	u8		 dvScheduled;		/* 1 if scheduled */
 	u8		 forceDv;		/* 1 to force DV scheduling */
 	u8		 noQas;			/* Disable QAS for this adapter */
-	u8		 rsvd[2];
+	u8		 Saf_Te;		/* 1 to force all Processors as SAF-TE if Inquiry data length is too short to check for SAF-TE */
+	u8		 rsvd[1];
 } ScsiCfgData;
 
 typedef struct _fw_image {
@@ -610,6 +608,9 @@
 	u32			 sense_buf_low_dma;
 	int			 mtrr_reg;
 	struct pci_dev		*pcidev;	/* struct pci_dev pointer */
+#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX)
+	struct pci_dev		pcidev32;	/* struct pci_dev pointer */
+#endif	
 	u8			*memmap;	/* mmap address */
 	struct Scsi_Host	*sh;		/* Scsi Host pointer */
 	ScsiCfgData		spi_data;	/* Scsi config. data */
@@ -622,6 +623,12 @@
 	int			 eventTypes;	/* Event logging parameters */
 	int			 eventContext;	/* Next event context */
 	int			 eventLogSize;	/* Max number of cached events */
+#ifdef MPTSCSIH_DBG_TIMEOUT
+	int			timeout_hard;
+	int			timeout_delta;
+	int			timeout_cnt;
+	int			timeout_maxcnt;
+#endif
 	struct _mpt_ioctl_events *events;	/* pointer to event log */
 	fw_image_t		**cached_fw;	/* Pointer to FW SG List */
 	Q_TRACKER		 configQ;	/* linked list of config. requests */
@@ -665,6 +672,7 @@
 /* reset_phase defs */
 #define MPT_IOC_PRE_RESET		0
 #define MPT_IOC_POST_RESET		1
+#define MPT_IOC_SETUP_RESET		2
 
 /*
  * Invent MPT host event (super-set of MPI Events)
@@ -880,14 +888,12 @@
 #define MPT_NVRAM_WIDE_DISABLE		(0x00100000)
 #define MPT_NVRAM_BOOT_CHOICE		(0x00200000)
 
-#ifdef MPT_SCSI_USE_NEW_EH
 /* The TM_STATE variable is used to provide strict single threading of TM
  * requests as well as communicate TM error conditions.
  */
 #define TM_STATE_NONE          (0)
 #define	TM_STATE_IN_PROGRESS   (1)
 #define	TM_STATE_ERROR	       (2)
-#endif
 
 typedef struct _MPT_SCSI_HOST {
 	MPT_ADAPTER		 *ioc;
@@ -928,12 +934,8 @@
 	u8			  is_spi;		/* Parallel SCSI i/f */
 	u8			  negoNvram;		/* DV disabled, nego NVRAM */
 	u8			  is_multipath;		/* Multi-path compatible */
-#ifdef MPT_SCSI_USE_NEW_EH
 	u8                        tmState;
 	u8			  rsvd[1];
-#else
-	u8			  rsvd[2];
-#endif
 	MPT_FRAME_HDR		 *tmPtr;		/* Ptr to TM request*/
 	MPT_FRAME_HDR		 *cmdPtr;		/* Ptr to nonOS request */
 	struct scsi_cmnd	 *abortSCpnt;
@@ -1033,8 +1035,10 @@
 extern void	 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
 extern int	 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
 extern int	 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
+extern int	 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
 extern void	*mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz);
 extern void	 mpt_free_fw_memory(MPT_ADAPTER *ioc, fw_image_t **alt_img);
+extern int	 mpt_findImVolumes(MPT_ADAPTER *ioc);
 extern int	 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
 
 /*
diff -Nru a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
--- a/drivers/message/fusion/mptctl.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/mptctl.c	Wed Mar 10 21:09:42 2004
@@ -29,7 +29,7 @@
  *
  *      (see also mptbase.c)
  *
- *  Copyright (c) 1999-2003 LSI Logic Corporation
+ *  Copyright (c) 1999-2004 LSI Logic Corporation
  *  Originally By: Steven J. Ralston, Noah Romer
  *  (mailto:sjralston1@netscape.net)
  *  (mailto:mpt_linux_developer@lsil.com)
@@ -82,6 +82,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/miscdevice.h>
+#include <linux/smp_lock.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -91,7 +92,7 @@
 #include "../../scsi/scsi.h"
 #include "../../scsi/hosts.h"
 
-#define COPYRIGHT	"Copyright (c) 1999-2003 LSI Logic Corporation"
+#define COPYRIGHT	"Copyright (c) 1999-2004 LSI Logic Corporation"
 #define MODULEAUTHOR	"Steven J. Ralston, Noah Romer, Pamela Delaney"
 #include "mptbase.h"
 #include "mptctl.h"
@@ -260,6 +261,7 @@
 			iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK;
 			if (iocStatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED) {
 				if (ioc->ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE) {
+					ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
 					del_timer (&ioc->ioctl->timer);
 					ioc->ioctl->timer.expires = jiffies + HZ;
 					add_timer(&ioc->ioctl->timer);
@@ -456,7 +458,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
-#ifdef MPT_SCSI_USE_NEW_EH
+
 	if (hd->tmState == TM_STATE_NONE) {
 		hd->tmState = TM_STATE_IN_PROGRESS;
 		hd->tmPending = 1;
@@ -465,15 +467,7 @@
 		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
 		return -EBUSY;
 	}
-#else
-	if (hd->tmPending) {
-		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
-		return -EBUSY;
-	} else {
-		hd->tmPending = 1;
-		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
-	}
-#endif
+
 	return 0;
 }
 
@@ -488,14 +482,10 @@
 		return;
 
 	spin_lock_irqsave(&ioc->FreeQlock, flags);
-#ifdef MPT_SCSI_USE_NEW_EH
+
 	hd->tmState = TM_STATE_ERROR;
 	hd->tmPending = 0;
 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
-#else
-	hd->tmPending = 0;
-	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
-#endif
 
 	return;
 }
@@ -513,9 +503,12 @@
 {
 	MPT_IOCTL *ioctl = ioc->ioctl;
 	dctlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to IOCTL driver!\n",
-			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+			reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
+			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
 
-	if (reset_phase == MPT_IOC_PRE_RESET){
+	if (reset_phase == MPT_IOC_SETUP_RESET){
+		;
+	} else if (reset_phase == MPT_IOC_PRE_RESET){
 
 		/* Someone has called the reset handler to
 		 * do a hard reset. No more replies from the FW.
@@ -532,13 +525,15 @@
 		}
 
 	} else {
+		ioctl->tmPtr = NULL;
+
 		/* Set the status and continue IOCTL
 		 * processing. All memory will be free'd
 		 * by originating thread after wake_up is
 		 * called.
 		 */
 		if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE)){
-			ioctl->status = MPT_IOCTL_STATUS_DID_IOCRESET;
+			ioctl->status |= MPT_IOCTL_STATUS_DID_IOCRESET;
 
 			/* Wake up the calling process
 			 */
@@ -620,7 +615,11 @@
 		return -ENODEV;
 	}
 
-
+	if (!iocp->active) {
+		printk(KERN_ERR "%s::mptctl_ioctl() @%d - Controller disabled.\n",
+				__FILE__, __LINE__);
+		return -EFAULT;
+	}
 
 	/* Handle those commands that are just returning
 	 * information stored in the driver.
@@ -691,7 +690,7 @@
 		return -ENODEV; /* (-6) No such device or address */
 	}
 
-	if (mpt_HardResetHandler(iocp, NO_SLEEP) != 0) {
+	if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) {
 		printk (KERN_ERR "%s@%d::mptctl_do_reset - reset failed.\n",
 			__FILE__, __LINE__);
 		return -1;
@@ -1254,10 +1253,10 @@
 	/* Fill in the data and return the structure to the calling
 	 * program
 	 */
-	if (ioc->chip_type == C1030)
-		karg.adapterType = MPT_IOCTL_INTERFACE_SCSI;
-	else
+	if ((int)ioc->chip_type <= (int) FC929)
 		karg.adapterType = MPT_IOCTL_INTERFACE_FC;
+	else
+		karg.adapterType = MPT_IOCTL_INTERFACE_SCSI;
 
 	port = karg.hdr.port;
 
@@ -1307,7 +1306,8 @@
 
 	/* Set the Version Strings.
 	 */
-	strlcpy (karg.driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
+	strncpy (karg.driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
+	karg.driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
 
 	karg.busChangeEvent = 0;
 	karg.hostId = ioc->pfacts[port].PortSCSIID;
@@ -1343,15 +1343,18 @@
 	MPT_ADAPTER		*ioc;
 	struct Scsi_Host	*sh;
 	MPT_SCSI_HOST		*hd;
+	VirtDevice		*vdev;
 	char			*pmem;
 	int			*pdata;
+	IOCPage2_t		*pIoc2;
 	int			iocnum;
 	int			numDevices = 0;
 	unsigned int		max_id;
-	int			ii, jj, lun;
+	int			id, jj, indexed_lun, lun_index;
+	u32			lun;
 	int			maxWordsLeft;
 	int			numBytes;
-	u8			port;
+	u8			port, devType, bus_id;
 
 	dctlprintk(("mptctl_gettargetinfo called.\n"));
 	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
@@ -1418,27 +1421,59 @@
 		 * sh->max_id = maximum target ID + 1
 		 */
 		if (hd && hd->Targets) {
-			ii = 0;
-			while (ii <= max_id) {
-				if (hd->Targets[ii]) {
-					for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
-						lun = (1 << jj);
-						if (hd->Targets[ii]->luns & lun) {
-							numDevices++;
-							*pdata = (jj << 16) | ii;
-							--maxWordsLeft;
-
-							pdata++;
-
-							if (maxWordsLeft <= 0)
-								break;
+			mpt_findImVolumes(ioc);
+			pIoc2 = ioc->spi_data.pIocPg2;
+			for ( id = 0; id <= max_id; id++ ) {
+				if ( pIoc2 && pIoc2->NumActiveVolumes &&
+					( id == pIoc2->RaidVolume[0].VolumeID ) ) {
+					if (maxWordsLeft <= 0) {
+						printk(KERN_ERR "mptctl_gettargetinfo - "
+			"buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices);
+						goto data_space_full;
+					}
+                    			if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 )
+                        			devType = 0x80;
+                    			else
+                        			devType = 0xC0;
+					bus_id = pIoc2->RaidVolume[0].VolumeBus;
+	            			numDevices++;
+                    			*pdata = ( (devType << 24) | (bus_id << 8) | id );
+					dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
+		"volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
+                    			pdata++;
+					--maxWordsLeft;
+            			} else {
+					vdev = hd->Targets[id];
+					if (vdev) {
+						for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
+							lun_index = (jj >> 5);
+							indexed_lun = (jj % 32);
+							lun = (1 << indexed_lun);
+							if (vdev->luns[lun_index] & lun) {
+								if (maxWordsLeft <= 0) {
+									printk(KERN_ERR
+									"mptctl_gettargetinfo - "
+									"buffer is full but more targets are available on ioc %d numDevices=%d\n",
+									iocnum, numDevices);
+									goto data_space_full;
+								}
+								bus_id = vdev->bus_id;
+								numDevices++;
+                            					*pdata = ( (jj << 16) | (bus_id << 8) | id );
+								dctlprintk((KERN_ERR
+								 "mptctl_gettargetinfo - "
+								 "target ioc=%d target=%x numDevices=%d pdata=%p\n",
+								 iocnum, *pdata, numDevices, pdata));
+								pdata++;
+								--maxWordsLeft;
+							}
 						}
 					}
 				}
-				ii++;
 			}
 		}
 	}
+data_space_full:
 	karg.numDevices = numDevices;
 
 	/* Copy part of the data from kernel memory to user memory
@@ -1507,8 +1542,10 @@
 #else
 	karg.chip_type = ioc->chip_type;
 #endif
-	strlcpy (karg.name, ioc->name, MPT_MAX_NAME);
-	strlcpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
+	strncpy (karg.name, ioc->name, MPT_MAX_NAME);
+	karg.name[MPT_MAX_NAME-1]='\0';
+	strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
+	karg.product[MPT_PRODUCT_LENGTH-1]='\0';
 
 	/* Copy the data from kernel memory to user memory
 	 */
@@ -1806,22 +1843,20 @@
 	MPT_FRAME_HDR	*mf = NULL;
 	MPIHeader_t	*hdr;
 	char		*psge;
-	MptSge_t	*this_sge = NULL;
-	MptSge_t	*sglbuf = NULL;
 	struct buflist	bufIn;	/* data In buffer */
 	struct buflist	bufOut; /* data Out buffer */
-	dma_addr_t	sglbuf_dma;
-	dma_addr_t	dma_addr;
+	dma_addr_t	dma_addr_in;
+	dma_addr_t	dma_addr_out;
 	int		dir;	/* PCI data direction */
 	int		sgSize = 0;	/* Num SG elements */
-	int		this_alloc;
-	int		 iocnum, flagsLength;
-	int		 sz, rc = 0;
-	int		 msgContext;
+	int		iocnum, flagsLength;
+	int		sz, rc = 0;
+	int		msgContext;
 	int		tm_flags_set = 0;
 	u16		req_idx;
 
 	dctlprintk(("mptctl_do_mpt_command called.\n"));
+	bufIn.kptr = bufOut.kptr = NULL;
 
 	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
 	    (ioc == NULL)) {
@@ -1848,7 +1883,7 @@
 	if (karg.dataOutSize > 0)
 		sz += sizeof(dma_addr_t) + sizeof(u32);
 
-	if ( sz > ioc->req_sz) {
+	if (sz > ioc->req_sz) {
 		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
 			"Request frame too large (%d) maximum (%d)\n",
 				__FILE__, __LINE__, sz, ioc->req_sz);
@@ -1891,6 +1926,9 @@
 	switch (hdr->Function) {
 	case MPI_FUNCTION_IOC_FACTS:
 	case MPI_FUNCTION_PORT_FACTS:
+		karg.dataOutSize  = karg.dataInSize = 0;
+		break;
+
 	case MPI_FUNCTION_CONFIG:
 	case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:
 	case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
@@ -1928,12 +1966,14 @@
 			 */
 			if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
 				pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
+			else
+				pScsiReq->SenseBufferLength = karg.maxSenseBytes;
 
 			pScsiReq->SenseBufferLowAddr =
 				cpu_to_le32(ioc->sense_buf_low_dma
 				   + (req_idx * MPT_SENSE_BUFFER_ALLOC));
 
-			if ( (hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) {
+			if ((hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) {
 				if (hd->Targets)
 					pTarget = hd->Targets[target];
 			}
@@ -1944,11 +1984,10 @@
 			/* Have the IOCTL driver set the direction based
 			 * on the dataOutSize (ordering issue with Sparc).
 			 */
-			if (karg.dataOutSize > 0 ) {
+			if (karg.dataOutSize > 0) {
 				scsidir = MPI_SCSIIO_CONTROL_WRITE;
 				dataSize = karg.dataOutSize;
-			}
-			else {
+			} else {
 				scsidir = MPI_SCSIIO_CONTROL_READ;
 				dataSize = karg.dataInSize;
 			}
@@ -1990,6 +2029,8 @@
 			 */
 			if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
 				pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
+			else
+				pScsiReq->SenseBufferLength = karg.maxSenseBytes;
 
 			pScsiReq->SenseBufferLowAddr =
 				cpu_to_le32(ioc->sense_buf_low_dma
@@ -2001,11 +2042,10 @@
 			/* Have the IOCTL driver set the direction based
 			 * on the dataOutSize (ordering issue with Sparc).
 			 */
-			if (karg.dataOutSize > 0 ) {
+			if (karg.dataOutSize > 0) {
 				scsidir = MPI_SCSIIO_CONTROL_WRITE;
 				dataSize = karg.dataOutSize;
-			}
-			else {
+			} else {
 				scsidir = MPI_SCSIIO_CONTROL_READ;
 				dataSize = karg.dataInSize;
 			}
@@ -2033,7 +2073,7 @@
 					__FILE__, __LINE__);
 				rc = -EFAULT;
 				goto done_free_mem;
-			}  else if (mptctl_set_tm_flags(hd) != 0) {
+			} else if (mptctl_set_tm_flags(hd) != 0) {
 				rc = -EPERM;
 				goto done_free_mem;
 			}
@@ -2107,7 +2147,7 @@
 	 * preceede the data in (read) SGE. psgList is used to free the
 	 * allocated memory.
 	 */
-	psge = (char *) ( ((int *) mf) + karg.dataSgeOffset);
+	psge = (char *) (((int *) mf) + karg.dataSgeOffset);
 	flagsLength = 0;
 
 	/* bufIn and bufOut are used for user to kernel space transfers
@@ -2115,30 +2155,18 @@
 	bufIn.kptr = bufOut.kptr = NULL;
 	bufIn.len = bufOut.len = 0;
 
-	if (karg.dataOutSize > 0 )
+	if (karg.dataOutSize > 0)
 		sgSize ++;
 
-	if (karg.dataInSize > 0 )
+	if (karg.dataInSize > 0)
 		sgSize ++;
 
 	if (sgSize > 0) {
 
-		/* Allocate memory for the SGL.
-		 * Used to free kernel memory once
-		 * the MF is freed.
-		 */
-		sglbuf = pci_alloc_consistent (ioc->pcidev,
-			sgSize*sizeof(MptSge_t), &sglbuf_dma);
-		if (sglbuf == NULL) {
-			rc = -ENOMEM;
-			goto done_free_mem;
-		}
-		this_sge = sglbuf;
-
 		/* Set up the dataOut memory allocation */
 		if (karg.dataOutSize > 0) {
 			dir = PCI_DMA_TODEVICE;
-			if (karg.dataInSize > 0 ) {
+			if (karg.dataInSize > 0) {
 				flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
 						MPI_SGE_FLAGS_DIRECTION |
 						mpt_addr_size() )
@@ -2147,22 +2175,25 @@
 				flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
 			}
 			flagsLength |= karg.dataOutSize;
-
-			this_alloc = karg.dataOutSize;
-			bufOut.len = this_alloc;
+			bufOut.len = karg.dataOutSize;
 			bufOut.kptr = pci_alloc_consistent(
-					ioc->pcidev, this_alloc, &dma_addr);
+					ioc->pcidev, bufOut.len, &dma_addr_out);
 
 			if (bufOut.kptr == NULL) {
 				rc = -ENOMEM;
 				goto done_free_mem;
 			} else {
+				/* Set up this SGE.
+				 * Copy to MF and to sglbuf
+				 */
+				mpt_add_sge(psge, flagsLength, dma_addr_out);
+				psge += (sizeof(u32) + sizeof(dma_addr_t));
+
 				/* Copy user data to kernel space.
 				 */
 				if (copy_from_user(bufOut.kptr,
 						karg.dataOutBufPtr,
 						bufOut.len)) {
-
 					printk(KERN_ERR
 						"%s@%d::mptctl_do_mpt_command - Unable "
 						"to read user data "
@@ -2171,16 +2202,6 @@
 					rc =  -EFAULT;
 					goto done_free_mem;
 				}
-
-				/* Set up this SGE.
-				 * Copy to MF and to sglbuf
-				 */
-				mpt_add_sge(psge, flagsLength, dma_addr);
-				psge += (sizeof(u32) + sizeof(dma_addr_t));
-
-				this_sge->FlagsLength = flagsLength;
-				this_sge->Address = dma_addr;
-				this_sge++;
 			}
 		}
 
@@ -2189,10 +2210,10 @@
 			flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
 			flagsLength |= karg.dataInSize;
 
-			this_alloc = karg.dataInSize;
-			bufIn.len = this_alloc;
+			bufIn.len = karg.dataInSize;
 			bufIn.kptr = pci_alloc_consistent(ioc->pcidev,
-							this_alloc, &dma_addr);
+					bufIn.len, &dma_addr_in);
+
 			if (bufIn.kptr == NULL) {
 				rc = -ENOMEM;
 				goto done_free_mem;
@@ -2200,11 +2221,7 @@
 				/* Set up this SGE
 				 * Copy to MF and to sglbuf
 				 */
-				mpt_add_sge(psge, flagsLength, dma_addr);
-
-				this_sge->FlagsLength = flagsLength;
-				this_sge->Address = dma_addr;
-				this_sge++;
+				mpt_add_sge(psge, flagsLength, dma_addr_in);
 			}
 		}
 	} else  {
@@ -2228,7 +2245,7 @@
 
 	if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
 		rc = mpt_send_handshake_request(mptctl_id, ioc->id,
-				sizeof(SCSITaskMgmt_t), (u32*)mf, NO_SLEEP);
+				sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
 		if (rc == 0) {
 			wait_event(mptctl_wait, ioc->ioctl->wait_done);
 		} else {
@@ -2236,45 +2253,41 @@
 			tm_flags_set= 0;
 			del_timer(&ioc->ioctl->timer);
 			ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
-			ioc->ioctl->status = MPT_IOCTL_STATUS_TM_FAILED;
+			ioc->ioctl->status |= MPT_IOCTL_STATUS_TM_FAILED;
+			mpt_free_msg_frame(mptctl_id, ioc->id, mf);
 		}
 	} else {
 		mpt_put_msg_frame(mptctl_id, ioc->id, mf);
 		wait_event(mptctl_wait, ioc->ioctl->wait_done);
 	}
 
-	/* The command is complete.  * Return data to the user.
+	mf = NULL;
+
+	/* MF Cleanup:
+	 * If command failed and failure triggered a diagnostic reset
+	 * OR a diagnostic reset happens during command processing,
+	 * no data, messaging queues are reset (mf cannot be accessed),
+	 * and status is DID_IOCRESET
 	 *
-	 * If command completed,  mf has been freed so cannot
-	 * use this memory.
+	 * If a user-requested bus reset fails to be handshaked, then
+	 * mf is returned to free queue and status is TM_FAILED.
 	 *
-	 * If timeout, a recovery  mechanism has been called.
-	 * Need to free the mf.
+	 * Otherise, the command completed and the mf was freed
+	 # by ISR (mf cannot be touched).
 	 */
 	if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) {
-
-		/* A timeout - there is no data to return to the
-		 * the user other than an error.
-		 * The timer callback deleted the
+		/* The timer callback deleted the
 		 * timer and reset the adapter queues.
 		 */
 		printk(KERN_WARNING "%s@%d::mptctl_do_mpt_command - "
 			"Timeout Occurred on IOCTL! Reset IOC.\n", __FILE__, __LINE__);
 		tm_flags_set= 0;
 		rc = -ETIME;
-
-		/* Free memory and return to the calling function
-		 */
-		goto done_free_mem;
 	} else if (ioc->ioctl->status & MPT_IOCTL_STATUS_TM_FAILED) {
-		/* User TM request failed!
+		/* User TM request failed! mf has not been freed.
 		 */
 		rc = -ENODATA;
 	} else {
-		/* Callback freed request frame.
-		 */
-		mf = NULL;
-
 		/* If a valid reply frame, copy to the user.
 		 * Offset 2: reply length in U32's
 		 */
@@ -2332,42 +2345,31 @@
 	}
 
 done_free_mem:
-	/* Clear status bits.
-	 */
-	ioc->ioctl->status = 0;
+	/* Clear all status bits except TMTIMER_ACTIVE, this bit is cleared
+	 * upon completion of the TM command.
+	 * ioc->ioctl->status = 0;
+	 */
+	ioc->ioctl->status &= ~(MPT_IOCTL_STATUS_TIMER_ACTIVE | MPT_IOCTL_STATUS_TM_FAILED |
+			MPT_IOCTL_STATUS_COMMAND_GOOD | MPT_IOCTL_STATUS_SENSE_VALID |
+			MPT_IOCTL_STATUS_RF_VALID | MPT_IOCTL_STATUS_DID_IOCRESET);
 
 	if (tm_flags_set)
 		mptctl_free_tm_flags(ioc);
 
-	if (sglbuf) {
-		this_sge = sglbuf;
-
-		/* Free the allocated memory.
-		 */
-		 if (bufOut.kptr != NULL ) {
-			dma_addr = this_sge->Address;
-			this_sge++;	/* go to next structure */
-			this_alloc = bufOut.len;
-			pci_free_consistent(ioc->pcidev,
-				this_alloc, (void *) bufOut.kptr, dma_addr);
-		}
-
-		if (bufIn.kptr != NULL ) {
-			dma_addr = this_sge->Address;
-			this_alloc = bufIn.len;
-
-			pci_free_consistent(ioc->pcidev,
-					this_alloc, (void *) bufIn.kptr, dma_addr);
-		}
-
-		this_alloc = sgSize * sizeof(MptSge_t);
+	/* Free the allocated memory.
+	 */
+	 if (bufOut.kptr != NULL) {
 		pci_free_consistent(ioc->pcidev,
-				this_alloc, (void *) sglbuf, sglbuf_dma);
+			bufOut.len, (void *) bufOut.kptr, dma_addr_out);
+	}
 
+	if (bufIn.kptr != NULL) {
+		pci_free_consistent(ioc->pcidev,
+			bufIn.len, (void *) bufIn.kptr, dma_addr_in);
 	}
 
-	/* mf will be null if allocation failed OR
-	 * if command completed OK (callback freed)
+	/* mf is null if command issued successfully
+	 * otherwise, failure occured after mf acquired.
 	 */
 	if (mf)
 		mpt_free_msg_frame(mptctl_id, ioc->id, mf);
@@ -2405,7 +2407,7 @@
 	 */
 	if (data_size == sizeof(hp_host_info_t))
 		cim_rev = 1;
-	else if (data_size == (sizeof(hp_host_info_t) + 12))
+	else if (data_size == sizeof(hp_host_info_rev0_t))
 		cim_rev = 0;	/* obsolete */
 	else
 		return -EFAULT;
@@ -2478,7 +2480,7 @@
 	cfg.dir = 0;	/* read */
 	cfg.timeout = 10;
 
-	strlcpy(karg.serial_number, " ", sizeof(karg.serial_number));
+	strncpy(karg.serial_number, " ", 24);
 	if (mpt_config(ioc, &cfg) == 0) {
 		if (cfg.hdr->PageLength > 0) {
 			/* Issue the second config page request */
@@ -2489,9 +2491,10 @@
 				cfg.physAddr = buf_dma;
 				if (mpt_config(ioc, &cfg) == 0) {
 					ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
-					if (strlen(pdata->BoardTracerNumber) > 1)
-						strlcpy(karg.serial_number, pdata->BoardTracerNumber,
-							sizeof(karg.serial_number));
+					if (strlen(pdata->BoardTracerNumber) > 1) {
+						strncpy(karg.serial_number, 									    pdata->BoardTracerNumber, 24);
+						karg.serial_number[24-1]='\0';
+					}
 				}
 				pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
 				pbuf = NULL;
@@ -2535,6 +2538,20 @@
 		}
 	}
 
+	cfg.pageAddr = 0;
+	cfg.action = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
+	cfg.dir = MPI_TB_ISTWI_FLAGS_READ;
+	cfg.timeout = 10;
+	pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
+	if (pbuf) {
+		cfg.physAddr = buf_dma;
+		if ((mpt_toolbox(ioc, &cfg)) == 0) {
+			karg.rsvd = *(u32 *)pbuf;
+		}
+		pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
+		pbuf = NULL;
+	}
+
 	/* Copy the data from kernel memory to user memory
 	 */
 	if (copy_to_user((char *)arg, &karg,
@@ -2736,6 +2753,19 @@
  * to ensure the structure contents is properly processed by mptctl.
  */
 static int
+compat_mptctl_ioctl(unsigned int fd, unsigned int cmd,
+			unsigned long arg, struct file *filp)
+{
+	int ret;
+
+	lock_kernel();
+	dctlprintk((KERN_INFO MYNAM "::compat_mptctl_ioctl() called\n"));
+	ret = mptctl_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+	unlock_kernel();
+	return ret;
+}
+ 
+static int
 compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
 			unsigned long arg, struct file *filp)
 {
@@ -2875,30 +2905,30 @@
 	}
 
 #ifdef CONFIG_COMPAT
-	err = register_ioctl32_conversion(MPTIOCINFO, NULL);
+	err = register_ioctl32_conversion(MPTIOCINFO, compat_mptctl_ioctl);
 	if (++where && err) goto out_fail;
-	err = register_ioctl32_conversion(MPTIOCINFO1, NULL);
+	err = register_ioctl32_conversion(MPTIOCINFO1, compat_mptctl_ioctl);
 	if (++where && err) goto out_fail;
-	err = register_ioctl32_conversion(MPTTARGETINFO, NULL);
+	err = register_ioctl32_conversion(MPTTARGETINFO, compat_mptctl_ioctl);
 	if (++where && err) goto out_fail;
-	err = register_ioctl32_conversion(MPTTEST, NULL);
+	err = register_ioctl32_conversion(MPTTEST, compat_mptctl_ioctl);
 	if (++where && err) goto out_fail;
-	err = register_ioctl32_conversion(MPTEVENTQUERY, NULL);
+	err = register_ioctl32_conversion(MPTEVENTQUERY, compat_mptctl_ioctl);
 	if (++where && err) goto out_fail;
-	err = register_ioctl32_conversion(MPTEVENTENABLE, NULL);
+	err = register_ioctl32_conversion(MPTEVENTENABLE, compat_mptctl_ioctl);
 	if (++where && err) goto out_fail;
-	err = register_ioctl32_conversion(MPTEVENTREPORT, NULL);
+	err = register_ioctl32_conversion(MPTEVENTREPORT, compat_mptctl_ioctl);
 	if (++where && err) goto out_fail;
-	err = register_ioctl32_conversion(MPTHARDRESET, NULL);
+	err = register_ioctl32_conversion(MPTHARDRESET, compat_mptctl_ioctl);
 	if (++where && err) goto out_fail;
 	err = register_ioctl32_conversion(MPTCOMMAND32, compat_mpt_command);
 	if (++where && err) goto out_fail;
 	err = register_ioctl32_conversion(MPTFWDOWNLOAD32,
 					  compat_mptfwxfer_ioctl);
 	if (++where && err) goto out_fail;
-	err = register_ioctl32_conversion(HP_GETHOSTINFO, NULL);
+	err = register_ioctl32_conversion(HP_GETHOSTINFO, compat_mptctl_ioctl);
 	if (++where && err) goto out_fail;
-	err = register_ioctl32_conversion(HP_GETTARGETINFO, NULL);
+	err = register_ioctl32_conversion(HP_GETTARGETINFO, compat_mptctl_ioctl);
 	if (++where && err) goto out_fail;
 #endif
 
diff -Nru a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h
--- a/drivers/message/fusion/mptctl.h	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/mptctl.h	Wed Mar 10 21:09:42 2004
@@ -15,7 +15,7 @@
  *
  *      (see also mptbase.c)
  *
- *  Copyright (c) 1999-2003 LSI Logic Corporation
+ *  Copyright (c) 1999-2004 LSI Logic Corporation
  *  Originally By: Steven J. Ralston
  *  (mailto:sjralston1@netscape.net)
  *  (mailto:mpt_linux_developer@lsil.com)
@@ -342,6 +342,7 @@
 #define CPQFCTS_IOC_MAGIC 'Z'
 #define HP_IOC_MAGIC 'Z'
 #define HP_GETHOSTINFO		_IOR(HP_IOC_MAGIC, 20, hp_host_info_t)
+#define HP_GETHOSTINFO1		_IOR(HP_IOC_MAGIC, 20, hp_host_info_rev0_t)
 #define HP_GETTARGETINFO	_IOR(HP_IOC_MAGIC, 21, hp_target_info_t)
 
 /* All HP IOCTLs must include this header
@@ -357,7 +358,7 @@
 /*
  *  Header:
  *  iocnum 	required (input)
- *  host 	ignored	
+ *  host 	ignored
  *  channe	ignored
  *  id		ignored
  *  lun		ignored
@@ -371,9 +372,9 @@
 	u8		 devfn;
 	u8		 bus;
 	ushort		 host_no;		/* SCSI Host number, if scsi driver not loaded*/
-	u8		 fw_version[16];	/* string */	
+	u8		 fw_version[16];	/* string */
 	u8		 serial_number[24];	/* string */
-	u32		 ioc_status;	
+	u32		 ioc_status;
 	u32		 bus_phys_width;
 	u32		 base_io_addr;
 	u32		 rsvd;
@@ -382,10 +383,33 @@
 	unsigned int	 timeouts;		/* num timeouts */
 } hp_host_info_t;
 
+/* replace ulongs with uints, need to preserve backwards
+ * compatibility.
+ */
+typedef struct _hp_host_info_rev0 {
+	hp_header_t	 hdr;
+	u16		 vendor;
+	u16		 device;
+	u16		 subsystem_vendor;
+	u16		 subsystem_id;
+	u8		 devfn;
+	u8		 bus;
+	ushort		 host_no;		/* SCSI Host number, if scsi driver not loaded*/
+	u8		 fw_version[16];	/* string */
+	u8		 serial_number[24];	/* string */
+	u32		 ioc_status;
+	u32		 bus_phys_width;
+	u32		 base_io_addr;
+	u32		 rsvd;
+	unsigned long	 hard_resets;		/* driver initiated resets */
+	unsigned long	 soft_resets;		/* ioc, external resets */
+	unsigned long	 timeouts;		/* num timeouts */
+} hp_host_info_rev0_t;
+
 /*
  *  Header:
  *  iocnum 	required (input)
- *  host 	required	
+ *  host 	required
  *  channel	required	(bus number)
  *  id		required
  *  lun		ignored
diff -Nru a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
--- a/drivers/message/fusion/mptlan.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/mptlan.c	Wed Mar 10 21:09:42 2004
@@ -23,7 +23,7 @@
  *
  *      (see also mptbase.c)
  *
- *  Copyright (c) 2000-2003 LSI Logic Corporation
+ *  Copyright (c) 2000-2004 LSI Logic Corporation
  *  Originally By: Noah Romer
  *  (mailto:mpt_linux_developer@lsil.com)
  *
@@ -340,12 +340,15 @@
 	struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
 
 	dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
-			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+			reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
+			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
 
 	if (priv->mpt_rxfidx == NULL)
 		return (1);
 
-	if (reset_phase == MPT_IOC_PRE_RESET) {
+	if (reset_phase == MPT_IOC_SETUP_RESET) {
+		;
+	} else if (reset_phase == MPT_IOC_PRE_RESET) {
 		int i;
 		unsigned long flags;
 
diff -Nru a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
--- a/drivers/message/fusion/mptscsih.c	Wed Mar 10 21:09:43 2004
+++ b/drivers/message/fusion/mptscsih.c	Wed Mar 10 21:09:43 2004
@@ -21,7 +21,7 @@
  *
  *      (see mptbase.c)
  *
- *  Copyright (c) 1999-2003 LSI Logic Corporation
+ *  Copyright (c) 1999-2004 LSI Logic Corporation
  *  Original author: Steven J. Ralston
  *  (mailto:sjralston1@netscape.net)
  *  (mailto:mpt_linux_developer@lsil.com)
@@ -165,17 +165,19 @@
 static MPT_FRAME_HDR *mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx);
 static void	post_pendingQ_commands(MPT_SCSI_HOST *hd);
 
-static int	mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
-static int	mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
+static int	mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
+static int	mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
 
 static int	mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
 static int	mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 
-static void	mptscsih_target_settings(MPT_SCSI_HOST *hd, VirtDevice *target, Scsi_Device *sdev);
+static void	mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
+void		mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
 static void	mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
 static void	mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
 static void	mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
 static int	mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
+static int	mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
 static int	mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 static void	mptscsih_timer_expired(unsigned long data);
 static void	mptscsih_taskmgmt_timeout(unsigned long data);
@@ -190,18 +192,18 @@
 static void	mptscsih_domainValidation(void *hd);
 static int	mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
 static void	mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
-static int	mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int target);
+static int	mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
 static void	mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
 static void	mptscsih_fillbuf(char *buffer, int size, int index, int width);
 #endif
 static int	mptscsih_setup(char *str);
 
 /* module entry point */
-static int  __init   mptscsih_init  (void);
-static void __exit   mptscsih_exit  (void);
+static int  __init    mptscsih_init  (void);
+static void __exit    mptscsih_exit  (void);
 
-static int  __devinit mptscsih_probe (struct pci_dev *, const struct pci_device_id *);
-static void __devexit mptscsih_remove(struct pci_dev *);
+static int  mptscsih_probe (struct pci_dev *, const struct pci_device_id *);
+static void mptscsih_remove(struct pci_dev *);
 static void mptscsih_shutdown(struct device *);
 #ifdef CONFIG_PM
 static int mptscsih_suspend(struct pci_dev *pdev, u32 state);
@@ -214,7 +216,6 @@
  */
 
 static int	mpt_scsi_hosts = 0;
-static atomic_t	queue_depth;
 
 static int	ScsiDoneCtx = -1;
 static int	ScsiTaskCtx = -1;
@@ -243,6 +244,10 @@
 static struct mptscsih_driver_setup
 	driver_setup = MPTSCSIH_DRIVER_SETUP;
 
+#ifdef MPTSCSIH_DBG_TIMEOUT
+static Scsi_Cmnd *foo_to[8];
+#endif
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
 /* see mptscsih.h */
@@ -438,10 +443,10 @@
 static inline int
 mptscsih_getFreeChainBuffer(MPT_SCSI_HOST *hd, int *retIndex)
 {
-	MPT_FRAME_HDR *chainBuf = NULL;
+	MPT_FRAME_HDR *chainBuf;
 	unsigned long flags;
-	int rc = FAILED;
-	int chain_idx = MPT_HOST_NO_CHAIN;
+	int rc;
+	int chain_idx;
 
 	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
 	if (!Q_IS_EMPTY(&hd->FreeChainQ)) {
@@ -454,6 +459,10 @@
 		chain_idx = offset / hd->ioc->req_sz;
 		rc = SUCCESS;
 	}
+	else {
+		rc = FAILED;
+		chain_idx = MPT_HOST_NO_CHAIN;
+	}
 	spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
 
 
@@ -506,13 +515,12 @@
 	/* Map the data portion, if any.
 	 * sges_left  = 0 if no data transfer.
 	 */
-	sges_left = SCpnt->use_sg;
-	if (SCpnt->use_sg) {
+	if ( (sges_left = SCpnt->use_sg) ) {
 		sges_left = pci_map_sg(hd->ioc->pcidev,
 			       (struct scatterlist *) SCpnt->request_buffer,
 			       SCpnt->use_sg,
 			       scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
-		if (sges_left == 0) 
+		if (sges_left == 0)
 			return FAILED;
 	} else if (SCpnt->request_bufflen) {
 		dma_addr_t	 buf_dma_addr;
@@ -729,50 +737,67 @@
 
 	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
 
-	if ((mf == NULL) ||
-	    (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
-		printk(MYIOC_s_ERR_FMT "%s req frame ptr! (=%p)!\n",
-				ioc->name, mf?"BAD":"NULL", (void *) mf);
-		return 0;
-	}
-
 	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
 	sc = hd->ScsiLookup[req_idx];
 	if (sc == NULL) {
+		MPIHeader_t *hdr = (MPIHeader_t *)mf;
+
 		/* Remark: writeSDP1 will use the ScsiDoneCtx
 		 * If a SCSI I/O cmd, device disabled by OS and
 		 * completion done. Cannot touch sc struct. Just free mem.
 		 */
-		atomic_dec(&queue_depth);
+		if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
+			printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
+			ioc->name);
 
 		mptscsih_freeChainBuffers(hd, req_idx);
 		return 1;
 	}
 
-	dmfprintk((MYIOC_s_INFO_FMT "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
-			ioc->name, mf, mr, sc, req_idx));
-
-	atomic_dec(&queue_depth);
+	dmfprintk((MYIOC_s_INFO_FMT
+		"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
+		ioc->name, mf, mr, sc, req_idx));
 
 	sc->result = DID_OK << 16;		/* Set default reply as OK */
 	pScsiReq = (SCSIIORequest_t *) mf;
 	pScsiReply = (SCSIIOReply_t *) mr;
 
+#ifdef MPTSCSIH_DBG_TIMEOUT
+	if (ioc->timeout_cnt > 0) {
+		int ii, left = 0;
+
+		for (ii=0; ii < 8; ii++) {
+			if (sc == foo_to[ii]) {
+				printk(MYIOC_s_INFO_FMT "complete (%p, %ld)\n",
+					ioc->name, sc, jiffies);
+				foo_to[ii] = NULL;
+			}
+			if (foo_to[ii] != NULL)
+				left++;
+		}
+
+		if (left == 0) {
+			ioc->timeout_maxcnt = 0;
+			ioc->timeout_cnt = 0;
+		}
+	}
+#endif
+
 	if (pScsiReply == NULL) {
 		/* special context reply handling */
 		;
 	} else {
 		u32	 xfer_cnt;
 		u16	 status;
-		u8	 scsi_state;
+		u8	 scsi_state, scsi_status;
 
 		status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
 		scsi_state = pScsiReply->SCSIState;
 
-		dsprintk((KERN_NOTICE "  Uh-Oh! (%d:%d:%d) mf=%p, mr=%p, sc=%p\n",
+		dprintk((KERN_NOTICE "  Uh-Oh! (%d:%d:%d) mf=%p, mr=%p, sc=%p\n",
 				ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
 				mf, mr, sc));
-		dsprintk((KERN_NOTICE "  IOCStatus=%04xh, SCSIState=%02xh"
+		dprintk((KERN_NOTICE "  IOCStatus=%04xh, SCSIState=%02xh"
 				", SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
 				status, scsi_state, pScsiReply->SCSIStatus,
 				le32_to_cpu(pScsiReply->IOCLogInfo)));
@@ -780,14 +805,6 @@
 		if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
 			copy_sense_data(sc, hd, mf, pScsiReply);
 
-		/*
-		 *  Look for + dump FCP ResponseInfo[]!
-		 */
-		if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
-			dprintk((KERN_NOTICE "  FCP_ResponseInfo=%08xh\n",
-					     le32_to_cpu(pScsiReply->ResponseInfo)));
-		}
-
 		switch(status) {
 		case MPI_IOCSTATUS_BUSY:			/* 0x0002 */
 			/* CHECKME!
@@ -827,52 +844,45 @@
 		case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:	/* 0x0049 */
 		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
 			/*
-			 *  YIKES!  I just discovered that SCSI IO which
-			 *  returns check condition, SenseKey=05 (ILLEGAL REQUEST)
-			 *  and ASC/ASCQ=94/01 (LSI Logic RAID vendor specific),
-			 *  comes down this path!
 			 *  Do upfront check for valid SenseData and give it
 			 *  precedence!
 			 */
-			sc->result = (DID_OK << 16) | pScsiReply->SCSIStatus;
-			if (scsi_state == 0) {
-				;
-			} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
+			scsi_status = pScsiReply->SCSIStatus;
+			sc->result = (DID_OK << 16) | scsi_status;
+			xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
+			if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
 				/* Have already saved the status and sense data
 				 */
 				;
-			} else if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
-				/* What to do?
-				 */
-				sc->result = DID_SOFT_ERROR << 16;
-			}
-			else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
-				/*  Not real sure here either...  */
-				sc->result = DID_RESET << 16;
+			} else {
+				if ( (xfer_cnt == 0) || (sc->underflow > xfer_cnt)) {
+					sc->result = DID_SOFT_ERROR << 16;
+				}
+				if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
+					/* What to do?
+				 	*/
+					sc->result = DID_SOFT_ERROR << 16;
+				}
+				else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
+					/*  Not real sure here either...  */
+					sc->result = DID_RESET << 16;
+				}
 			}
 
 			/* Give report and update residual count.
 			 */
-			xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
 			dprintk((KERN_NOTICE "  sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
 					sc->underflow));
 			dprintk((KERN_NOTICE "  ActBytesXferd=%02xh\n", xfer_cnt));
 
 			sc->resid = sc->request_bufflen - xfer_cnt;
 			dprintk((KERN_NOTICE "  SET sc->resid=%02xh\n", sc->resid));
-
-			if(sc->underflow > xfer_cnt) {
-				printk(MYIOC_s_INFO_FMT
-				"SCSI data underrun: underflow=%02x, xfercnt=%02x\n",
-				ioc->name, sc->underflow, xfer_cnt);
-				sc->result = DID_SOFT_ERROR << 16;
-			}
-
+			
 			/* Report Queue Full
 			 */
-			if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
+			if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
 				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
-
+			
 			break;
 
 		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
@@ -965,9 +975,7 @@
 
 	hd->ScsiLookup[req_idx] = NULL;
 
-	MPT_HOST_LOCK(flags);
 	sc->scsi_done(sc);		/* Issue the command callback */
-	MPT_HOST_UNLOCK(flags);
 
 	/* Free Chain buffers */
 	mptscsih_freeChainBuffers(hd, req_idx);
@@ -988,7 +996,7 @@
 
 	/* Flush the doneQ.
 	 */
-	dprintk((KERN_INFO MYNAM ": flush_doneQ called\n"));
+	dtmprintk((KERN_INFO MYNAM ": flush_doneQ called\n"));
 	while (1) {
 		spin_lock_irqsave(&hd->freedoneQlock, flags);
 		if (Q_IS_EMPTY(&hd->doneQ)) {
@@ -1013,9 +1021,7 @@
 
 		/* Do the OS callback.
 		 */
-                MPT_HOST_LOCK(flags);
 		SCpnt->scsi_done(SCpnt);
-                MPT_HOST_UNLOCK(flags);
 	}
 
 	return;
@@ -1055,6 +1061,22 @@
 	return;
 }
 
+static void
+mptscsih_reset_timeouts (MPT_SCSI_HOST *hd)
+{
+	Scsi_Cmnd	*SCpnt;
+	int		 ii;
+	int		 max = hd->ioc->req_depth;
+
+	for (ii= 0; ii < max; ii++) {
+		if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
+			mod_timer(&SCpnt->eh_timeout, jiffies + (HZ * 60));
+			dtmprintk((MYIOC_s_WARN_FMT "resetting SCpnt=%p timeout + 60HZ",
+				(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
+		}
+	}
+}
+
 /*
  *	mptscsih_flush_running_cmds - For each command found, search
  *		Scsi_Host instance taskQ and reply to OS.
@@ -1068,23 +1090,24 @@
 static void
 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
 {
-	Scsi_Cmnd	*SCpnt = NULL;
-	MPT_FRAME_HDR	*mf = NULL;
+	Scsi_Cmnd	*SCpnt;
+	MPT_FRAME_HDR	*mf;
+	MPT_DONE_Q	*buffer;
 	int		 ii;
 	int		 max = hd->ioc->req_depth;
+	unsigned long	 flags;
 
 	dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
 	for (ii= 0; ii < max; ii++) {
 		if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
 
 			/* Command found.
-			 *
-			 * Search pendingQ, if found,
-			 * delete from Q. If found, do not decrement
-			 * queue_depth, command never posted.
 			 */
-			if (mptscsih_search_pendingQ(hd, ii) == NULL)
-				atomic_dec(&queue_depth);
+
+			/* Search pendingQ, if found,
+			 * delete from Q.
+			 */
+			mptscsih_search_pendingQ(hd, ii);
 
 			/* Null ScsiLookup index
 			 */
@@ -1111,15 +1134,39 @@
 			}
 			SCpnt->result = DID_RESET << 16;
 			SCpnt->host_scribble = NULL;
-                        MPT_HOST_LOCK(flags);
-			SCpnt->scsi_done(SCpnt);	/* Issue the command callback */
-                        MPT_HOST_UNLOCK(flags);
 
 			/* Free Chain buffers */
 			mptscsih_freeChainBuffers(hd, ii);
 
 			/* Free Message frames */
 			mpt_free_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
+
+#if 1
+			/* Post to doneQ, do not reply until POST phase
+			 * of reset handler....prevents new commands from
+			 * being queued.
+			 */
+			spin_lock_irqsave(&hd->freedoneQlock, flags);
+			if (!Q_IS_EMPTY(&hd->freeQ)) {
+				buffer = hd->freeQ.head;
+				Q_DEL_ITEM(buffer);
+
+				/* Set the Scsi_Cmnd pointer
+				 */
+				buffer->argp = (void *)SCpnt;
+
+				/* Add to the doneQ
+				 */
+				Q_ADD_TAIL(&hd->doneQ.head, buffer, MPT_DONE_Q);
+				spin_unlock_irqrestore(&hd->freedoneQlock, flags);
+			} else {
+				spin_unlock_irqrestore(&hd->freedoneQlock, flags);
+				SCpnt->scsi_done(SCpnt);
+			}
+#else
+			SCpnt->scsi_done(SCpnt);	/* Issue the command callback */
+#endif
+
 		}
 	}
 
@@ -1147,8 +1194,8 @@
 	int		 ii;
 	int		 max = hd->ioc->req_depth;
 
-	dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d numIos %d\n",
-			target, lun, max, atomic_read(&queue_depth)));
+	dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
+			target, lun, max));
 
 	for (ii=0; ii < max; ii++) {
 		if (hd->ScsiLookup[ii] != NULL) {
@@ -1161,11 +1208,6 @@
 			if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
 				continue;
 
-			/* If cmd pended, do not decrement queue_depth, command never posted.
-			 */
-			if (mptscsih_search_pendingQ(hd, ii) == NULL)
-				atomic_dec(&queue_depth);
-
 			/* Cleanup
 			 */
 			hd->ScsiLookup[ii] = NULL;
@@ -1177,73 +1219,6 @@
 	return;
 }
 
-#ifdef DROP_TEST
-/* 	mptscsih_flush_drop_test - Free resources and do callback if
- *		DROP_TEST enabled.
- *
- *	@hd: Pointer to a SCSI HOST structure
- *
- *	Returns: None.
- *
- *	Must be called while new I/Os are being queued.
- */
-static void
-mptscsih_flush_drop_test (MPT_SCSI_HOST *hd)
-{
-	Scsi_Cmnd	*sc;
-	unsigned long	 flags;
-	u16		 req_idx;
-
-	/* Free resources for the drop test MF
-	 * and chain buffers.
-	 */
-	if (dropMfPtr) {
-		req_idx = le16_to_cpu(dropMfPtr->u.frame.hwhdr.msgctxu.fld.req_idx);
-		sc = hd->ScsiLookup[req_idx];
-		if (sc == NULL) {
-			printk(MYIOC_s_ERR_FMT "Drop Test: NULL ScsiCmd ptr!\n",
-					ioc->name);
-		} else {
-			/* unmap OS resources, set status, do callback
-			 * free driver resources
-			 */
-			if (sc->use_sg) {
-				pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
-					    sc->use_sg, scsi_to_pci_dma_dir(sc->sc_data_direction));
-			} else if (sc->request_bufflen) {
-				scPrivate	*my_priv;
-
-				my_priv = (scPrivate *) &sc->SCp;
-				pci_unmap_single(ioc->pcidev, (dma_addr_t)(ulong)my_priv->p1,
-					   sc->request_bufflen,
-					   scsi_to_pci_dma_dir(sc->sc_data_direction));
-			}
-
-			sc->host_scribble = NULL;
-			sc->result = DID_RESET << 16;
-			hd->ScsiLookup[req_idx] = NULL;
-			atomic_dec(&queue_depth);
-			MPT_HOST_LOCK(flags);
-			sc->scsi_done(sc);	/* Issue callback */
-			MPT_HOST_UNLOCK(flags);
-		}
-
-		mptscsih_freeChainBuffers(hd, req_idx);
-		mpt_free_msg_frame(ScsiDoneCtx, ioc->id, dropMfPtr);
-		printk(MYIOC_s_INFO_FMT "Free'd Dropped cmd (%p)\n",
-					hd->ioc->name, sc);
-		printk(MYIOC_s_INFO_FMT "mf (%p) reqidx (%4x)\n",
-					hd->ioc->name, dropMfPtr, req_idx);
-		printk(MYIOC_s_INFO_FMT "Num Tot (%d) Good (%d) Bad (%d) \n",
-				hd->ioc->name, dropTestNum,
-				dropTestOK, dropTestBad);
-	}
-	dropMfPtr = NULL;
-
-	return;
-}
-#endif
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	mptscsih_initChainBuffers - Allocate memory for and initialize
@@ -1263,18 +1238,15 @@
 	/* ReqToChain size must equal the req_depth
 	 * index = req_idx
 	 */
-	sz = hd->ioc->req_depth * sizeof(int);
 	if (hd->ReqToChain == NULL) {
+		sz = hd->ioc->req_depth * sizeof(int);
 		mem = kmalloc(sz, GFP_ATOMIC);
 		if (mem == NULL)
 			return -1;
 
 		hd->ReqToChain = (int *) mem;
-	} else {
-		mem = (u8 *) hd->ReqToChain;
 	}
-/*	memset(mem, 0xFF, sz); */
-	for(ii=0;ii<hd->ioc->req_depth;ii++)
+	for (ii = 0; ii < hd->ioc->req_depth; ii++)
 		hd->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
 
 	/* ChainToChain size must equal the total number
@@ -1322,7 +1294,11 @@
 	if (hd->ChainBuffer == NULL) {
 		/* Allocate free chain buffer pool
 		 */
+#if defined(MPTBASE_MEM_ALLOC_FIFO_FIX)
+		mem = pci_alloc_consistent(&hd->ioc->pcidev32, sz, &hd->ChainBufferDMA);
+#else		
 		mem = pci_alloc_consistent(hd->ioc->pcidev, sz, &hd->ChainBufferDMA);
+#endif		
 		if (mem == NULL)
 			return -1;
 
@@ -1405,310 +1381,333 @@
  *
  */
 
-static int  __devinit
+static int
 mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-	struct Scsi_Host	*sh = NULL;
-	MPT_SCSI_HOST		*hd = NULL;
+	struct Scsi_Host	*sh;
+	MPT_SCSI_HOST		*hd;
 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
-	int			portnum;
 	MPT_DONE_Q		*freedoneQ;
 	unsigned long		 flags;
 	int			 sz, ii;
 	int			 numSGE = 0;
 	int			 scale;
+	int			 ioc_cap;
 	u8			*mem;
 	int			error=0;
 
-	for (portnum=0; portnum < ioc->facts.NumberOfPorts; portnum++) {
-
-		/* 20010215 -sralston
-		 *  Added sanity check on SCSI Initiator-mode enabled
-		 *  for this MPT adapter.
-		 */
-		if (!(ioc->pfacts[portnum].ProtocolFlags &
-		  MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
-			printk(MYIOC_s_WARN_FMT
-			  "Skipping because SCSI Initiator mode is NOT enabled!\n",
-			  ioc->name);
-			continue;
-		}
-
-		/* 20010202 -sralston
-		 *  Added sanity check on readiness of the MPT adapter.
-		 */
-		if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
-			printk(MYIOC_s_WARN_FMT
-			  "Skipping because it's not operational!\n",
-			  ioc->name);
-			continue;
-		}
-
-		sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST));
-		if (sh != NULL) {
-			spin_lock_irqsave(&ioc->FreeQlock, flags);
-
-			/* Attach the SCSI Host to the IOC structure
-			 */
-			ioc->sh = sh;
-
-			sh->io_port = 0;
-			sh->n_io_port = 0;
-			sh->irq = 0;
-
-			/* set 16 byte cdb's */
-			sh->max_cmd_len = 16;
-
-			/* Yikes!  This is important!
-			 * Otherwise, by default, linux
-			 * only scans target IDs 0-7!
-			 * pfactsN->MaxDevices unreliable
-			 * (not supported in early
-			 *	versions of the FW).
-			 * max_id = 1 + actual max id,
-			 * max_lun = 1 + actual last lun,
-			 *	see hosts.h :o(
-			 */
-			if ((int)ioc->chip_type > (int)FC929) {
-				sh->max_id = MPT_MAX_SCSI_DEVICES;
-			} else {
-			/* For FC, increase the queue depth
-			 * from MPT_SCSI_CAN_QUEUE (31)
-			 * to MPT_FC_CAN_QUEUE (63).
-			 */
-				sh->can_queue = MPT_FC_CAN_QUEUE;
-				sh->max_id =
-				  MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
-			}
-
-			sh->max_lun = MPT_LAST_LUN + 1;
-			sh->max_sectors = MPT_SCSI_MAX_SECTORS;
-			sh->this_id = ioc->pfacts[portnum].PortSCSIID;
-
-			/* Required entry.
-			 */
-			sh->unique_id = ioc->id;
-
-			/* Verify that we won't exceed the maximum
-			 * number of chain buffers
-			 * We can optimize:  ZZ = req_sz/sizeof(SGE)
-			 * For 32bit SGE's:
-			 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
-			 *               + (req_sz - 64)/sizeof(SGE)
-			 * A slightly different algorithm is required for
-			 * 64bit SGEs.
-			 */
-			scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
-			if (sizeof(dma_addr_t) == sizeof(u64)) {
-				numSGE = (scale - 1) *
-				  (ioc->facts.MaxChainDepth-1) + scale +
-				  (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
-				  sizeof(u32));
-			} else {
-				numSGE = 1 + (scale - 1) *
-				  (ioc->facts.MaxChainDepth-1) + scale +
-				  (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
-				  sizeof(u32));
-			}
-
-			if (numSGE < sh->sg_tablesize) {
-				/* Reset this value */
-				dprintk((MYIOC_s_INFO_FMT
-				  "Resetting sg_tablesize to %d from %d\n",
-				  ioc->name, numSGE, sh->sg_tablesize));
-				sh->sg_tablesize = numSGE;
-			}
-
-			/* Set the pci device pointer in Scsi_Host structure.
-			 */
-			scsi_set_device(sh, &ioc->pcidev->dev);
 
-			spin_unlock_irqrestore(&ioc->FreeQlock, flags);
-
-			hd = (MPT_SCSI_HOST *) sh->hostdata;
-			hd->ioc = ioc;
-			hd->max_sge = sh->sg_tablesize;
-
-			if ((int)ioc->chip_type > (int)FC929)
-			hd->is_spi = 1;
+	/* 20010202 -sralston
+	 *  Added sanity check on readiness of the MPT adapter.
+	 */
+	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
+		printk(MYIOC_s_WARN_FMT
+		  "Skipping because it's not operational!\n",
+		  ioc->name);
+		return -ENODEV;
+	}
 
-			if (DmpService && (ioc->chip_type == FC919 ||
-			  ioc->chip_type == FC929)) {
-				hd->is_multipath = 1;
-			}
-			hd->port = 0; /* FIXME! */
+	if (!ioc->active) {
+		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
+		  ioc->name);
+		return -ENODEV;
+	}
 
-			/* SCSI needs Scsi_Cmnd lookup table!
-			 * (with size equal to req_depth*PtrSz!)
-			 */
-			sz = hd->ioc->req_depth * sizeof(void *);
-			mem = kmalloc(sz, GFP_ATOMIC);
-			if (mem == NULL) {
-				error = -ENOMEM;
-				goto mptscsih_probe_failed;
-			}
+	/*  Sanity check - ensure at least 1 port is INITIATOR capable
+	 */
+	ioc_cap = 0;
+	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
+		if (ioc->pfacts[ii].ProtocolFlags &
+		    MPI_PORTFACTS_PROTOCOL_INITIATOR)
+			ioc_cap ++;
+	}
 
-			memset(mem, 0, sz);
-			hd->ScsiLookup = (struct scsi_cmnd **) mem;
+	if (!ioc_cap) {
+		printk(MYIOC_s_WARN_FMT
+			"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
+			ioc->name, ioc);
+		return -ENODEV;
+	}
 
-			dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
-				 ioc->name, hd->ScsiLookup, sz));
+	sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST));
+        
+	if (!sh) {
+		printk(MYIOC_s_WARN_FMT
+			"Unable to register controller with SCSI subsystem\n",
+			ioc->name);
+                return -1;
+        }
+	
+	spin_lock_irqsave(&ioc->FreeQlock, flags);
 
-			if (mptscsih_initChainBuffers(hd, 1) < 0) {
-				error = -EINVAL;
-				goto mptscsih_probe_failed;
-			}
+	/* Attach the SCSI Host to the IOC structure
+	 */
+	ioc->sh = sh;
 
-			/* Allocate memory for free and doneQ's
-			 */
-			sz = sh->can_queue * sizeof(MPT_DONE_Q);
-			mem = kmalloc(sz, GFP_ATOMIC);
-			if (mem == NULL) {
-				error = -ENOMEM;
-				goto mptscsih_probe_failed;
-			}
+	sh->io_port = 0;
+	sh->n_io_port = 0;
+	sh->irq = 0;
+
+	/* set 16 byte cdb's */
+	sh->max_cmd_len = 16;
+
+	/* Yikes!  This is important!
+	 * Otherwise, by default, linux
+	 * only scans target IDs 0-7!
+	 * pfactsN->MaxDevices unreliable
+	 * (not supported in early
+	 *	versions of the FW).
+	 * max_id = 1 + actual max id,
+	 * max_lun = 1 + actual last lun,
+	 *	see hosts.h :o(
+	 */
+	if ((int)ioc->chip_type > (int)FC929) {
+		sh->max_id = MPT_MAX_SCSI_DEVICES;
+	} else {
+	/* For FC, increase the queue depth
+	 * from MPT_SCSI_CAN_QUEUE (31)
+	 * to MPT_FC_CAN_QUEUE (63).
+	 */
+		sh->can_queue = MPT_FC_CAN_QUEUE;
+		sh->max_id =
+		  MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
+	}
+		
+	sh->max_lun = MPT_LAST_LUN + 1;
+	sh->max_sectors = MPT_SCSI_MAX_SECTORS;
+	sh->max_channel = 0;
+	sh->this_id = ioc->pfacts[0].PortSCSIID;
+		
+	/* Required entry.
+	 */
+	sh->unique_id = ioc->id;
+
+	/* Verify that we won't exceed the maximum
+	 * number of chain buffers
+	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
+	 * For 32bit SGE's:
+	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
+	 *               + (req_sz - 64)/sizeof(SGE)
+	 * A slightly different algorithm is required for
+	 * 64bit SGEs.
+	 */
+	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
+	if (sizeof(dma_addr_t) == sizeof(u64)) {
+		numSGE = (scale - 1) *
+		  (ioc->facts.MaxChainDepth-1) + scale +
+		  (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
+		  sizeof(u32));
+	} else {
+		numSGE = 1 + (scale - 1) *
+		  (ioc->facts.MaxChainDepth-1) + scale +
+		  (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
+		  sizeof(u32));
+	}
+		
+	if (numSGE < sh->sg_tablesize) {
+		/* Reset this value */
+		dprintk((MYIOC_s_INFO_FMT
+		  "Resetting sg_tablesize to %d from %d\n",
+		  ioc->name, numSGE, sh->sg_tablesize));
+		sh->sg_tablesize = numSGE;
+	}
 
-			memset(mem, 0xFF, sz);
-			hd->memQ = mem;
+	/* Set the pci device pointer in Scsi_Host structure.
+	 */
+	scsi_set_device(sh, &ioc->pcidev->dev);
 
-			/* Initialize the free, done and pending Qs.
-			 */
-			Q_INIT(&hd->freeQ, MPT_DONE_Q);
-			Q_INIT(&hd->doneQ, MPT_DONE_Q);
-			Q_INIT(&hd->pendingQ, MPT_DONE_Q);
-			spin_lock_init(&hd->freedoneQlock);
-
-			mem = hd->memQ;
-			for (ii=0; ii < sh->can_queue; ii++) {
-				freedoneQ = (MPT_DONE_Q *) mem;
-				Q_ADD_TAIL(&hd->freeQ.head, freedoneQ, MPT_DONE_Q);
-				mem += sizeof(MPT_DONE_Q);
-			}
+	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
 
-			/* Initialize this Scsi_Host
-			 * internal task Q.
-			 */
-			Q_INIT(&hd->taskQ, MPT_FRAME_HDR);
-			hd->taskQcnt = 0;
+	hd = (MPT_SCSI_HOST *) sh->hostdata;
+	hd->ioc = ioc;
+	hd->max_sge = sh->sg_tablesize;
+
+	if ((int)ioc->chip_type > (int)FC929)
+	hd->is_spi = 1;
+
+	if (DmpService && (ioc->chip_type == FC919 ||
+	  ioc->chip_type == FC929)) {
+		hd->is_multipath = 1;
+	}
+
+	/* SCSI needs Scsi_Cmnd lookup table!
+	 * (with size equal to req_depth*PtrSz!)
+	 */
+	sz = hd->ioc->req_depth * sizeof(void *);
+	mem = kmalloc(sz, GFP_ATOMIC);
+	if (mem == NULL) {
+		error = -ENOMEM;
+		goto mptscsih_probe_failed;
+	}
 
-			/* Allocate memory for the device structures.
-			 * A non-Null pointer at an offset
-			 * indicates a device exists.
-			 * max_id = 1 + maximum id (hosts.h)
-			 */
-			sz = sh->max_id * sizeof(void *);
-			mem = kmalloc(sz, GFP_ATOMIC);
-			if (mem == NULL) {
-				error = -ENOMEM;
-				goto mptscsih_probe_failed;
-			}
+	memset(mem, 0, sz);
+	hd->ScsiLookup = (struct scsi_cmnd **) mem;
 
-			memset(mem, 0, sz);
-			hd->Targets = (VirtDevice **) mem;
+	dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
+		 ioc->name, hd->ScsiLookup, sz));
+		
+	if (mptscsih_initChainBuffers(hd, 1) < 0) {
+		error = -EINVAL;
+		goto mptscsih_probe_failed;
+	}
+
+	/* Allocate memory for free and doneQ's
+	 */
+	sz = sh->can_queue * sizeof(MPT_DONE_Q);
+	mem = kmalloc(sz, GFP_ATOMIC);
+	if (mem == NULL) {
+		error = -ENOMEM;
+		goto mptscsih_probe_failed;
+	}
 
-			dprintk((KERN_INFO
-			  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
+	memset(mem, 0xFF, sz);
+	hd->memQ = mem;
 
+	/* Initialize the free, done and pending Qs.
+	 */
+	Q_INIT(&hd->freeQ, MPT_DONE_Q);
+	Q_INIT(&hd->doneQ, MPT_DONE_Q);
+	Q_INIT(&hd->pendingQ, MPT_DONE_Q);
+	spin_lock_init(&hd->freedoneQlock);
+
+	mem = hd->memQ;
+	for (ii=0; ii < sh->can_queue; ii++) {
+		freedoneQ = (MPT_DONE_Q *) mem;
+		Q_ADD_TAIL(&hd->freeQ.head, freedoneQ, MPT_DONE_Q);
+		mem += sizeof(MPT_DONE_Q);
+	}
+
+	/* Initialize this Scsi_Host
+	 * internal task Q.
+	 */
+	Q_INIT(&hd->taskQ, MPT_FRAME_HDR);
+	hd->taskQcnt = 0;
+		
+	/* Allocate memory for the device structures.
+	 * A non-Null pointer at an offset
+	 * indicates a device exists.
+	 * max_id = 1 + maximum id (hosts.h)
+	 */
+	sz = sh->max_id * sizeof(void *);
+	mem = kmalloc(sz, GFP_ATOMIC);
+	if (mem == NULL) {
+		error = -ENOMEM;
+		goto mptscsih_probe_failed;
+	}
 
-			/* Clear the TM flags
-			 */
-			hd->tmPending = 0;
-			hd->tmState = TM_STATE_NONE;
-			hd->resetPending = 0;
-			hd->abortSCpnt = NULL;
-			hd->tmPtr = NULL;
-			hd->numTMrequests = 0;
+	memset(mem, 0, sz);
+	hd->Targets = (VirtDevice **) mem;
 
-			/* Clear the pointer used to store
-			 * single-threaded commands, i.e., those
-			 * issued during a bus scan, dv and
-			 * configuration pages.
-			 */
-			hd->cmdPtr = NULL;
+	dprintk((KERN_INFO
+	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
 
-			/* Initialize this SCSI Hosts' timers
-			 * To use, set the timer expires field
-			 * and add_timer
-			 */
-			init_timer(&hd->timer);
-			hd->timer.data = (unsigned long) hd;
-			hd->timer.function = mptscsih_timer_expired;
-
-			init_timer(&hd->TMtimer);
-			hd->TMtimer.data = (unsigned long) hd;
-			hd->TMtimer.function = mptscsih_taskmgmt_timeout;
-			hd->qtag_tick = jiffies;
+	/* Clear the TM flags
+	 */
+	hd->tmPending = 0;
+	hd->tmState = TM_STATE_NONE;
+	hd->resetPending = 0;
+	hd->abortSCpnt = NULL;
+	hd->tmPtr = NULL;
+	hd->numTMrequests = 0;
+		
+	/* Clear the pointer used to store
+	 * single-threaded commands, i.e., those
+	 * issued during a bus scan, dv and
+	 * configuration pages.
+	 */
+	hd->cmdPtr = NULL;
 
-			/* Moved Earlier Pam D */
-			/* ioc->sh = sh;	*/
+	/* Initialize this SCSI Hosts' timers
+	 * To use, set the timer expires field
+	 * and add_timer
+	 */
+	init_timer(&hd->timer);
+	hd->timer.data = (unsigned long) hd;
+	hd->timer.function = mptscsih_timer_expired;
+
+	init_timer(&hd->TMtimer);
+	hd->TMtimer.data = (unsigned long) hd;
+	hd->TMtimer.function = mptscsih_taskmgmt_timeout;
+	hd->qtag_tick = jiffies;
+
+	/* Moved Earlier Pam D */
+	/* ioc->sh = sh;	*/
+
+#ifdef MPTSCSIH_DBG_TIMEOUT
+	hd->ioc->timeout_hard = 0;
+	hd->ioc->timeout_delta = 30 * HZ;
+	hd->ioc->timeout_maxcnt = 0;
+	hd->ioc->timeout_cnt = 0;
+	for (ii=0; ii < 8; ii++)
+		foo_to[ii] = NULL;
+#endif
+	if (hd->is_spi) {
+		/* Update with the driver setup
+		 * values.
+		 */
+		if (hd->ioc->spi_data.maxBusWidth >
+		  driver_setup.max_width) {
+			hd->ioc->spi_data.maxBusWidth =
+			  driver_setup.max_width;
+		}
 
-			if (hd->is_spi) {
-				/* Update with the driver setup
-				 * values.
-				 */
-				if (hd->ioc->spi_data.maxBusWidth >
-				  driver_setup.max_width) {
-					hd->ioc->spi_data.maxBusWidth =
-					  driver_setup.max_width;
-				}
+		if (hd->ioc->spi_data.minSyncFactor <
+		  driver_setup.min_sync_fac) {
+			hd->ioc->spi_data.minSyncFactor =
+			  driver_setup.min_sync_fac;
+		}
 
-				if (hd->ioc->spi_data.minSyncFactor <
-				  driver_setup.min_sync_fac) {
-					hd->ioc->spi_data.minSyncFactor =
-					  driver_setup.min_sync_fac;
-				}
+		if (hd->ioc->spi_data.minSyncFactor == MPT_ASYNC) {
+			hd->ioc->spi_data.maxSyncOffset = 0;
+		}
 
-				if (hd->ioc->spi_data.minSyncFactor == MPT_ASYNC) {
-					hd->ioc->spi_data.maxSyncOffset = 0;
-				}
+		hd->ioc->spi_data.Saf_Te = driver_setup.saf_te;
 
-				hd->negoNvram = 0;
+		hd->negoNvram = 0;
 #ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-				hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
+		hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
 #endif
-				if (driver_setup.dv == 0) {
-					hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
-				}
-
-				hd->ioc->spi_data.forceDv = 0;
-				for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
-					hd->ioc->spi_data.dvStatus[ii] =
-					  MPT_SCSICFG_NEGOTIATE;
-				}
-
-				if (hd->negoNvram == 0) {
-					for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
-						hd->ioc->spi_data.dvStatus[ii] |=
-						  MPT_SCSICFG_DV_NOT_DONE;
-				}
+		if (driver_setup.dv == 0) {
+			hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
+		}
 
-				ddvprintk((MYIOC_s_INFO_FMT
-					"dv %x width %x factor %x \n",
-					hd->ioc->name, driver_setup.dv,
-					driver_setup.max_width,
-					driver_setup.min_sync_fac));
+		hd->ioc->spi_data.forceDv = 0;
+		for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
+			hd->ioc->spi_data.dvStatus[ii] =
+			  MPT_SCSICFG_NEGOTIATE;
+		}
 
-			}
+		if (hd->negoNvram == 0) {
+			for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
+				hd->ioc->spi_data.dvStatus[ii] |=
+				  MPT_SCSICFG_DV_NOT_DONE;
+		}
 
-			mpt_scsi_hosts++;
+		ddvprintk((MYIOC_s_INFO_FMT
+			"dv %x width %x factor %x saf_te %x\n",
+			hd->ioc->name, driver_setup.dv,
+			driver_setup.max_width,
+			driver_setup.min_sync_fac,
+			driver_setup.saf_te));
+	}
 
-			error = scsi_add_host (sh, &ioc->pcidev->dev);
-			if(error) {
-				dprintk((KERN_ERR MYNAM,
-				  "scsi_add_host failed\n"));
-				goto mptscsih_probe_failed;
-			}
+	mpt_scsi_hosts++;
 
-			scsi_scan_host(sh);
-			return 0;
-		} /* scsi_host_alloc */
+	error = scsi_add_host (sh, &ioc->pcidev->dev);
+	if(error) {
+		dprintk((KERN_ERR MYNAM
+		  "scsi_add_host failed\n"));
+		goto mptscsih_probe_failed;
+	}
 
-	} /* for each adapter port */
+	scsi_scan_host(sh);
+	return 0;
 
 mptscsih_probe_failed:
 
 	mptscsih_remove(pdev);
 	return error;
+
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1718,7 +1717,7 @@
  *
  *
  */
-static void __devexit
+static void
 mptscsih_remove(struct pci_dev *pdev)
 {
 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
@@ -1920,7 +1919,7 @@
 
 static struct mpt_pci_driver mptscsih_driver = {
 	.probe		= mptscsih_probe,
-	.remove		= __devexit_p(mptscsih_remove),
+	.remove		= mptscsih_remove,
 	.shutdown	= mptscsih_shutdown,
 #ifdef CONFIG_PM
 	.suspend	= mptscsih_suspend,
@@ -1979,8 +1978,8 @@
  *	mptscsih_exit - Unregisters MPT adapter(s)
  *
  */
-static void __exit
-mptscsih_exit(void)
+static void
+__exit mptscsih_exit(void)
 {
 	MPT_ADAPTER	*ioc;
 
@@ -2023,7 +2022,7 @@
 const char *
 mptscsih_info(struct Scsi_Host *SChost)
 {
-	MPT_SCSI_HOST *h = NULL;
+	MPT_SCSI_HOST *h;
 	int size = 0;
 
 	if (info_kbuf == NULL)
@@ -2099,101 +2098,20 @@
 	return ((info.pos > info.offset) ? info.pos - info.offset : 0);
 }
 
-struct mptscsih_usrcmd {
-	ulong target;
-	ulong lun;
-	ulong data;
-	ulong cmd;
-};
-
-#define UC_GET_SPEED	0x10
-
-static void mptscsih_exec_user_cmd(MPT_ADAPTER *ioc, struct mptscsih_usrcmd *uc)
+#ifndef MPTSCSIH_DBG_TIMEOUT
+static int mptscsih_user_command(MPT_ADAPTER *ioc, char *pbuf, int len)
 {
-	CONFIGPARMS		 cfg;
-	dma_addr_t		 cfg_dma_addr = -1;
-	ConfigPageHeader_t	 header;
-
-	dprintk(("exec_user_command: ioc %p cmd %ld target=%ld\n",
-			ioc, uc->cmd, uc->target));
-
-	switch (uc->cmd) {
-	case UC_GET_SPEED:
-		{
-			SCSIDevicePage0_t	*pData = NULL;
-
-			if (ioc->spi_data.sdp0length == 0)
-				return;
-
-			pData = (SCSIDevicePage0_t *)pci_alloc_consistent(ioc->pcidev,
-				 ioc->spi_data.sdp0length * 4, &cfg_dma_addr);
-
-			if (pData == NULL)
-				return;
-
-			header.PageVersion = ioc->spi_data.sdp0version;
-			header.PageLength = ioc->spi_data.sdp0length;
-			header.PageNumber = 0;
-			header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
-
-			cfg.hdr = &header;
-			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
-			cfg.dir = 0;
-			cfg.pageAddr = (u32) uc->target; /* bus << 8 | target */
-			cfg.physAddr = cfg_dma_addr;
-
-			if (mpt_config(ioc, &cfg) == 0) {
-				u32 np = le32_to_cpu(pData->NegotiatedParameters);
-				u32 tmp = np & MPI_SCSIDEVPAGE0_NP_WIDE;
-
-				printk("Target %d: %s;",
-						(u32) uc->target,
-						tmp ? "Wide" : "Narrow");
-
-				tmp = np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK;
-				if (tmp) {
-					u32 speed = 0;
-					printk(" Synchronous");
-					tmp = (tmp >> 16);
-					printk(" (Offset=0x%x", tmp);
-					tmp = np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK;
-					tmp = (tmp >> 8);
-					printk(" Factor=0x%x)", tmp);
-					if (tmp <= MPT_ULTRA320)
-						speed=160;
-					else if (tmp <= MPT_ULTRA160)
-						speed=80;
-					else if (tmp <= MPT_ULTRA2)
-						speed=40;
-					else if (tmp <= MPT_ULTRA)
-						speed=20;
-					else if (tmp <= MPT_FAST)
-						speed=10;
-					else if (tmp <= MPT_SCSI)
-						speed=5;
-
-					if (np & MPI_SCSIDEVPAGE0_NP_WIDE)
-						speed*=2;
-
-					printk(" %dMB/sec\n", speed);
-
-				} else
-					printk(" Asynchronous.\n");
-			} else {
-				printk("failed\n" );
-			}
-
-			pci_free_consistent(ioc->pcidev, ioc->spi_data.sdp0length * 4,
-					    pData, cfg_dma_addr);
-		}
-		break;
-	}
+	/* Not yet implemented */
+	return len;
 }
-
+#else
 #define is_digit(c)	((c) >= '0' && (c) <= '9')
 #define digit_to_bin(c)	((c) - '0')
 #define is_space(c)	((c) == ' ' || (c) == '\t')
 
+#define UC_DBG_TIMEOUT		0x01
+#define UC_DBG_HARDRESET	0x02
+
 static int skip_spaces(char *ptr, int len)
 {
 	int cnt, c;
@@ -2242,50 +2160,66 @@
 
 static int mptscsih_user_command(MPT_ADAPTER *ioc, char *buffer, int length)
 {
-	char *ptr	= buffer;
-	struct mptscsih_usrcmd cmd, *uc = &cmd;
-	ulong		target;
-	int		arg_len;
-	int len		= length;
+	char *ptr = buffer;
+	char btmp[24];	/* REMOVE */
+	int arg_len;
+	int len	= length;
+	int cmd;
+	ulong number = 1;
+	ulong delta = 10;
 
-	uc->target = uc->cmd = uc->lun = uc->data = 0;
-	
 	if ((len > 0) && (ptr[len -1] == '\n'))
 		--len;
 
-	if ((arg_len = is_keyword(ptr, len, "getspeed")) != 0)
-		uc->cmd = UC_GET_SPEED;
-	else
-		arg_len = 0;
-
-	dprintk(("user_command:  arg_len=%d, cmd=%ld\n", arg_len, uc->cmd));
+	if (len < 22) {
+		strncpy(btmp, buffer, len);
+		btmp[len+1]='\0';
+	} else {
+		strncpy(btmp, buffer, 22);
+		btmp[23]='\0';
+	}
+	printk("user_command:  ioc %d, buffer %s, length %d\n",
+			ioc->id, btmp, length);
 
-	if (!arg_len)
+	if ((arg_len = is_keyword(ptr, len, "timeout")) != 0)
+		cmd = UC_DBG_TIMEOUT;
+	else if ((arg_len = is_keyword(ptr, len, "hardreset")) != 0)
+		cmd = UC_DBG_HARDRESET;
+	else
 		return -EINVAL;
 
 	ptr += arg_len;
 	len -= arg_len;
 
-	switch(uc->cmd) {
-		case UC_GET_SPEED:
+	switch(cmd) {
+		case UC_DBG_TIMEOUT:
+			SKIP_SPACES(1);
+			GET_INT_ARG(number);
 			SKIP_SPACES(1);
-			GET_INT_ARG(target);
-			uc->target = target;
+			GET_INT_ARG(delta);
 			break;
 	}
 
-	dprintk(("user_command: target=%ld len=%d\n", uc->target, len));
+	printk("user_command: cnt=%ld delta=%ld\n", number, delta);
 
 	if (len)
 		return -EINVAL;
 	else {
-		/* process this command ...
-		 */
-		mptscsih_exec_user_cmd(ioc, uc);
+		if (cmd == UC_DBG_HARDRESET) {
+			ioc->timeout_hard = 1;
+		} else if (cmd == UC_DBG_TIMEOUT) {
+			/* process this command ...
+			 */
+			ioc->timeout_maxcnt = 0;
+			ioc->timeout_delta = delta < 2 ? 2 : delta;
+			ioc->timeout_cnt = 0;
+			ioc->timeout_maxcnt = number < 8 ? number: 8;
+		}
 	}
 	/* Not yet implemented */
 	return length;
 }
+#endif
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
@@ -2303,7 +2237,7 @@
 int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
 			int length, int func)
 {
-	MPT_ADAPTER	*ioc = NULL;
+	MPT_ADAPTER	*ioc;
 	MPT_SCSI_HOST	*hd = NULL;
 	int size = 0;
 
@@ -2334,49 +2268,8 @@
 
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-	static int max_qd = 1;
 #define ADD_INDEX_LOG(req_ent)	do { } while(0)
 
-#ifdef	DROP_TEST
-#define DROP_IOC	1	/* IOC to force failures */
-#define DROP_TARGET	3	/* Target ID to force failures */
-#define	DROP_THIS_CMD	10000	/* iteration to drop command */
-static int dropCounter = 0;
-static int dropTestOK = 0;	/* num did good */
-static int dropTestBad = 0;	/* num did bad */
-static int dropTestNum = 0;	/* total = good + bad + incomplete */
-static int numTotCmds = 0;
-static MPT_FRAME_HDR *dropMfPtr = NULL;
-static int numTMrequested = 0;
-#endif
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *	mptscsih_put_msgframe - Wrapper routine to post message frame to F/W.
- *	@context: Call back context (ScsiDoneCtx, ScsiScanDvCtx)
- *	@id: IOC id number
- *	@mf: Pointer to message frame
- *
- *	Handles the call to mptbase for posting request and queue depth
- *	tracking.
- *
- *	Returns none.
- */
-static inline void
-mptscsih_put_msgframe(int context, int id, MPT_FRAME_HDR *mf)
-{
-	/* Main banana... */
-	atomic_inc(&queue_depth);
-	if (atomic_read(&queue_depth) > max_qd) {
-		max_qd = atomic_read(&queue_depth);
-		dprintk((KERN_INFO MYNAM ": Queue depth now %d.\n", max_qd));
-	}
-
-	mpt_put_msg_frame(context, id, mf);
-
-	return;
-}
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
@@ -2396,7 +2289,7 @@
 	MPT_FRAME_HDR		*mf;
 	SCSIIORequest_t		*pScsiReq;
 	VirtDevice		*pTarget;
-	MPT_DONE_Q		*buffer = NULL;
+	MPT_DONE_Q		*buffer;
 	unsigned long		 flags;
 	int	 target;
 	int	 lun;
@@ -2424,9 +2317,14 @@
 
 	if (hd->resetPending) {
 		/* Prevent new commands from being issued
-		 * while reloading the FW.
+		 * while reloading the FW. Reset timer to 60 seconds,
+		 * as the FW can take some time to come ready.
+		 * For New EH, cmds on doneQ posted to FW.
 		 */
 		did_errcode = 1;
+		mod_timer(&SCpnt->eh_timeout, jiffies + (HZ * 60));
+		dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
+			(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
 		goto did_error;
 	}
 
@@ -2481,8 +2379,8 @@
 
 	/* Use the above information to set up the message frame
 	 */
-	pScsiReq->TargetID = target;
-	pScsiReq->Bus = hd->port;
+	pScsiReq->TargetID = (u8) target;
+	pScsiReq->Bus = (u8) SCpnt->device->channel;
 	pScsiReq->ChainOffset = 0;
 	pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
 	pScsiReq->CDBLength = SCpnt->cmd_len;
@@ -2501,12 +2399,14 @@
 
 	/*
 	 *  Write SCSI CDB into the message
-	 *  Should write from cmd_len up to 16, but skip for performance reasons.
 	 */
 	cmd_len = SCpnt->cmd_len;
 	for (ii=0; ii < cmd_len; ii++)
 		pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
 
+	for (ii=cmd_len; ii < 16; ii++)
+		pScsiReq->CDB[ii] = 0;
+
 	/* DataLength */
 	pScsiReq->DataLength = cpu_to_le32(datalen);
 
@@ -2532,39 +2432,6 @@
 		hd->ScsiLookup[my_idx] = SCpnt;
 		SCpnt->host_scribble = NULL;
 
-#ifdef	DROP_TEST
-		numTotCmds++;
-		/* If the IOC number and target match, increment
-		 * counter. If counter matches DROP_THIS, do not
-		 * issue command to FW to force a reset.
-		 * Save the MF pointer so we can free resources
-		 * when task mgmt completes.
-		 */
-		if ((hd->ioc->id == DROP_IOC) && (target == DROP_TARGET)) {
-			dropCounter++;
-
-			if (dropCounter == DROP_THIS_CMD) {
-				dropCounter = 0;
-
-				/* If global is set, then we are already
-				 * doing something - so keep issuing commands.
-				 */
-				if (dropMfPtr == NULL) {
-					dropTestNum++;
-					dropMfPtr = mf;
-					atomic_inc(&queue_depth);
-					printk(MYIOC_s_INFO_FMT
-						"Dropped SCSI cmd (%p)\n",
-						hd->ioc->name, SCpnt);
-					printk("mf (%p) req (%4x) tot cmds (%d)\n",
-						mf, my_idx, numTotCmds);
-
-					return 0;
-				}
-			}
-		}
-#endif
-
 		/* SCSI specific processing */
 		issueCmd = 1;
 		if (hd->is_spi) {
@@ -2617,8 +2484,20 @@
 			}
 		}
 
+#ifdef MPTSCSIH_DBG_TIMEOUT
+		if (hd->ioc->timeout_cnt < hd->ioc->timeout_maxcnt) {
+			foo_to[hd->ioc->timeout_cnt] = SCpnt;
+			hd->ioc->timeout_cnt++;
+			//mod_timer(&SCpnt->eh_timeout, jiffies + hd->ioc->timeout_delta);
+			issueCmd = 0;
+			printk(MYIOC_s_WARN_FMT
+				"to pendingQ: (sc=%p, mf=%p, time=%ld)\n",
+				hd->ioc->name, SCpnt, mf, jiffies);
+		}
+#endif
+
 		if (issueCmd) {
-			mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
+			mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
 			dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
 					hd->ioc->name, SCpnt, mf, my_idx));
 		} else {
@@ -2660,6 +2539,8 @@
 	SCpnt->result = (DID_BUS_BUSY << 16);
 	spin_lock_irqsave(&hd->freedoneQlock, flags);
 	if (!Q_IS_EMPTY(&hd->freeQ)) {
+		dtmprintk((MYIOC_s_WARN_FMT "SCpnt=%p to doneQ\n",
+			(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
 		buffer = hd->freeQ.head;
 		Q_DEL_ITEM(buffer);
 
@@ -2692,7 +2573,7 @@
 static void
 mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx)
 {
-	MPT_FRAME_HDR *chain = NULL;
+	MPT_FRAME_HDR *chain;
 	unsigned long flags;
 	int chain_idx;
 	int next;
@@ -2755,9 +2636,9 @@
  *	Returns 0 for SUCCESS or -1 if FAILED.
  */
 static int
-mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
+mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
 {
-	MPT_ADAPTER	*ioc = NULL;
+	MPT_ADAPTER	*ioc;
 	int		 rc = -1;
 	int		 doTask = 1;
 	u32		 ioc_raw_state;
@@ -2770,19 +2651,18 @@
 		return 0;
 
 	ioc = hd->ioc;
-	dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
-
 	if (ioc == NULL) {
 		printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
-		return 0;
+		return FAILED;
 	}
+	dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
 
 	// SJR - CHECKME - Can we avoid this here?
 	// (mpt_HardResetHandler has this check...)
 	spin_lock_irqsave(&ioc->diagLock, flags);
 	if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
 		spin_unlock_irqrestore(&ioc->diagLock, flags);
-		return 0;
+		return FAILED;
 	}
 	spin_unlock_irqrestore(&ioc->diagLock, flags);
 
@@ -2792,6 +2672,37 @@
 	if (hd->numTMrequests > MPT_HOST_TOO_MANY_TM)
 		doTask = 0;
 
+	/*  Wait a fixed amount of time for the TM pending flag to be cleared.
+	 *  If we time out and not bus reset, then we return a FAILED status to the caller.
+	 *  The call to mptscsih_tm_pending_wait() will set the pending flag if we are
+	 *  successful. Otherwise, reload the FW.
+	 */
+	if (mptscsih_tm_pending_wait(hd) == FAILED) {
+		if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
+			dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: "
+			   "Timed out waiting for last TM (%d) to complete! \n",
+			   hd->ioc->name, hd->tmPending));
+			return FAILED;
+		} else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
+			dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: "
+			   "Timed out waiting for last TM (%d) to complete! \n",
+			   hd->ioc->name, hd->tmPending));
+			return FAILED;
+		} else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
+			dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: "
+			   "Timed out waiting for last TM (%d) to complete! \n",
+			   hd->ioc->name, hd->tmPending));
+			if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
+				return FAILED;
+
+			doTask = 0;
+		}
+	} else {
+		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
+		hd->tmPending |=  (1 << type);
+		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+	}
+
 	/* Is operational?
 	 */
 	ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
@@ -2799,7 +2710,7 @@
 #ifdef MPT_DEBUG_RESET
 	if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
 		printk(MYIOC_s_WARN_FMT
-			"TM Handler: IOC Not operational! state 0x%x Calling HardResetHandler\n",
+			"TM Handler: IOC Not operational(0x%x)!\n",
 			hd->ioc->name, ioc_raw_state);
 	}
 #endif
@@ -2811,23 +2722,24 @@
 		 */
 		if (hd->hard_resets < -1)
 			hd->hard_resets++;
-		rc = mptscsih_IssueTaskMgmt(hd, type, target, lun, ctx2abort, timeout, sleepFlag);
+		rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout, sleepFlag);
 		if (rc) {
 			printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
 		} else {
 			dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
 		}
 	}
-#ifdef DROP_TEST
-	numTMrequested++;
-	if (numTMrequested > 5) {
-		rc = 0;		/* set to 1 to force a hard reset */
-		numTMrequested = 0;
-	}
+
+#ifdef MPTSCSIH_DBG_TIMEOUT
+	if (hd->ioc->timeout_hard)
+		rc = 1;
 #endif
 
-	if (rc || ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw)) {
-		dtmprintk((MYIOC_s_INFO_FMT "Falling through to HardReset! \n",
+	/* Only fall through to the HRH if this is a bus reset
+	 */
+	if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
+		ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
+		dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
 			 hd->ioc->name));
 		rc = mpt_HardResetHandler(hd->ioc, sleepFlag);
 	}
@@ -2857,7 +2769,7 @@
  *	else other non-zero value returned.
  */
 static int
-mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
+mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
 {
 	MPT_FRAME_HDR	*mf;
 	SCSITaskMgmt_t	*pScsiTm;
@@ -2879,7 +2791,7 @@
 	 */
 	pScsiTm = (SCSITaskMgmt_t *) mf;
 	pScsiTm->TargetID = target;
-	pScsiTm->Bus = hd->port;
+	pScsiTm->Bus = channel;
 	pScsiTm->ChainOffset = 0;
 	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
 
@@ -2953,8 +2865,11 @@
 		return FAILED;
 	}
 
-	printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p, numIOs=%d)\n",
-	       hd->ioc->name, SCpnt, atomic_read(&queue_depth));
+	if (hd->resetPending)
+		return FAILED;
+
+	printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
+	       hd->ioc->name, SCpnt);
 
 	if (hd->timeouts < -1)
 		hd->timeouts++;
@@ -2968,38 +2883,21 @@
 		search_doneQ_for_cmd(hd, SCpnt);
 
 		SCpnt->result = DID_RESET << 16;
-		SCpnt->scsi_done(SCpnt);
 		dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
 			   "Command not in the active list! (sc=%p)\n",
 			   hd->ioc->name, SCpnt));
 		return SUCCESS;
 	}
 
-	/*  Wait a fixed amount of time for the TM pending flag to be cleared.
-	 *  If we time out, then we return a FAILED status to the caller.  This
-	 *  call to mptscsih_tm_pending_wait() will set the pending flag if we are
-	 *  successful.
-	 */
-	spin_unlock_irq(host_lock);
-	if (mptscsih_tm_pending_wait(hd) == FAILED){
-		dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
-			   "Timed out waiting for previous TM to complete! "
-			   "(sc = %p)\n",
-			   hd->ioc->name, SCpnt));
-		spin_lock_irq(host_lock);
-		return FAILED;
-	}
-	spin_lock_irq(host_lock);
-
 	/* If this command is pended, then timeout/hang occurred
 	 * during DV. Post command and flush pending Q
 	 * and then following up with the reset request.
 	 */
 	if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) {
-		mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
+		mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
 		post_pendingQ_commands(hd);
 		dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
-			   "Found command in pending queue! (sc=%p)\n",
+			   "Posting pended cmd! (sc=%p)\n",
 			   hd->ioc->name, SCpnt));
 	}
 
@@ -3017,7 +2915,7 @@
 
 	spin_unlock_irq(host_lock);
 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
-		SCpnt->device->id, SCpnt->device->lun,
+		SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
 		ctx2abort, (HZ*2) /* 2 second timeout */,CAN_SLEEP)
 		< 0) {
 
@@ -3064,31 +2962,21 @@
 		return FAILED;
 	}
 
-	printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p, numIOs=%d)\n",
-	       hd->ioc->name, SCpnt, atomic_read(&queue_depth));
+	if (hd->resetPending)
+		return FAILED;
 
-	/* Unsupported for SCSI. Suppored for FCP
+	printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
+	       hd->ioc->name, SCpnt);
+
+	/* Unsupported for SCSI. Supported for FCP
 	 */
 	if (hd->is_spi)
 		return FAILED;
 
-	/*  Wait a fixed amount of time for the TM pending flag to be cleared.
-	 *  If we time out, then we return a FAILED status to the caller.  This
-	 *  call to mptscsih_tm_pending_wait() will set the pending flag if we are
-	 *  successful.
-	 */
 	spin_unlock_irq(host_lock);
-	if (mptscsih_tm_pending_wait(hd) == FAILED) {
-		dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_dev_reset: "
-			   "Timed out waiting for previous TM to complete! "
-			   "(sc = %p)\n",
-			   hd->ioc->name, SCpnt));
-		spin_lock_irq(host_lock);
-		return FAILED;
-	}
-
 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
-		SCpnt->device->id, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
+		SCpnt->device->channel, SCpnt->device->id,
+		0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
 		< 0){
 		/* The TM request failed and the subsequent FW-reload failed!
 		 * Fatal error case.
@@ -3129,30 +3017,19 @@
 		return FAILED;
 	}
 
-	printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p, numIOs=%d)\n",
-	       hd->ioc->name, SCpnt, atomic_read(&queue_depth));
+	printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
+	       hd->ioc->name, SCpnt);
 
 	if (hd->timeouts < -1)
 		hd->timeouts++;
 
-	/*  Wait a fixed amount of time for the TM pending flag to be cleared.
-	 *  If we time out, then we return a FAILED status to the caller.  This
-	 *  call to mptscsih_tm_pending_wait() will set the pending flag if we are
-	 *  successful.
-	 */
-	spin_unlock_irq(host_lock);
-	if (mptscsih_tm_pending_wait(hd) == FAILED) {
-		dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_bus_reset: "
-			   "Timed out waiting for previous TM to complete! "
-			   "(sc = %p)\n",
-			   hd->ioc->name, SCpnt));
-		spin_lock_irq(host_lock);
-		return FAILED;
-	}
-
 	/* We are now ready to execute the task management request. */
+	spin_unlock_irq(host_lock);
+//	printk("testing start : mptscsih_schedule_reset\n");
+//	mptscsih_schedule_reset(hd);
+//	printk("testing end: mptscsih_schedule_reset\n");
 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
-		0, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
+		SCpnt->device->channel, 0, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
 	    < 0){
 
 		/* The TM request failed and the subsequent FW-reload failed!
@@ -3197,8 +3074,6 @@
 
 	printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
 	       hd->ioc->name, SCpnt);
-	printk(KERN_WARNING MYNAM ": %s: IOs outstanding = %d\n",
-	       hd->ioc->name, atomic_read(&queue_depth));
 
 	/*  If our attempts to reset the host failed, then return a failed
 	 *  status.  The host will be taken off line by the SCSI mid-layer.
@@ -3274,7 +3149,7 @@
 {
 	SCSITaskMgmtReply_t	*pScsiTmReply;
 	SCSITaskMgmt_t		*pScsiTmReq;
-	MPT_SCSI_HOST		*hd = NULL;
+	MPT_SCSI_HOST		*hd;
 	unsigned long		 flags;
 	u8			 tmType = 0;
 
@@ -3325,10 +3200,7 @@
 			 */
 			if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
 				hd->abortSCpnt = NULL;
-#ifdef	DROP_TEST
-			if (dropMfPtr)
-				dropTestBad++;
-#endif
+
 			/* If an internal command is present
 			 * or the TM failed - reload the FW.
 			 * FC FW may respond FAILED to an ABORT
@@ -3349,17 +3221,9 @@
 			hd->abortSCpnt = NULL;
 			flush_doneQ(hd);
 
-#ifdef	DROP_TEST
-			if (dropMfPtr)
-				dropTestOK++;
-#endif
 		}
 	}
 
-#ifdef	DROP_TEST
-	mptscsih_flush_drop_test(hd);
-#endif
-
 	hd->tmPtr = NULL;
 	spin_lock_irqsave(&ioc->FreeQlock, flags);
 	hd->tmPending = 0;
@@ -3438,15 +3302,14 @@
 
 	hd = (MPT_SCSI_HOST *)host->hostdata;
 
-
 	if (hd == NULL)
-		return ENODEV;
+		return -ENODEV;
 
 	if ((vdev = hd->Targets[device->id]) == NULL) {
 		if ((vdev = kmalloc(sizeof(VirtDevice), GFP_ATOMIC)) == NULL) {
 			printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%d) FAILED!\n",
-					hd->ioc->name, (int)sizeof(VirtDevice));
-			return ENOMEM;
+			hd->ioc->name, (int)sizeof(VirtDevice));
+			return -ENOMEM;
 		} else {
 			memset(vdev, 0, sizeof(VirtDevice));
 			rwlock_init(&vdev->VdevLock);
@@ -3478,7 +3341,7 @@
 	VirtDevice		*vdev;
 
 	hd = (MPT_SCSI_HOST *)host->hostdata;
-	
+
 	if (hd == NULL)
 		return;
 
@@ -3489,8 +3352,8 @@
 	if ((vdev = hd->Targets[device->id]) != NULL) {
 		vdev->num_luns--;
 
-		if (vdev->luns & (1 << device->lun))
-			vdev->luns &= ~(1 << device->lun);
+		if (vdev->luns[0] & (1 << device->lun))
+			vdev->luns[0] &= ~(1 << device->lun);
 
 		/* Free device structure only if number of luns is 0.
 		 */
@@ -3499,16 +3362,20 @@
 			hd->Targets[device->id] = NULL;
 
 			if (hd->is_spi) {
-				hd->ioc->spi_data.dvStatus[device->id] = MPT_SCSICFG_NEGOTIATE;
+				hd->ioc->spi_data.dvStatus[device->id] =
+				MPT_SCSICFG_NEGOTIATE;
 
 				if (hd->negoNvram == 0)
-					hd->ioc->spi_data.dvStatus[device->id] |= MPT_SCSICFG_DV_NOT_DONE;
+					hd->ioc->spi_data.dvStatus[device->id]
+					|= MPT_SCSICFG_DV_NOT_DONE;
 
 				/* Don't alter isRaid, not allowed to move
 				 * volumes on a running system.
 				 */
-				if (hd->ioc->spi_data.isRaid & (1 << (device->id)))
-					hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
+				if (hd->ioc->spi_data.isRaid & (1 <<
+					(device->id)))
+					hd->ioc->spi_data.forceDv |=
+					MPT_SCSICFG_RELOAD_IOC_PG3;
 			}
 		}
 	}
@@ -3525,205 +3392,76 @@
 int
 mptscsih_slave_configure(Scsi_Device *device)
 {
-	struct Scsi_Host	*host = device->host;
-	VirtDevice		*vdev;
-	MPT_SCSI_HOST		*hd;
-
-	hd = (MPT_SCSI_HOST *)host->hostdata;
-
-	dsprintk((KERN_INFO "slave_configure: device @ %p, id=%d, LUN=%d, channel=%d\n",
-		device, device->id, device->lun, device->channel));
-	dsprintk((KERN_INFO "sdtr %d wdtr %d ppr %d inq length=%d\n",
-		device->sdtr, device->wdtr, device->ppr, device->inquiry_len));
-	dsprintk(("tagged %d simple %d ordered %d\n",
-		device->tagged_supported, device->simple_tags, device->ordered_tags));
-
-	/*	set target parameters, queue depths, set dv flags ?  */
-	if (hd && (hd->Targets != NULL)) {
-		vdev = hd->Targets[device->id];
-
-		if (vdev && !(vdev->tflags & MPT_TARGET_FLAGS_CONFIGURED)) {
-			/* Configure only the first discovered LUN
-			 */
-			vdev->raidVolume = 0;
-			if (hd->is_spi && (hd->ioc->spi_data.isRaid & (1 << (device->id)))) {
-				vdev->raidVolume = 1;
-				ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", device->id));
-			}
-
-			mptscsih_target_settings(hd, vdev, device);
+	struct Scsi_Host	*sh = device->host;
+	VirtDevice		*pTarget;
+	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)sh->hostdata;
 
-			vdev->tflags |= MPT_TARGET_FLAGS_CONFIGURED;
-		}
+	if ((hd == NULL) || (hd->Targets == NULL)) {
+		return 0;
+	}
 
-		if (vdev) {
-			/* set the queue depth for all devices
-			 */
-			if (!device->tagged_supported ||
-			    !(vdev->tflags & MPT_TARGET_FLAGS_Q_YES)) {
+	dsprintk((MYIOC_s_INFO_FMT
+		"device @ %p, id=%d, LUN=%d, channel=%d\n",
+		hd->ioc->name, device, device->id, device->lun, device->channel));
+	dsprintk((MYIOC_s_INFO_FMT
+		"sdtr %d wdtr %d ppr %d inq length=%d\n",
+		hd->ioc->name, device->sdtr, device->wdtr,
+		device->ppr, device->inquiry_len));
+
+	if (device->id > sh->max_id) {
+		/* error case, should never happen */
+		scsi_adjust_queue_depth(device, 0, 1);
+		goto slave_configure_exit;
+	}
+
+	pTarget = hd->Targets[device->id];
+
+	if (pTarget == NULL) {
+		/* error case - don't know about this device */
+		scsi_adjust_queue_depth(device, 0, 1);
+		goto slave_configure_exit;
+	}
+
+	mptscsih_initTarget(hd, device->channel, device->id, device->lun,
+		device->inquiry, device->inquiry_len );
+	scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
+		MPT_SCSI_CMD_PER_DEV_HIGH);
+	if ( hd->is_spi ) {
+		if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
+			if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
 				scsi_adjust_queue_depth(device, 0, 1);
-			} else if (vdev->type == 0x00
-				   && (vdev->minSyncFactor <= MPT_ULTRA160 || !hd->is_spi)) {
+			else if (((pTarget->inq_data[0] & 0x1f) == 0x00)
+			  && (pTarget->minSyncFactor <= MPT_ULTRA160 ))
 				scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
-							MPT_SCSI_CMD_PER_DEV_HIGH);
-			} else {
+					MPT_SCSI_CMD_PER_DEV_HIGH);
+			else
 				scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
-							MPT_SCSI_CMD_PER_DEV_LOW);
-			}
-
-			vdev->luns |= (1 << device->lun);
-			vdev->tflags |= MPT_TARGET_FLAGS_CONFIGURED;
-		}
-	}
-	return 0;
-}
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *  Update the target negotiation parameters based on the
- *  the Inquiry data, adapter capabilities, and NVRAM settings.
- *
- */
-static void
-mptscsih_target_settings(MPT_SCSI_HOST *hd, VirtDevice *target, Scsi_Device *sdev)
-{
-	ScsiCfgData *pspi_data = &hd->ioc->spi_data;
-	int  id = (int) target->target_id;
-	int  nvram;
-	u8 width = MPT_NARROW;
-	u8 factor = MPT_ASYNC;
-	u8 offset = 0;
-	u8 nfactor;
-	u8 noQas = 1;
-
-	ddvtprintk((KERN_INFO "set Target: (id %d) \n", id));
-
-	if (!hd->is_spi) {
-		/* FC - only care about QTag support
-	 	 */
-		if (sdev->tagged_supported)
-			target->tflags |= MPT_TARGET_FLAGS_Q_YES;
-		return;
-	}
-
-	/* SCSI - Set flags based on Inquiry data
-	 */
-	if (sdev->scsi_level < 2) {
-		width = 0;
-		factor = MPT_ULTRA2;
-		offset = pspi_data->maxSyncOffset;
-	} else {
-		width = sdev->wdtr;
-		if (sdev->sdtr) {
-			if (sdev->ppr) {
-				/* U320 requires IU capability */
-				if ((sdev->inquiry_len > 56) && (sdev->inquiry[56] & 0x01))
-					factor = MPT_ULTRA320;
-				else
-					factor = MPT_ULTRA160;
-			} else
-				factor = MPT_ULTRA2;
-
-			/* If RAID, never disable QAS
-			 * else if non RAID, do not disable
-			 *   QAS if bit 1 is set
-			 * bit 1 QAS support, non-raid only
-			 * bit 0 IU support
-			 */
-			if ((target->raidVolume == 1) ||
-			    ((sdev->inquiry_len > 56) && (sdev->inquiry[56] & 0x02)))
-				noQas = 0;
-
-			offset = pspi_data->maxSyncOffset;
-
+					MPT_SCSI_CMD_PER_DEV_LOW);
 		} else {
-			factor = MPT_ASYNC;
-			offset = 0;
+			/* error case - No Inq. Data */
+			scsi_adjust_queue_depth(device, 0, 1);
 		}
 	}
 
-	/* Update tflags based on NVRAM settings. (SCSI only)
-	 */
-	if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
-		nvram = pspi_data->nvram[id];
-		nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
-
-		if (width)
-			width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
-
-		if (offset > 0) {
-			/* Ensure factor is set to the
-			 * maximum of: adapter, nvram, inquiry
-			 */
-			if (nfactor) {
-				if (nfactor < pspi_data->minSyncFactor )
-					nfactor = pspi_data->minSyncFactor;
-
-				factor = MAX (factor, nfactor);
-				if (factor == MPT_ASYNC)
-					offset = 0;
-			} else {
-				offset = 0;
-				factor = MPT_ASYNC;
-			}
-		} else
-			factor = MPT_ASYNC;
-	}
+	dsprintk((MYIOC_s_INFO_FMT
+		"Queue depth=%d, tflags=%x\n",
+		hd->ioc->name, device->queue_depth, pTarget->tflags));
 
-	/* Make sure data is consistent
-	 */
-	if ((!width) && (factor < MPT_ULTRA2))
-		factor = MPT_ULTRA2;
-
-	/* Save the data to the target structure.
-	 */
-	target->minSyncFactor = factor;
-	target->maxOffset = offset;
-	target->maxWidth = width;
-	if (sdev->tagged_supported)
-		target->tflags |= MPT_TARGET_FLAGS_Q_YES;
-
-	/* Disable unused features.
-	 */
-	target->negoFlags = pspi_data->noQas;
-	if (!width)
-		target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
+	dsprintk((MYIOC_s_INFO_FMT
+		"negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
+		hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
 
-	if (!offset)
-		target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
+slave_configure_exit:
 
-	if (noQas)
-		target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
-
-	/* GEM, processor WORKAROUND
-	 */
-	target->type = sdev->inquiry[0] & 0x1F;
-	if ((target->type == 0x03) || (target->type > 0x08)){
-		target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
-		pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
-	}
-
-	/* Disable QAS if mixed configuration case
-	 */
-	if ((noQas) && (!pspi_data->noQas) && (target->type == 0x00)){
-		VirtDevice	*vdev;
-		int ii;
+	dsprintk((MYIOC_s_INFO_FMT
+		"tagged %d, simple %d, ordered %d\n",
+		hd->ioc->name,device->tagged_supported, device->simple_tags,
+		device->ordered_tags));
 
-		ddvtprintk((KERN_INFO "Disabling QAS!\n"));
-		pspi_data->noQas = MPT_TARGET_NO_NEGO_QAS;
-		for (ii = 0; ii < id; ii++) {
-			vdev = hd->Targets[id];
-			if (vdev != NULL)
-				vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
-		}
-	}
-
-	ddvtprintk((KERN_INFO "Final settings id %d: dvstatus 0x%x\n", sdev->id, pspi_data->dvStatus[id]));
-	ddvtprintk(("wide %d, factor 0x%x offset 0x%x neg flags 0x%x flags 0x%x\n",
-			width, factor, offset, target->negoFlags, target->tflags));
-
-	return;
+	return 0;
 }
 
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  Private routines...
@@ -3789,11 +3527,10 @@
 		thisIo.SCSIStatus = pScsiReply->SCSIStatus;
 		thisIo.DoDisplay = 1;
 		if (hd->is_multipath)
-			sprintf(devFoo, "%d:%d:%d \"%s\"",
+			sprintf(devFoo, "%d:%d:%d",
 					hd->ioc->id,
 					pReq->TargetID,
-					pReq->LUN[1],
-					target->dev_vol_name);
+					pReq->LUN[1]);
 		else
 			sprintf(devFoo, "%d:%d:%d", hd->ioc->id, sc->device->id, sc->device->lun);
 		thisIo.DevIDStr = devFoo;
@@ -3842,7 +3579,7 @@
 	unsigned long	 flags;
 	MPT_DONE_Q	*buffer;
 	MPT_FRAME_HDR	*mf = NULL;
-	MPT_FRAME_HDR	*cmdMfPtr = NULL;
+	MPT_FRAME_HDR	*cmdMfPtr;
 
 	ddvtprintk((MYIOC_s_INFO_FMT ": search_pendingQ ...", hd->ioc->name));
 	cmdMfPtr = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
@@ -3911,7 +3648,7 @@
 			continue;
 		}
 
-		mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf);
+		mpt_put_msg_frame(ScsiDoneCtx, hd->ioc->id, mf);
 
 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
 		{
@@ -3930,12 +3667,13 @@
 static int
 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
 {
-	MPT_SCSI_HOST	*hd = NULL;
+	MPT_SCSI_HOST	*hd;
 	unsigned long	 flags;
 
 	dtmprintk((KERN_WARNING MYNAM
 			": IOC %s_reset routed to SCSI host driver!\n",
-			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+			reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
+			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
 
 	/* If a FW reload request arrives after base installed but
 	 * before all scsi hosts have been attached, then an alt_ioc
@@ -3946,9 +3684,8 @@
 	else
 		hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
 
-	if (reset_phase == MPT_IOC_PRE_RESET) {
-		dtmprintk((MYIOC_s_WARN_FMT "Do Pre-Diag Reset handling\n",
-			ioc->name));
+	if (reset_phase == MPT_IOC_SETUP_RESET) {
+		dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
 
 		/* Clean Up:
 		 * 1. Set Hard Reset Pending Flag
@@ -3956,6 +3693,15 @@
 		 */
 		hd->resetPending = 1;
 
+#if 0		
+		/* calling mod_timer() panics in 2.6 kernel...
+		 * need to investigate
+		 */
+		mptscsih_reset_timeouts (hd);
+#endif
+	} else if (reset_phase == MPT_IOC_PRE_RESET) {
+		dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
+
 		/* 2. Flush running commands
 		 *	Clean drop test code - if compiled
 		 *	Clean ScsiLookup (and associated memory)
@@ -3964,9 +3710,6 @@
 
 		/* 2a. Drop Test Command.
 		 */
-#ifdef	DROP_TEST
-		mptscsih_flush_drop_test(hd);
-#endif
 
 		/* 2b. Reply to OS all known outstanding I/O commands.
 		 */
@@ -3979,7 +3722,6 @@
 		if (hd->cmdPtr) {
 			del_timer(&hd->timer);
 			mpt_free_msg_frame(ScsiScanDvCtx, ioc->id, hd->cmdPtr);
-			atomic_dec(&queue_depth);
 		}
 
 		/* 2d. If a task management has not completed,
@@ -3990,12 +3732,14 @@
 			mpt_free_msg_frame(ScsiTaskCtx, ioc->id, hd->tmPtr);
 		}
 
-		dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset handling complete.\n",
-			ioc->name));
+#ifdef MPTSCSIH_DBG_TIMEOUT
+		ioc->timeout_hard = 0;
+#endif
+
+		dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
 
 	} else {
-		dtmprintk((MYIOC_s_WARN_FMT "Do Post-Diag Reset handling\n",
-			ioc->name));
+		dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
 
 		/* Once a FW reload begins, all new OS commands are
 		 * redirected to the doneQ w/ a reset status.
@@ -4052,10 +3796,6 @@
 		 */
 		flush_doneQ(hd);
 
-		dtmprintk((MYIOC_s_WARN_FMT "Post-Reset handling complete.\n",
-			ioc->name));
-
-
 		/* 8. Set flag to force DV and re-read IOC Page 3
 		 */
 		if (hd->is_spi) {
@@ -4063,6 +3803,8 @@
 			ddvtprintk(("Set reload IOC Pg3 Flag\n"));
 		}
 
+		dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
+
 	}
 
 	return 1;		/* currently means nothing really */
@@ -4571,6 +4313,268 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptscsih_initTarget - Target, LUN alloc/free functionality.
+ *	@hd: Pointer to MPT_SCSI_HOST structure
+ *	@bus_id: Bus number (?)
+ *	@target_id: SCSI target id
+ *	@lun: SCSI LUN id
+ *	@data: Pointer to data
+ *	@dlen: Number of INQUIRY bytes
+ *
+ *	NOTE: It's only SAFE to call this routine if data points to
+ *	sane & valid STANDARD INQUIRY data!
+ *
+ *	Allocate and initialize memory for this target.
+ *	Save inquiry data.
+ *
+ */
+static void
+mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
+{
+	int		indexed_lun, lun_index;
+	VirtDevice	*vdev;
+	char		data_56;
+
+	dprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
+			hd->ioc->name, bus_id, target_id, lun, hd));
+
+	/* Is LUN supported? If so, upper 3 bits will be 0
+	* in first byte of inquiry data.
+	*/
+	if (data[0] & 0xe0)
+		return;
+
+	vdev = hd->Targets[target_id];
+
+	lun_index = (lun >> 5);  /* 32 luns per lun_index */
+	indexed_lun = (lun % 32);
+	vdev->luns[lun_index] |= (1 << indexed_lun);
+
+	vdev->raidVolume = 0;
+	if (hd->is_spi) {
+		if (hd->ioc->spi_data.isRaid & (1 << target_id)) {
+			vdev->raidVolume = 1;
+			ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", target_id));
+		}
+	}
+
+	if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
+		if ( dlen > 8 ) {
+			memcpy (vdev->inq_data, data, 8);
+		} else {
+			memcpy (vdev->inq_data, data, dlen);
+		}
+		vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
+
+		/* If LUN 0, tape and have not done DV, set the DV flag.
+		 */
+		if (hd->is_spi && (lun == 0) && (data[0] == SCSI_TYPE_TAPE)) {
+			ScsiCfgData *pSpi = &hd->ioc->spi_data;
+			if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
+				pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
+		}
+
+		if ( (data[0] == SCSI_TYPE_PROC) &&
+			!(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
+			if ( dlen > 49 ) {
+				vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
+				if ( data[44] == 'S' &&
+				     data[45] == 'A' &&
+				     data[46] == 'F' &&
+				     data[47] == '-' &&
+				     data[48] == 'T' &&
+				     data[49] == 'E' ) {
+					vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+					mptscsih_writeIOCPage4(hd, target_id, bus_id);
+				}
+			} else {
+				/* Treat all Processors as SAF-TE if
+				 * command line option is set */
+				if ( hd->ioc->spi_data.Saf_Te ) {
+					vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+					mptscsih_writeIOCPage4(hd, target_id, bus_id);
+				}
+			}
+		}
+
+		data_56 = 0;
+		if (dlen > 56) {
+			if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
+			/* Update the target capabilities
+			 */
+				data_56 = data[56];
+				vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
+			}
+		}
+		mptscsih_setTargetNegoParms(hd, vdev, data_56);
+	}
+
+	dprintk((KERN_INFO "  target = %p\n", vdev));
+	return;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *  Update the target negotiation parameters based on the
+ *  the Inquiry data, adapter capabilities, and NVRAM settings.
+ *
+ */
+void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
+{
+	ScsiCfgData *pspi_data = &hd->ioc->spi_data;
+	int  id = (int) target->target_id;
+	int  nvram;
+	char canQ = 0;
+	VirtDevice	*vdev;
+	int ii;
+	u8 width = MPT_NARROW;
+	u8 factor = MPT_ASYNC;
+	u8 offset = 0;
+	u8 version, nfactor;
+	u8 noQas = 1;
+
+	if (!hd->is_spi) {
+		if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
+			if (target->inq_data[7] & 0x02)
+				target->tflags |= MPT_TARGET_FLAGS_Q_YES;
+		}
+		return;
+	}
+
+	target->negoFlags = pspi_data->noQas;
+
+	/* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
+	 * support. If available, default QAS to off and allow enabling.
+	 * If not available, default QAS to on, turn off for non-disks.
+	 */
+
+	/* Set flags based on Inquiry data
+	 */
+	if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
+		version = target->inq_data[2] & 0x07;
+		if (version < 2) {
+			width = 0;
+			factor = MPT_ULTRA2;
+			offset = pspi_data->maxSyncOffset;
+		} else {
+			if (target->inq_data[7] & 0x20) {
+				width = 1;
+			}
+
+			if (target->inq_data[7] & 0x10) {
+				/* bits 2 & 3 show DT support
+				 */
+				if ((byte56 & 0x04) == 0)
+					factor = MPT_ULTRA2;
+				else if ((byte56 & 0x03) == 0)
+					factor = MPT_ULTRA160;
+				else
+					factor = MPT_ULTRA320;
+				offset = pspi_data->maxSyncOffset;
+
+				/* If RAID, never disable QAS
+				 * else if non RAID, do not disable
+				 *   QAS if bit 1 is set
+				 * bit 1 QAS support, non-raid only
+				 * bit 0 IU support
+				 */
+				if ((target->raidVolume == 1) || ((byte56 & 0x02) != 0))
+					noQas = 0;
+			} else {
+				factor = MPT_ASYNC;
+				offset = 0;
+			}
+		}
+
+		if (target->inq_data[7] & 0x02) {
+			canQ = 1;
+		}
+
+		/* Update tflags based on NVRAM settings. (SCSI only)
+		 */
+		if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
+			nvram = pspi_data->nvram[id];
+			nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
+
+			if (width)
+				width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
+
+			if (offset > 0) {
+				/* Ensure factor is set to the
+				 * maximum of: adapter, nvram, inquiry
+				 */
+				if (nfactor) {
+					if (nfactor < pspi_data->minSyncFactor )
+						nfactor = pspi_data->minSyncFactor;
+
+					factor = MAX (factor, nfactor);
+					if (factor == MPT_ASYNC)
+						offset = 0;
+				} else {
+					offset = 0;
+					factor = MPT_ASYNC;
+				}
+			} else {
+				factor = MPT_ASYNC;
+			}
+		}
+
+		/* Make sure data is consistent
+		 */
+		if ((!width) && (factor < MPT_ULTRA2)) {
+			factor = MPT_ULTRA2;
+		}
+
+		/* Save the data to the target structure.
+		 */
+		target->minSyncFactor = factor;
+		target->maxOffset = offset;
+		target->maxWidth = width;
+		if (canQ) {
+			target->tflags |= MPT_TARGET_FLAGS_Q_YES;
+		}
+
+		target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
+
+		/* Disable unused features.
+		 */
+		if (!width)
+			target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
+
+		if (!offset)
+			target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
+
+		/* GEM, processor WORKAROUND
+		 */
+		if (((target->inq_data[0] & 0x1F) == 0x03)
+			|| ((target->inq_data[0] & 0x1F) > 0x08)) {
+			target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
+			pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
+		} else {
+			if (noQas && (pspi_data->noQas == 0)) {
+				pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
+				target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
+
+				/* Disable QAS in a mixed configuration case
+		 		*/
+
+//				ddvtprintk((KERN_INFO "Disabling QAS!\n"));
+				for (ii = 0; ii < id; ii++) {
+					if ( (vdev = hd->Targets[ii]) ) {
+						vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
+					}
+				}
+			}
+		}
+	}
+
+	return;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
  * Else set the NEED_DV flag after Read Capacity Issued (disks)
  * or Mode Sense (cdroms).
@@ -4581,7 +4585,7 @@
 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
 {
 	u8 cmd;
-	
+
 	if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
 		return;
 
@@ -4609,16 +4613,14 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- * If no Target (old) or Target unconfigured (new) and bus reset on 1st I/O,
- * set the flag to prevent any future negotiations to this device.
+ * If no Target, bus reset on 1st I/O. Set the flag to
+ * prevent any future negotiations to this device.
  */
 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
 {
-	if (hd->Targets) {
-		VirtDevice *vdev = hd->Targets[target_id];
-		if ((vdev == NULL) || !(vdev->tflags & MPT_TARGET_FLAGS_CONFIGURED))
-			hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
-	}
+
+	if ((hd->Targets) && (hd->Targets[target_id] == NULL))
+		hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
 
 	return;
 }
@@ -4691,9 +4693,9 @@
 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
 {
 	MPT_ADAPTER		*ioc = hd->ioc;
-	Config_t		*pReq = NULL;
-	SCSIDevicePage1_t	*pData = NULL;
-	VirtDevice		*pTarget = NULL;
+	Config_t		*pReq;
+	SCSIDevicePage1_t	*pData;
+	VirtDevice		*pTarget;
 	MPT_FRAME_HDR		*mf;
 	dma_addr_t		 dataDma;
 	u16			 req_idx;
@@ -4784,13 +4786,11 @@
 		/* If id is not a raid volume, get the updated
 		 * transmission settings from the target structure.
 		 */
-		if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume
-				&& (pTarget->tflags & MPT_TARGET_FLAGS_CONFIGURED)) {
+		if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
 			width = pTarget->maxWidth;
 			factor = pTarget->minSyncFactor;
 			offset = pTarget->maxOffset;
 			negoFlags = pTarget->negoFlags;
-			pTarget = NULL;
 		}
 
 		if (flags & MPT_SCSICFG_BLK_NEGO)
@@ -4832,9 +4832,8 @@
 		pReq->Reserved = 0;
 		pReq->ChainOffset = 0;
 		pReq->Function = MPI_FUNCTION_CONFIG;
-		pReq->Reserved1[0] = 0;
-		pReq->Reserved1[1] = 0;
-		pReq->Reserved1[2] = 0;
+		pReq->ExtPageLength = 0;
+		pReq->ExtPageType = 0;
 		pReq->MsgFlags = 0;
 		for (ii=0; ii < 8; ii++) {
 			pReq->Reserved2[ii] = 0;
@@ -4861,18 +4860,97 @@
 		pData->Reserved = 0;
 		pData->Configuration = cpu_to_le32(configuration);
 
-		dsprintk((MYIOC_s_INFO_FMT
+		dprintk((MYIOC_s_INFO_FMT
 			"write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
 				ioc->name, id, (id | (bus<<8)),
 				requested, configuration));
 
-		mptscsih_put_msgframe(ScsiDoneCtx, ioc->id, mf);
+		mpt_put_msg_frame(ScsiDoneCtx, ioc->id, mf);
 	}
 
 	return 0;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*	mptscsih_writeIOCPage4  - write IOC Page 4
+ *	@hd: Pointer to a SCSI Host Structure
+ *	@target_id: write IOC Page4 for this ID & Bus
+ *
+ *	Return: -EAGAIN if unable to obtain a Message Frame
+ *		or 0 if success.
+ *
+ *	Remark: We do not wait for a return, write pages sequentially.
+ */
+static int
+mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
+{
+	MPT_ADAPTER		*ioc = hd->ioc;
+	Config_t		*pReq;
+	IOCPage4_t		*IOCPage4Ptr;
+	MPT_FRAME_HDR		*mf;
+	dma_addr_t		 dataDma;
+	u16			 req_idx;
+	u32			 frameOffset;
+	u32			 flagsLength;
+	int			 ii;
+
+	/* Get a MF for this command.
+	 */
+	if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc->id)) == NULL) {
+		dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
+					ioc->name));
+		return -EAGAIN;
+	}
+
+	ddvprintk((MYIOC_s_INFO_FMT "writeIOCPage4 (mf=%p, id=%d)\n",
+		ioc->name, mf, target_id));
+
+	/* Set the request and the data pointers.
+	 * Place data at end of MF.
+	 */
+	pReq = (Config_t *)mf;
+
+	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
+	frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
+
+	/* Complete the request frame (same for all requests).
+	 */
+	pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+	pReq->Reserved = 0;
+	pReq->ChainOffset = 0;
+	pReq->Function = MPI_FUNCTION_CONFIG;
+	pReq->ExtPageLength = 0;
+	pReq->ExtPageType = 0;
+	pReq->MsgFlags = 0;
+	for (ii=0; ii < 8; ii++) {
+		pReq->Reserved2[ii] = 0;
+	}
+
+       	IOCPage4Ptr = ioc->spi_data.pIocPg4;
+       	dataDma = ioc->spi_data.IocPg4_dma;
+       	ii = IOCPage4Ptr->ActiveSEP++;
+       	IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
+       	IOCPage4Ptr->SEP[ii].SEPBus = bus;
+       	pReq->Header = IOCPage4Ptr->Header;
+	pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
+
+	/* Add a SGE to the config request.
+	 */
+	flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
+		(IOCPage4Ptr->Header.PageLength + ii) * 4;
+
+	mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
+
+	dsprintk((MYIOC_s_INFO_FMT
+		"writeIOCPage4: pgaddr 0x%x\n",
+			ioc->name, (target_id | (bus<<8))));
+
+	mpt_put_msg_frame(ScsiDoneCtx, ioc->id, mf);
+
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*	mptscsih_taskmgmt_timeout - Call back for timeout on a
  *	task management request.
  *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
@@ -4982,8 +5060,6 @@
 	ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
 			hd->ioc->name, mf, mr, req_idx));
 
-	atomic_dec(&queue_depth);
-
 	hd->pLocal = &hd->localReply;
 	hd->pLocal->scsiStatus = 0;
 
@@ -5042,7 +5118,7 @@
 				u8		*sense_data;
 				int		 sz;
 
-				/* save sense data in global & target structure
+				/* save sense data in global structure
 				 */
 				completionCode = MPT_SCANDV_SENSE;
 				hd->pLocal->scsiStatus = pReply->SCSIStatus;
@@ -5215,7 +5291,7 @@
 	hd->cmdPtr = mf;
 
 	add_timer(&hd->timer);
-	mptscsih_put_msgframe(ScsiScanDvCtx, hd->ioc->id, mf);
+	mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc->id, mf);
 	wait_event(scandv_waitq, scandv_wait_done);
 
 	if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
@@ -5452,7 +5528,7 @@
 	hd->cmdPtr = mf;
 
 	add_timer(&hd->timer);
-	mptscsih_put_msgframe(ScsiScanDvCtx, hd->ioc->id, mf);
+	mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc->id, mf);
 	wait_event(scandv_waitq, scandv_wait_done);
 
 	if (hd->pLocal) {
@@ -5490,7 +5566,7 @@
 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
 {
 	MPT_ADAPTER		*ioc= hd->ioc;
-	VirtDevice		*pTarget = NULL;
+	VirtDevice		*pTarget;
 	SCSIDevicePage1_t	*pcfg1Data = NULL;
 	INTERNAL_CMD		 iocmd;
 	CONFIGPARMS		 cfg;
@@ -5498,7 +5574,8 @@
 	ConfigPageHeader_t	 header1;
 	int			 bus = 0;
 	int			 id = 0;
-	int			 lun = 0;
+	int			 lun;
+	int			 indexed_lun, lun_index;
 	int			 hostId = ioc->pfacts[portnum].PortSCSIID;
 	int			 max_id;
 	int			 requested, configuration, data;
@@ -5593,7 +5670,9 @@
 			for (lun=0; lun <= MPT_LAST_LUN; lun++) {
 				/* If LUN present, issue the command
 				 */
-				if (pTarget->luns & (1<<lun)) {
+				lun_index = (lun >> 5);  /* 32 luns per lun_index */
+				indexed_lun = (lun % 32);
+				if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
 					iocmd.lun = lun;
 					(void) mptscsih_do_cmd(hd, &iocmd);
 				}
@@ -5634,8 +5713,8 @@
 static void
 mptscsih_domainValidation(void *arg)
 {
-	MPT_SCSI_HOST		*hd = NULL;
-	MPT_ADAPTER		*ioc = NULL;
+	MPT_SCSI_HOST		*hd;
+	MPT_ADAPTER		*ioc;
 	unsigned long		 flags;
 	int 			 id, maxid, dvStatus, did;
 	int			 ii, isPhysDisk;
@@ -5792,7 +5871,7 @@
  */
 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
 {
-	VirtDevice *pTarget = NULL;
+	VirtDevice *pTarget;
 	int ii;
 
 	if (hd->Targets == NULL)
@@ -5843,15 +5922,15 @@
  *	Return: None.
  */
 static int
-mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
+mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
 {
 	MPT_ADAPTER		*ioc = hd->ioc;
-	VirtDevice		*pTarget = NULL;
-	SCSIDevicePage1_t	*pcfg1Data = NULL;
-	SCSIDevicePage0_t	*pcfg0Data = NULL;
-	u8			*pbuf1 = NULL;
-	u8			*pbuf2 = NULL;
-	u8			*pDvBuf = NULL;
+	VirtDevice		*pTarget;
+	SCSIDevicePage1_t	*pcfg1Data;
+	SCSIDevicePage0_t	*pcfg0Data;
+	u8			*pbuf1;
+	u8			*pbuf2;
+	u8			*pDvBuf;
 	dma_addr_t		 dvbuf_dma = -1;
 	dma_addr_t		 buf1_dma = -1;
 	dma_addr_t		 buf2_dma = -1;
@@ -5871,6 +5950,7 @@
 	int			 patt;
 	int			 repeat;
 	int			 retcode = 0;
+	int			 nfactor =  MPT_ULTRA320;
 	char			 firstPass = 1;
 	char			 doFallback = 0;
 	char			 readPage0;
@@ -5883,14 +5963,17 @@
 	if (ioc->spi_data.sdp0length == 0)
 		return 0;
 
-	if (id == ioc->pfacts[portnum].PortSCSIID)
+	/* If multiple buses are used, require that the initiator
+	 * id be the same on all buses.
+	 */
+	if (id == ioc->pfacts[0].PortSCSIID)
 		return 0;
 
 	lun = 0;
-	bus = 0;
+	bus = (u8) bus_number;
 	ddvtprintk((MYIOC_s_NOTE_FMT
-			"DV started: numIOs %d bus=%d, id %d dv @ %p\n",
-			ioc->name, atomic_read(&queue_depth), bus, id, &dv));
+			"DV started: bus=%d, id %d dv @ %p\n",
+			ioc->name, bus, id, &dv));
 
 	/* Prep DV structure
 	 */
@@ -5916,11 +5999,11 @@
 	iocmd.rsvd = iocmd.rsvd2 = 0;
 
 	pTarget = hd->Targets[id];
-	if (pTarget && (pTarget->tflags & MPT_TARGET_FLAGS_CONFIGURED)) {
+	if (pTarget && (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
 		/* Another GEM workaround. Check peripheral device type,
 		 * if PROCESSOR, quit DV.
 		 */
-		if ((pTarget->type == 0x03) || (pTarget->type > 0x08)) {
+		if (((pTarget->inq_data[0] & 0x1F) == 0x03) || ((pTarget->inq_data[0] & 0x1F) > 0x08)) {
 			pTarget->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
 			return 0;
 		}
@@ -5992,24 +6075,34 @@
 
 	/* Skip this ID? Set cfg.hdr to force config page write
 	 */
-	if ((ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID) &&
-			(!(ioc->spi_data.nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE))) {
+	{
+		ScsiCfgData *pspi_data = &hd->ioc->spi_data;
+		if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
+			/* Set the factor from nvram */
+			nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
+			if (nfactor < pspi_data->minSyncFactor )
+				nfactor = pspi_data->minSyncFactor;
 
-		ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
-			ioc->name, bus, id, lun));
+			if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
+				(pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
 
-		dv.cmd = MPT_SET_MAX;
-		mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
-		cfg.hdr = &header1;
-		/* Double writes to SDP1 can cause problems,
-		 * skip save of the final negotiated settings to
-		 * SCSI device page 1.
-		 */
-		cfg.physAddr = cfg1_dma_addr;
-		cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
-		cfg.dir = 1;
-		mpt_config(hd->ioc, &cfg);
-		goto target_done;
+				ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
+					ioc->name, bus, id, lun));
+
+				dv.cmd = MPT_SET_MAX;
+				mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
+				cfg.hdr = &header1;
+
+				/* Save the final negotiated settings to
+				 * SCSI device page 1.
+				 */
+				cfg.physAddr = cfg1_dma_addr;
+				cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+				cfg.dir = 1;
+				mpt_config(hd->ioc, &cfg);
+				goto target_done;
+			}
+		}
 	}
 
 	/* Finish iocmd inititialization - hidden or visible disk? */
@@ -6059,7 +6152,7 @@
 	sz = SCSI_STD_INQUIRY_BYTES;
 	rc = MPT_SCANDV_GOOD;
 	while (1) {
-		ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test.\n", ioc->name));
+		ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
 		retcode = 0;
 		dv.cmd = MPT_SET_MIN;
 		mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
@@ -6131,6 +6224,14 @@
 			}
 		}
 
+		/* Reset the size for disks
+		 */
+		inq0 = (*pbuf1) & 0x1F;
+		if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
+			sz = 0x40;
+			iocmd.size = sz;
+		}
+
 		/* Another GEM workaround. Check peripheral device type,
 		 * if PROCESSOR, quit DV.
 		 */
@@ -6140,6 +6241,28 @@
 		if (mptscsih_do_cmd(hd, &iocmd) < 0)
 			goto target_done;
 
+		if (sz == 0x40) {
+			if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
+				&& (pTarget->minSyncFactor > 0x09)) {
+				if ((pbuf1[56] & 0x04) == 0)
+					;
+				else if ((pbuf1[56] & 0x01) == 1) {
+					pTarget->minSyncFactor =
+					    nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
+				} else {
+					pTarget->minSyncFactor =
+					    nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
+				}
+
+				dv.max.factor = pTarget->minSyncFactor;
+
+				if ((pbuf1[56] & 0x02) == 0) {
+					pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
+					hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
+				}
+			}
+		}
+
 		if (doFallback)
 			dv.cmd = MPT_FALLBACK;
 		else
@@ -6223,7 +6346,7 @@
 			firstPass = 0;
 		}
 	}
-	ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test completed OK.\n", ioc->name));
+	ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
 	inq0 = (*pbuf1) & 0x1F;
 
 	/* Continue only for disks
@@ -6231,6 +6354,9 @@
 	if (inq0 != 0)
 		goto target_done;
 
+	if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
+		goto target_done;
+
 	/* Start the Enhanced Test.
 	 * 0) issue TUR to clear out check conditions
 	 * 1) read capacity of echo (regular) buffer
@@ -6671,8 +6797,8 @@
 	if (pDvBuf)
 		pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
 
-	ddvtprintk((MYIOC_s_INFO_FMT "DV Done. IOs outstanding = %d\n",
-			ioc->name, atomic_read(&queue_depth)));
+	ddvtprintk((MYIOC_s_INFO_FMT "DV Done.\n",
+			ioc->name));
 
 	return retcode;
 }
@@ -6687,9 +6813,9 @@
 static void
 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
 {
-	VirtDevice		*pTarget = NULL;
-	SCSIDevicePage0_t	*pPage0 = NULL;
-	SCSIDevicePage1_t	*pPage1 = NULL;
+	VirtDevice		*pTarget;
+	SCSIDevicePage0_t	*pPage0;
+	SCSIDevicePage1_t	*pPage1;
 	int			val = 0, data, configuration;
 	u8			width = 0;
 	u8			offset = 0;
@@ -6841,7 +6967,6 @@
 				factor = MPT_ULTRA;
 				width = MPT_WIDE;
 			} else if ((factor == MPT_ULTRA) && width) {
-				factor = MPT_ULTRA;
 				width = MPT_NARROW;
 			} else if (factor < MPT_FAST) {
 				factor = MPT_FAST;
@@ -7072,9 +7197,9 @@
 /* Commandline Parsing routines and defines.
  *
  * insmod format:
- *	insmod mptscsih mptscsih="width:1 dv:n factor:0x09"
+ *	insmod mptscsih mptscsih="width:1 dv:n factor:0x09 saf-te:1"
  *  boot format:
- *	mptscsih=width:1,dv:n,factor:0x8
+ *	mptscsih=width:1,dv:n,factor:0x8,saf-te:1
  *
  */
 #ifdef MODULE
@@ -7087,11 +7212,13 @@
 	"dv:"
 	"width:"
 	"factor:"
-       ;	/* DONNOT REMOVE THIS ';' */
+	"saf-te:"
+       ;	/* DO NOT REMOVE THIS ';' */
 
 #define OPT_DV			1
 #define OPT_MAX_WIDTH		2
 #define OPT_MIN_SYNC_FACTOR	3
+#define OPT_SAF_TE		4
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static int
@@ -7146,6 +7273,10 @@
 
 		case OPT_MIN_SYNC_FACTOR:
 			driver_setup.min_sync_fac = val;
+			break;
+
+		case OPT_SAF_TE:
+			driver_setup.saf_te = val;
 			break;
 
 		default:
diff -Nru a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
--- a/drivers/message/fusion/mptscsih.h	Wed Mar 10 21:09:43 2004
+++ b/drivers/message/fusion/mptscsih.h	Wed Mar 10 21:09:43 2004
@@ -15,7 +15,7 @@
  *
  *      (see also mptbase.c)
  *
- *  Copyright (c) 1999-2003 LSI Logic Corporation
+ *  Copyright (c) 1999-2004 LSI Logic Corporation
  *  Originally By: Steven J. Ralston
  *  (mailto:netscape.net)
  *  (mailto:mpt_linux_developer@lsil.com)
@@ -70,11 +70,7 @@
  *	Try to keep these at 2^N-1
  */
 #define MPT_FC_CAN_QUEUE	127
-#if defined MPT_SCSI_USE_NEW_EH
-	#define MPT_SCSI_CAN_QUEUE	127
-#else
-	#define MPT_SCSI_CAN_QUEUE	63
-#endif
+#define MPT_SCSI_CAN_QUEUE	127
 
 #define MPT_SCSI_CMD_PER_DEV_HIGH	31
 #define MPT_SCSI_CMD_PER_DEV_LOW	7
@@ -98,7 +94,7 @@
 #define MPT_SCSI_SG_DEPTH	40
 #endif
 
-/* To disable domain validation, comment the
+/* To disable domain validation, uncomment the
  * following line. No effect for FC devices.
  * For SCSI devices, driver will negotiate to
  * NVRAM settings (if available) or to maximum adapter
@@ -114,12 +110,14 @@
 #define MPTSCSIH_DOMAIN_VALIDATION      1
 #define MPTSCSIH_MAX_WIDTH              1
 #define MPTSCSIH_MIN_SYNC               0x08
+#define MPTSCSIH_SAF_TE                 0
 
 struct mptscsih_driver_setup
 {
         u8      dv;
         u8      max_width;
         u8      min_sync_fac;
+        u8      saf_te;
 };
 
 
@@ -128,6 +126,7 @@
         MPTSCSIH_DOMAIN_VALIDATION,             \
         MPTSCSIH_MAX_WIDTH,                     \
         MPTSCSIH_MIN_SYNC,                      \
+        MPTSCSIH_SAF_TE,                        \
 }
 
 
diff -Nru a/drivers/message/fusion/scsi3.h b/drivers/message/fusion/scsi3.h
--- a/drivers/message/fusion/scsi3.h	Wed Mar 10 21:09:42 2004
+++ b/drivers/message/fusion/scsi3.h	Wed Mar 10 21:09:42 2004
@@ -4,7 +4,7 @@
  *      (Ultimately) SCSI-3 definitions; for now, inheriting
  *      SCSI-2 definitions.
  *
- *  Copyright (c) 1996-2003 Steven J. Ralston
+ *  Copyright (c) 1996-2004 Steven J. Ralston
  *  Written By: Steven J. Ralston (19960517)
  *  (mailto:sjralston1@netscape.net)
  *  (mailto:mpt_linux_developer@lsil.com)
diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
--- a/drivers/scsi/53c700.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/53c700.c	Wed Mar 10 21:09:42 2004
@@ -137,6 +137,9 @@
 #include "scsi.h"
 #include "hosts.h"
 
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_spi.h>
+
 #include "53c700.h"
 
 /* NOTE: For 64 bit drivers there are points in the code where we use
@@ -173,6 +176,8 @@
 
 STATIC struct device_attribute *NCR_700_dev_attrs[];
 
+STATIC struct scsi_transport_template *NCR_700_transport_template = NULL;
+
 static char *NCR_700_phase[] = {
 	"",
 	"after selection",
@@ -236,6 +241,53 @@
 	NCR_700_MAX_OFFSET
 };
 
+/* This translates the SDTR message offset and period to a value
+ * which can be loaded into the SXFER_REG.
+ *
+ * NOTE: According to SCSI-2, the true transfer period (in ns) is
+ *       actually four times this period value */
+static inline __u8
+NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata,
+			       __u8 offset, __u8 period)
+{
+	int XFERP;
+
+	__u8 min_xferp = (hostdata->chip710
+			  ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP);
+	__u8 max_offset = (hostdata->chip710
+			   ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET);
+
+	if(offset == 0)
+		return 0;
+
+	if(period < hostdata->min_period) {
+		printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_SDTR_msg[3]*4);
+		period = hostdata->min_period;
+	}
+	XFERP = (period*4 * hostdata->sync_clock)/1000 - 4;
+	if(offset > max_offset) {
+		printk(KERN_WARNING "53c700: Offset %d exceeds chip maximum, setting to %d\n",
+		       offset, max_offset);
+		offset = max_offset;
+	}
+	if(XFERP < min_xferp) {
+		printk(KERN_WARNING "53c700: XFERP %d is less than minium, setting to %d\n",
+		       XFERP,  min_xferp);
+		XFERP =  min_xferp;
+	}
+	return (offset & 0x0f) | (XFERP & 0x07)<<4;
+}
+
+static inline __u8
+NCR_700_get_SXFER(Scsi_Device *SDp)
+{
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
+
+	return NCR_700_offset_period_to_sxfer(hostdata, spi_offset(SDp),
+					      spi_period(SDp));
+}
+
 struct Scsi_Host *
 NCR_700_detect(Scsi_Host_Template *tpnt,
 	       struct NCR_700_Host_Parameters *hostdata)
@@ -326,6 +378,8 @@
 	hostdata->cmd = NULL;
 	host->max_id = 7;
 	host->max_lun = NCR_700_MAX_LUNS;
+	BUG_ON(NCR_700_transport_template == NULL);
+	host->transportt = NCR_700_transport_template;
 	host->unique_id = hostdata->base;
 	host->base = hostdata->base;
 	hostdata->eh_complete = NULL;
@@ -520,40 +574,6 @@
 	hostdata->cmd = NULL;
 }
 
-/* This translates the SDTR message offset and period to a value
- * which can be loaded into the SXFER_REG.
- *
- * NOTE: According to SCSI-2, the true transfer period (in ns) is
- *       actually four times this period value */
-STATIC inline __u8
-NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata,
-			       __u8 offset, __u8 period)
-{
-	int XFERP;
-	__u8 min_xferp = (hostdata->chip710
-			  ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP);
-	__u8 max_offset = (hostdata->chip710
-			   ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET);
-	/* NOTE: NCR_700_SDTR_msg[3] contains our offer of the minimum
-	 * period.  It is set in NCR_700_chip_setup() */
-	if(period < NCR_700_SDTR_msg[3]) {
-		printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_SDTR_msg[3]*4);
-		period = NCR_700_SDTR_msg[3];
-	}
-	XFERP = (period*4 * hostdata->sync_clock)/1000 - 4;
-	if(offset > max_offset) {
-		printk(KERN_WARNING "53c700: Offset %d exceeds chip maximum, setting to %d\n",
-		       offset, max_offset);
-		offset = max_offset;
-	}
-	if(XFERP < min_xferp) {
-		printk(KERN_WARNING "53c700: XFERP %d is less than minium, setting to %d\n",
-		       XFERP,  min_xferp);
-		XFERP =  min_xferp;
-	}
-	return (offset & 0x0f) | (XFERP & 0x07)<<4;
-}
-
 STATIC inline void
 NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, Scsi_Cmnd *SCp,
 	      struct NCR_700_command_slot *slot)
@@ -724,11 +744,9 @@
 	 * exact details of this calculation which is based on a
 	 * setting of the SXFER register */
 	min_period = 1000*(4+min_xferp)/(4*hostdata->sync_clock);
-	if(min_period > NCR_700_MIN_PERIOD) {
-		NCR_700_SDTR_msg[3] = min_period;
-	}
-	if(hostdata->chip710)
-		NCR_700_SDTR_msg[4] = NCR_710_MAX_OFFSET;
+	hostdata->min_period = NCR_700_MIN_PERIOD;
+	if(min_period > NCR_700_MIN_PERIOD)
+		hostdata->min_period = min_period;
 }
 
 STATIC void
@@ -777,20 +795,25 @@
 		if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {
 			__u8 period = hostdata->msgin[3];
 			__u8 offset = hostdata->msgin[4];
-			__u8 sxfer;
 
-			if(offset != 0 && period != 0)
-				sxfer = NCR_700_offset_period_to_sxfer(hostdata, offset, period);
-			else 
-				sxfer = 0;
+			if(offset == 0 || period == 0) {
+				offset = 0;
+				period = 0;
+			}
 			
-			if(sxfer != NCR_700_get_SXFER(SCp->device)) {
-				printk(KERN_INFO "scsi%d: (%d:%d) Synchronous at offset %d, period %dns\n",
-				       host->host_no, pun, lun,
-				       offset, period*4);
-				
-				NCR_700_set_SXFER(SCp->device, sxfer);
+			if(NCR_700_is_flag_set(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION)) {
+				if(spi_offset(SCp->device) != 0)
+					printk(KERN_INFO "scsi%d: (%d:%d) Synchronous at offset %d, period %dns\n",
+					       host->host_no, pun, lun,
+					       offset, period*4);
+				else
+					printk(KERN_INFO "scsi%d: (%d:%d) Asynchronous\n",
+					       host->host_no, pun, lun);
+				NCR_700_clear_flag(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION);
 			}
+				
+			spi_offset(SCp->device) = offset;
+			spi_period(SCp->device) = period;
 			
 
 			NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
@@ -870,7 +893,7 @@
 	case A_REJECT_MSG:
 		if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {
 			/* Rejected our sync negotiation attempt */
-			NCR_700_set_SXFER(SCp->device, 0);
+			spi_period(SCp->device) = spi_offset(SCp->device) = 0;
 			NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
 			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
 		} else if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) {
@@ -1396,6 +1419,8 @@
 	   NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC)) {
 		memcpy(&hostdata->msgout[count], NCR_700_SDTR_msg,
 		       sizeof(NCR_700_SDTR_msg));
+		hostdata->msgout[count+3] = spi_period(SCp->device);
+		hostdata->msgout[count+4] = spi_offset(SCp->device);
 		count += sizeof(NCR_700_SDTR_msg);
 		NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
 	}
@@ -1967,9 +1992,51 @@
 	return SUCCESS;
 }
 
+STATIC void
+NCR_700_set_period(struct scsi_device *SDp, int period)
+{
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
+	
+	if(!hostdata->fast || period < hostdata->min_period)
+		return;
+
+	spi_period(SDp) = period;
+	NCR_700_clear_flag(SDp, NCR_700_DEV_NEGOTIATED_SYNC);
+	NCR_700_clear_flag(SDp, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
+	NCR_700_set_flag(SDp, NCR_700_DEV_PRINT_SYNC_NEGOTIATION);
+}
+
+STATIC void
+NCR_700_set_offset(struct scsi_device *SDp, int offset)
+{
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
+	
+	if(!hostdata->fast ||
+	   offset > (hostdata->chip710
+		     ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET))
+		return;
+
+	/* if we're currently async, make sure the period is reasonable */
+	if(spi_offset(SDp) == 0 && (spi_period(SDp) < hostdata->min_period ||
+				    spi_period(SDp) > 0xff))
+		spi_period(SDp) = hostdata->min_period;
+
+	spi_offset(SDp) = offset;
+	NCR_700_clear_flag(SDp, NCR_700_DEV_NEGOTIATED_SYNC);
+	NCR_700_clear_flag(SDp, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
+	NCR_700_set_flag(SDp, NCR_700_DEV_PRINT_SYNC_NEGOTIATION);
+}
+
+
+
 STATIC int
 NCR_700_slave_configure(Scsi_Device *SDp)
 {
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
+
 	/* to do here: allocate memory; build a queue_full list */
 	if(SDp->tagged_supported) {
 		/* do TCQ stuff here */
@@ -1977,6 +2044,11 @@
 		/* initialise to default depth */
 		scsi_adjust_queue_depth(SDp, 0, SDp->host->cmd_per_lun);
 	}
+	if(hostdata->fast) {
+		NCR_700_set_period(SDp, hostdata->min_period);
+		NCR_700_set_offset(SDp, hostdata->chip710
+				   ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET);
+	}
 	return 0;
 }
 
@@ -2033,3 +2105,25 @@
 EXPORT_SYMBOL(NCR_700_detect);
 EXPORT_SYMBOL(NCR_700_release);
 EXPORT_SYMBOL(NCR_700_intr);
+
+static struct spi_function_template NCR_700_transport_functions =  {
+	.set_period = NCR_700_set_period,
+	.set_offset = NCR_700_set_offset,
+};
+
+static int __init NCR_700_init(void)
+{
+	NCR_700_transport_template = spi_attach_transport(&NCR_700_transport_functions);
+	if(!NCR_700_transport_template)
+		return -ENODEV;
+	return 0;
+}
+
+static void __exit NCR_700_exit(void)
+{
+	spi_release_transport(NCR_700_transport_template);
+}
+
+module_init(NCR_700_init);
+module_exit(NCR_700_exit);
+
diff -Nru a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h
--- a/drivers/scsi/53c700.h	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/53c700.h	Wed Mar 10 21:09:42 2004
@@ -99,19 +99,9 @@
 #define NCR_700_DEV_NEGOTIATED_SYNC	(1<<16)
 #define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION	(1<<17)
 #define NCR_700_DEV_BEGIN_TAG_QUEUEING	(1<<18)
-#define NCR_700_DEV_TAG_STARVATION_WARNED (1<<19)
+#define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19)
 
 static inline void
-NCR_700_set_SXFER(Scsi_Device *SDp, __u8 sxfer)
-{
-	SDp->hostdata = (void *)(((long)SDp->hostdata & 0xffffff00) |
-				(sxfer & 0xff));
-}
-static inline __u8 NCR_700_get_SXFER(Scsi_Device *SDp)
-{
-	return (((unsigned long)SDp->hostdata) & 0xff);
-}
-static inline void
 NCR_700_set_depth(Scsi_Device *SDp, __u8 depth)
 {
 	long l = (long)SDp->hostdata;
@@ -215,6 +205,7 @@
 	__u8	tag_negotiated;
 	__u8	rev;
 	__u8	reselection_id;
+	__u8	min_period;
 
 	/* Free list, singly linked by ITL_forw elements */
 	struct NCR_700_command_slot *free_list;
@@ -438,6 +429,7 @@
 		       #symbol, A_##symbol##_used[i], val)); \
 	} \
 }
+
 
 static inline __u8
 NCR_700_mem_readb(struct Scsi_Host *host, __u32 reg)
diff -Nru a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
--- a/drivers/scsi/BusLogic.c	Wed Mar 10 21:09:43 2004
+++ b/drivers/scsi/BusLogic.c	Wed Mar 10 21:09:43 2004
@@ -140,7 +140,7 @@
   Name, Copyright Notice, and Electronic Mail Address.
 */
 
-static void __init BusLogic_AnnounceDriver(struct BusLogic_HostAdapter *HostAdapter)
+static void BusLogic_AnnounceDriver(struct BusLogic_HostAdapter *HostAdapter)
 {
   BusLogic_Announce("***** BusLogic SCSI Driver Version "
 		    BusLogic_DriverVersion " of "
diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
--- a/drivers/scsi/Kconfig	Wed Mar 10 21:09:43 2004
+++ b/drivers/scsi/Kconfig	Wed Mar 10 21:09:43 2004
@@ -196,6 +196,25 @@
 	  there should be no noticeable performance impact as long as you have
 	  logging turned off.
 
+menu "SCSI Transport Attributes"
+	depends on SCSI
+
+config SCSI_SPI_ATTRS
+	tristate "Parallel SCSI (SPI) Transport Attributes"
+	depends on SCSI
+	help
+	  If you wish to export transport-specific information about
+	  each attached SCSI device to sysfs, say Y.  Otherwise, say N.
+
+config SCSI_FC_ATTRS
+	tristate "FiberChannel Transport Attributes"
+	depends on SCSI
+	help
+	  If you wish to export transport-specific information about
+	  each attached FiberChannel device to sysfs, say Y.
+	  Otherwise, say N.
+
+endmenu
 
 menu "SCSI low-level drivers"
 	depends on SCSI!=n
@@ -845,6 +864,7 @@
 config SCSI_NCR_D700
 	tristate "NCR Dual 700 MCA SCSI support"
 	depends on MCA && SCSI
+	select SCSI_SPI_ATTRS
 	help
 	  This is a driver for the MicroChannel Dual 700 card produced by
 	  NCR and commonly used in 345x/35xx/4100 class machines.  It always
@@ -861,6 +881,7 @@
 config SCSI_LASI700
 	tristate "HP Lasi SCSI support for 53c700/710"
 	depends on GSC && SCSI
+	select SCSI_SPI_ATTRS
 	help
 	  This is a driver for the SCSI controller in the Lasi chip found in
 	  many PA-RISC workstations & servers.  If you do not know whether you
@@ -1212,6 +1233,7 @@
 config SCSI_SIM710
 	tristate "Simple 53c710 SCSI support (Compaq, NCR machines)"
 	depends on (EISA || MCA) && SCSI
+	select SCSI_SPI_ATTRS
 	---help---
 	  This driver for NCR53c710 based SCSI host adapters.
 
diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile
--- a/drivers/scsi/Makefile	Wed Mar 10 21:09:43 2004
+++ b/drivers/scsi/Makefile	Wed Mar 10 21:09:43 2004
@@ -22,6 +22,14 @@
 
 obj-$(CONFIG_SCSI)		+= scsi_mod.o
 
+# --- NOTE ORDERING HERE ---
+# For kernel non-modular link, transport attributes need to
+# be initialised before drivers
+# --------------------------
+obj-$(CONFIG_SCSI_SPI_ATTRS)	+= scsi_transport_spi.o
+obj-$(CONFIG_SCSI_FC_ATTRS) 	+= scsi_transport_fc.o
+
+
 obj-$(CONFIG_SCSI_AMIGA7XX)	+= amiga7xx.o	53c7xx.o
 obj-$(CONFIG_A3000_SCSI)	+= a3000.o	wd33c93.o
 obj-$(CONFIG_A2091_SCSI)	+= a2091.o	wd33c93.o
@@ -41,7 +49,7 @@
 obj-$(CONFIG_SUN3_SCSI)		+= sun3_scsi.o  sun3_scsi_vme.o
 obj-$(CONFIG_MVME16x_SCSI)	+= mvme16x.o	53c7xx.o
 obj-$(CONFIG_BVME6000_SCSI)	+= bvme6000.o	53c7xx.o
-obj-$(CONFIG_SCSI_SIM710)	+= sim710.o	53c700.o
+obj-$(CONFIG_SCSI_SIM710)	+= 53c700.o	sim710.o
 obj-$(CONFIG_SCSI_ADVANSYS)	+= advansys.o
 obj-$(CONFIG_SCSI_PCI2000)	+= pci2000.o
 obj-$(CONFIG_SCSI_PCI2220I)	+= pci2220i.o
@@ -64,7 +72,7 @@
 obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
 obj-$(CONFIG_SCSI_GENERIC_NCR5380_MMIO) += g_NCR5380_mmio.o
 obj-$(CONFIG_SCSI_NCR53C406A)	+= NCR53c406a.o
-obj-$(CONFIG_SCSI_NCR_D700)	+= NCR_D700.o 53c700.o
+obj-$(CONFIG_SCSI_NCR_D700)	+= 53c700.o NCR_D700.o
 obj-$(CONFIG_SCSI_NCR_Q720)	+= NCR_Q720_mod.o
 obj-$(CONFIG_SCSI_SYM53C416)	+= sym53c416.o
 obj-$(CONFIG_SCSI_QLOGIC_FAS)	+= qlogicfas.o
@@ -107,7 +115,7 @@
 obj-$(CONFIG_SCSI_DEBUG)	+= scsi_debug.o
 obj-$(CONFIG_SCSI_FCAL)		+= fcal.o
 obj-$(CONFIG_SCSI_CPQFCTS)	+= cpqfc.o
-obj-$(CONFIG_SCSI_LASI700)	+= lasi700.o 53c700.o
+obj-$(CONFIG_SCSI_LASI700)	+= 53c700.o lasi700.o
 obj-$(CONFIG_SCSI_NSP32)	+= nsp32.o
 obj-$(CONFIG_SCSI_SATA_SVW)	+= libata.o sata_svw.o
 obj-$(CONFIG_SCSI_ATA_PIIX)	+= libata.o ata_piix.o
@@ -130,7 +138,7 @@
 scsi_mod-$(CONFIG_SYSCTL)	+= scsi_sysctl.o
 scsi_mod-$(CONFIG_SCSI_PROC_FS)	+= scsi_proc.o
 scsi_mod-$(CONFIG_X86_PC9800)	+= scsi_pc98.o
-			
+
 sd_mod-objs	:= sd.o
 sr_mod-objs	:= sr.o sr_ioctl.o sr_vendor.o
 initio-objs	:= ini9100u.o i91uscsi.o
diff -Nru a/drivers/scsi/aic7xxx/Kconfig.aic79xx b/drivers/scsi/aic7xxx/Kconfig.aic79xx
--- a/drivers/scsi/aic7xxx/Kconfig.aic79xx	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/aic7xxx/Kconfig.aic79xx	Wed Mar 10 21:09:42 2004
@@ -4,7 +4,7 @@
 #
 config SCSI_AIC79XX
 	tristate "Adaptec AIC79xx U320 support"
-	depends on PCI
+	depends on PCI && SCSI
 	help
 	This driver supports all of Adaptec's Ultra 320 PCI-X
 	based SCSI controllers.
diff -Nru a/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
--- a/drivers/scsi/aic7xxx/Kconfig.aic7xxx	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx	Wed Mar 10 21:09:42 2004
@@ -4,7 +4,7 @@
 #
 config SCSI_AIC7XXX
 	tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)"
-	depends on PCI || EISA
+	depends on (PCI || EISA) && SCSI
 	---help---
 	This driver supports all of Adaptec's Fast through Ultra 160 PCI
 	based SCSI controllers as well as the aic7770 based EISA and VLB
diff -Nru a/drivers/scsi/constants.c b/drivers/scsi/constants.c
--- a/drivers/scsi/constants.c	Wed Mar 10 21:09:43 2004
+++ b/drivers/scsi/constants.c	Wed Mar 10 21:09:43 2004
@@ -1135,7 +1135,7 @@
 static const char * hostbyte_table[]={
 "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", 
 "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",
-"DID_PASSTHROUGH", "DID_SOFT_ERROR", NULL};
+"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", NULL};
 
 void print_hostbyte(int scsiresult)
 {   static int maxcode=0;
diff -Nru a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
--- a/drivers/scsi/dc395x.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/dc395x.c	Wed Mar 10 21:09:42 2004
@@ -62,6 +62,10 @@
 #include <linux/pci.h>
 #include <linux/list.h>
 
+#define DC395X_NAME	"dc395x"
+#define DC395X_BANNER	"Tekram DC395(U/UW/F), DC315(U) - ASIC TRM-S1040"
+#define DC395X_VERSION	"v2.05, 2004/03/08"
+
 /*---------------------------------------------------------------------------
                                   Features
  ---------------------------------------------------------------------------*/
@@ -82,22 +86,16 @@
 #define DBG_KG		0x0001
 #define DBG_0		0x0002
 #define DBG_1		0x0004
-#define DBG_DCB		0x0008
-#define DBG_PARSE	0x0010		/* debug command line parsing */
-#define DBG_SGPARANOIA	0x0020
+#define DBG_SG		0x0020
 #define DBG_FIFO	0x0040
 #define DBG_PIO		0x0080
-#define DBG_RECURSION	0x0100		/* check for excessive recursion */
-#define DBG_MALLOC	0x0200		/* report on memory allocations */
-#define DBG_TRACE	0x0400
-#define DBG_TRACEALL	0x0800
 
 
 /*
  * Set set of things to output debugging for.
  * Undefine to remove all debugging
  */
-/*#define DEBUG_MASK (DBG_0|DBG_1|DBG_DCB|DBG_PARSE|DBG_SGPARANOIA|DBG_FIFO|DBG_PIO|DBG_TRACE|DBG_TRACEALL)*/
+/*#define DEBUG_MASK (DBG_0|DBG_1|DBG_SG|DBG_FIFO|DBG_PIO)*/
 /*#define  DEBUG_MASK	DBG_0*/
 
 
@@ -138,72 +136,6 @@
 #endif
 
 
-/*
- * The recursion debugging just counts entries into the driver and
- * prints out a messge if it exceeds a certain limit. This variable
- * hold the count.
- */
-#if debug_enabled(DBG_RECURSION)
-static int dbg_in_driver = 0;
-#endif
-
-
-/*
- * Memory allocation debugging
- * Just reports when memory is allocated and/or released.
- */
-#if debug_enabled(DBG_MALLOC)
-inline void *dc395x_kmalloc(size_t sz, int fl)
-{
-	void *ptr = kmalloc(sz, fl);
-	dprintkl(KERN_DEBUG, "Alloc %i bytes @ %p w/ fl %08x\n", sz, ptr, fl);
-	return ptr;
-}
-inline void dc395x_kfree(const void *adr)
-{
-	dprintkl(KERN_DEBUG, "Free mem @ %p\n", adr);
-	kfree(adr);
-}
-#else
-#define dc395x_kmalloc(sz, fl)	kmalloc(sz, fl)
-#define dc395x_kfree(adr) kfree(adr)
-#endif
-
-
-/*
- * Debug/trace stuff
- */
-#if debug_enabled(DBG_TRACEALL)
-# define TRACEOUTALL(x...) printk ( x)
-#else
-# define TRACEOUTALL(x...) do {} while (0)
-#endif
-
-#if debug_enabled(DBG_TRACE|DBG_TRACEALL)
-# define DEBUGTRACEBUFSZ 512
-static char tracebuf[64];
-static char traceoverflow[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-# define TRACEPRINTF(x...) \
-	do { \
-		int ln = sprintf(tracebuf, x); \
-		if (srb->debugpos + ln >= DEBUGTRACEBUFSZ) { \
-			srb->debugtrace[srb->debugpos] = 0; \
-			srb->debugpos = DEBUGTRACEBUFSZ/5; \
-			srb->debugtrace[srb->debugpos++] = '>'; \
-		} \
-		sprintf(srb->debugtrace + srb->debugpos, "%s", tracebuf); \
-		srb->debugpos += ln - 1; \
-	} while (0)
-# define TRACEOUT(x...) printk (x)
-#else
-# define TRACEPRINTF(x...) do {} while (0)
-# define TRACEOUT(x...) do {} while (0)
-#endif
-
-
-/*---------------------------------------------------------------------------
- ---------------------------------------------------------------------------*/
-
 #ifndef PCI_VENDOR_ID_TEKRAM
 #define PCI_VENDOR_ID_TEKRAM                    0x1DE1	/* Vendor ID    */
 #endif
@@ -212,32 +144,16 @@
 #endif
 
 
-
 #define DC395x_LOCK_IO(dev,flags)		spin_lock_irqsave(((struct Scsi_Host *)dev)->host_lock, flags)
 #define DC395x_UNLOCK_IO(dev,flags)		spin_unlock_irqrestore(((struct Scsi_Host *)dev)->host_lock, flags)
 
-#define DC395x_ACB_INITLOCK(acb)		spin_lock_init(&acb->smp_lock)
-#define DC395x_ACB_LOCK(acb,acb_flags)		if (!acb->lock_level_count[cpuid]) { spin_lock_irqsave(&acb->smp_lock,acb_flags); acb->lock_level_count[cpuid]++; } else { acb->lock_level_count[cpuid]++; }
-#define DC395x_ACB_UNLOCK(acb,acb_flags)	if (--acb->lock_level_count[cpuid] == 0) { spin_unlock_irqrestore(&acb->smp_lock,acb_flags); }
-
-#define DC395x_SMP_IO_LOCK(dev,irq_flags)	spin_lock_irqsave(((struct Scsi_Host*)dev)->host_lock,irq_flags)
-#define DC395x_SMP_IO_UNLOCK(dev,irq_flags)	spin_unlock_irqrestore(((struct Scsi_Host*)dev)->host_lock,irq_flags)
-
-
 #define DC395x_read8(acb,address)		(u8)(inb(acb->io_port_base + (address)))
-#define DC395x_read8_(address, base)		(u8)(inb((USHORT)(base) + (address)))
 #define DC395x_read16(acb,address)		(u16)(inw(acb->io_port_base + (address)))
 #define DC395x_read32(acb,address)		(u32)(inl(acb->io_port_base + (address)))
 #define DC395x_write8(acb,address,value)	outb((value), acb->io_port_base + (address))
-#define DC395x_write8_(address,value,base)	outb((value), (USHORT)(base) + (address))
 #define DC395x_write16(acb,address,value)	outw((value), acb->io_port_base + (address))
 #define DC395x_write32(acb,address,value)	outl((value), acb->io_port_base + (address))
 
-
-#define BUS_ADDR(sg)		sg_dma_address(&(sg))
-#define CPU_ADDR(sg)		(page_address((sg).page)+(sg).offset)
-#define PAGE_ADDRESS(sg)	page_address((sg)->page)
-
 /* cmd->result */
 #define RES_TARGET		0x000000FF	/* Target State */
 #define RES_TARGET_LNX  STATUS_MASK	/* Only official ... */
@@ -254,20 +170,22 @@
 #define SET_RES_DID(who,did) { who &= ~RES_DID; who |= (int)(did) << 16; }
 #define SET_RES_DRV(who,drv) { who &= ~RES_DRV; who |= (int)(drv) << 24; }
 
-/*
-**************************************************************************
-*/
 #define TAG_NONE 255
 
+/*
+ * srb->segement_x is the hw sg list. It is always allocated as a
+ * DC395x_MAX_SG_LISTENTRY entries in a linear block which does not
+ * cross a page boundy.
+ */
+#define SEGMENTX_LEN	(sizeof(struct SGentry)*DC395x_MAX_SG_LISTENTRY)
+
+
 struct SGentry {
 	u32 address;		/* bus! address */
 	u32 length;
 };
 
-
-/*
- * The SEEPROM structure for TRM_S1040 
- */
+/* The SEEPROM structure for TRM_S1040 */
 struct NVRamTarget {
 	u8 cfg0;		/* Target configuration byte 0  */
 	u8 period;		/* Target period                */
@@ -275,7 +193,6 @@
 	u8 cfg3;		/* Target configuration byte 3  */
 };
 
-
 struct NvRamType {
 	u8 sub_vendor_id[2];	/* 0,1  Sub Vendor ID   */
 	u8 sub_sys_id[2];	/* 2,3  Sub System ID   */
@@ -302,28 +219,31 @@
 	u16 cksum;		/* 126,127 */
 };
 
-
-/*-----------------------------------------------------------------------
-  SCSI Request Block
-  -----------------------------------------------------------------------*/
 struct ScsiReqBlk {
 	struct list_head list;		/* next/prev ptrs for srb lists */
 	struct DeviceCtlBlk *dcb;
-
-	/* HW scatter list (up to 64 entries) */
-	struct SGentry *segment_x;
 	Scsi_Cmnd *cmd;
 
-	unsigned char *virt_addr;	/* set by update_sg_list */
+	struct SGentry *segment_x;	/* Linear array of hw sg entries (up to 64 entries) */
+	u32 sg_bus_addr;	        /* Bus address of sg list (ie, of segment_x) */
 
-	u32 total_xfer_length;
-	u32 xferred;		/* Backup for the already xferred len */
+	u8 sg_count;			/* No of HW sg entries for this request */
+	u8 sg_index;			/* Index of HW sg entry for this request */
+	u32 total_xfer_length;		/* Total number of bytes remaining to be transfered */
+	unsigned char *virt_addr;	/* Virtual address of current transfer position */
 
-	u32 sg_bus_addr;	/* bus address of DC395x scatterlist */
+	/*
+	 * The sense buffer handling function, request_sense, uses
+	 * the first hw sg entry (segment_x[0]) and the transfer
+	 * length (total_xfer_length). While doing this it stores the
+	 * original values into the last sg hw list
+	 * (srb->segment_x[DC395x_MAX_SG_LISTENTRY - 1] and the
+	 * total_xfer_length in xferred. These values are restored in
+	 * pci_unmap_srb_sense. This is the only place xferred is used.
+	 */
+	u32 xferred;		        /* Saved copy of total_xfer_length */
 
 	u16 state;
-	u8 sg_count;
-	u8 sg_index;
 
 	u8 msgin_buf[6];
 	u8 msgout_buf[6];
@@ -339,17 +259,8 @@
 	u8 flag;
 
 	u8 scsi_phase;
-
-#if debug_enabled(DBG_TRACE|DBG_TRACEALL)
-	u16 debugpos;
-	char *debugtrace;
-#endif
 };
 
-
-/*-----------------------------------------------------------------------
-  Device Control Block
-  -----------------------------------------------------------------------*/
 struct DeviceCtlBlk {
 	struct list_head list;		/* next/prev ptrs for the dcb list */
 	struct AdapterCtlBlk *acb;
@@ -377,9 +288,6 @@
 	u8 init_tcq_flag;
 };
 
-/*-----------------------------------------------------------------------
-  Adapter Control Block
-  -----------------------------------------------------------------------*/
 struct AdapterCtlBlk {
 	struct Scsi_Host *scsi_host;
 
@@ -423,80 +331,63 @@
 };
 
 
-
-
 /*---------------------------------------------------------------------------
                             Forward declarations
  ---------------------------------------------------------------------------*/
-static void data_out_phase0(struct AdapterCtlBlk *acb,
-			    struct ScsiReqBlk *srb,
-			    u16 * pscsi_status);
-static void data_in_phase0(struct AdapterCtlBlk *acb,
-			   struct ScsiReqBlk *srb,
-			   u16 * pscsi_status);
-static void command_phase0(struct AdapterCtlBlk *acb,
-			   struct ScsiReqBlk *srb,
-			   u16 * pscsi_status);
-static void status_phase0(struct AdapterCtlBlk *acb,
-			  struct ScsiReqBlk *srb,
-			  u16 * pscsi_status);
-static void msgout_phase0(struct AdapterCtlBlk *acb,
-			  struct ScsiReqBlk *srb,
-			  u16 * pscsi_status);
-static void msgin_phase0(struct AdapterCtlBlk *acb,
-			 struct ScsiReqBlk *srb,
-			 u16 * pscsi_status);
-static void data_out_phase1(struct AdapterCtlBlk *acb,
-			    struct ScsiReqBlk *srb,
-			    u16 * pscsi_status);
-static void data_in_phase1(struct AdapterCtlBlk *acb,
-			   struct ScsiReqBlk *srb,
-			   u16 * pscsi_status);
-static void command_phase1(struct AdapterCtlBlk *acb,
-			   struct ScsiReqBlk *srb,
-			   u16 * pscsi_status);
-static void status_phase1(struct AdapterCtlBlk *acb,
-			  struct ScsiReqBlk *srb,
-			  u16 * pscsi_status);
-static void msgout_phase1(struct AdapterCtlBlk *acb,
-			  struct ScsiReqBlk *srb,
-			  u16 * pscsi_status);
-static void msgin_phase1(struct AdapterCtlBlk *acb,
-			 struct ScsiReqBlk *srb,
-			 u16 * pscsi_status);
+static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status);
+static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status);
+static void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status);
+static void status_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status);
+static void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status);
+static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status);
+static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status);
+static void data_in_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status);
+static void command_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status);
+static void status_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status);
+static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status);
+static void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status);
 static void nop0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		 u16 * pscsi_status);
-static void nop1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		 u16 * pscsi_status);
+		u16 *pscsi_status);
+static void nop1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, 
+		u16 *pscsi_status);
 static void set_basic_config(struct AdapterCtlBlk *acb);
 static void cleanup_after_transfer(struct AdapterCtlBlk *acb,
-				   struct ScsiReqBlk *srb);
+		struct ScsiReqBlk *srb);
 static void reset_scsi_bus(struct AdapterCtlBlk *acb);
 static void data_io_transfer(struct AdapterCtlBlk *acb,
-			     struct ScsiReqBlk *srb, u16 io_dir);
+		struct ScsiReqBlk *srb, u16 io_dir);
 static void disconnect(struct AdapterCtlBlk *acb);
 static void reselect(struct AdapterCtlBlk *acb);
 static u8 start_scsi(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
-		     struct ScsiReqBlk *srb);
-static void build_srb(Scsi_Cmnd * cmd, struct DeviceCtlBlk *dcb,
-		      struct ScsiReqBlk *srb);
+		struct ScsiReqBlk *srb);
+static void build_srb(Scsi_Cmnd *cmd, struct DeviceCtlBlk *dcb,
+		struct ScsiReqBlk *srb);
 static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_code,
-			   Scsi_Cmnd * cmd, u8 force);
+		Scsi_Cmnd *cmd, u8 force);
 static void scsi_reset_detect(struct AdapterCtlBlk *acb);
-static void pci_unmap_srb(struct AdapterCtlBlk *acb,
-			  struct ScsiReqBlk *srb);
+static void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb);
 static void pci_unmap_srb_sense(struct AdapterCtlBlk *acb,
-				struct ScsiReqBlk *srb);
+		struct ScsiReqBlk *srb);
 static inline void enable_msgout_abort(struct AdapterCtlBlk *acb,
-				       struct ScsiReqBlk *srb);
-static void srb_done(struct AdapterCtlBlk *acb,
-		     struct DeviceCtlBlk *dcb,
-		     struct ScsiReqBlk *srb);
-static void request_sense(struct AdapterCtlBlk *acb,
-			  struct DeviceCtlBlk *dcb,
-			  struct ScsiReqBlk *srb);
+		struct ScsiReqBlk *srb);
+static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
+		struct ScsiReqBlk *srb);
+static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
+		struct ScsiReqBlk *srb);
 static inline void set_xfer_rate(struct AdapterCtlBlk *acb,
-				 struct DeviceCtlBlk *dcb);
+		struct DeviceCtlBlk *dcb);
 static void waiting_timeout(unsigned long ptr);
 
 
@@ -504,11 +395,7 @@
                                  Static Data
  ---------------------------------------------------------------------------*/
 static u16 current_sync_offset = 0;
-static char monitor_next_irq = 0;
 
-/* 
- * dc395x_statev = (void *)dc395x_scsi_phase0[phase]
- */
 static void *dc395x_scsi_phase0[] = {
 	data_out_phase0,/* phase:0 */
 	data_in_phase0,	/* phase:1 */
@@ -520,9 +407,6 @@
 	msgin_phase0,	/* phase:7 */
 };
 
-/*
- * dc395x_statev = (void *)dc395x_scsi_phase1[phase]
- */
 static void *dc395x_scsi_phase1[] = {
 	data_out_phase1,/* phase:0 */
 	data_in_phase1,	/* phase:1 */
@@ -558,8 +442,6 @@
 /* real period:48ns,76ns,100ns,124ns,148ns,176ns,200ns,248ns */
 static u8 clock_period[] = { 12, 18, 25, 31, 37, 43, 50, 62 };
 static u16 clock_speed[] = { 200, 133, 100, 80, 67, 58, 50, 40 };
-/* real period:48ns,72ns,100ns,124ns,148ns,172ns,200ns,248ns */
-
 
 
 /*---------------------------------------------------------------------------
@@ -655,8 +537,9 @@
 
 
 /*
- * Safe settings. If set to zero the the BIOS/default values with command line
- * overrides will be used. If set to 1 then safe and slow settings will be used.
+ * Safe settings. If set to zero the the BIOS/default values with
+ * command line overrides will be used. If set to 1 then safe and
+ * slow settings will be used.
  */
 static int use_safe_settings = 0;
 module_param_named(safe, use_safe_settings, bool, 0);
@@ -686,8 +569,7 @@
  * set_safe_settings - if the use_safe_settings option is set then
  * set all values to the safe and slow values.
  **/
-static
-void __init set_safe_settings(void)
+static void __init set_safe_settings(void)
 {
 	if (use_safe_settings)
 	{
@@ -706,25 +588,24 @@
  * fix_settings - reset any boot parameters which are out of range
  * back to the default values.
  **/
-static
-void __init fix_settings(void)
+static void __init fix_settings(void)
 {
 	int i;
 
-	dprintkdbg(DBG_PARSE, "setup %08x %08x %08x %08x %08x %08x\n",
-		    cfg_data[CFG_ADAPTER_ID].value,
-		    cfg_data[CFG_MAX_SPEED].value,
-		    cfg_data[CFG_DEV_MODE].value,
-		    cfg_data[CFG_ADAPTER_MODE].value,
-		    cfg_data[CFG_TAGS].value,
-		    cfg_data[CFG_RESET_DELAY].value);
+	dprintkdbg(DBG_1,
+		"setup: AdapterId=%08x MaxSpeed=%08x DevMode=%08x "
+		"AdapterMode=%08x Tags=%08x ResetDelay=%08x\n",
+		cfg_data[CFG_ADAPTER_ID].value,
+		cfg_data[CFG_MAX_SPEED].value,
+		cfg_data[CFG_DEV_MODE].value,
+		cfg_data[CFG_ADAPTER_MODE].value,
+		cfg_data[CFG_TAGS].value,
+		cfg_data[CFG_RESET_DELAY].value);
 	for (i = 0; i < CFG_NUM; i++)
 	{
-		if (cfg_data[i].value < cfg_data[i].min ||
-			cfg_data[i].value > cfg_data[i].max)
-		{
+		if (cfg_data[i].value < cfg_data[i].min
+		    || cfg_data[i].value > cfg_data[i].max)
 			cfg_data[i].value = cfg_data[i].def;
-		}
 	}
 }
 
@@ -734,8 +615,8 @@
  * Mapping from the eeprom delay index value (index into this array)
  * to the the number of actual seconds that the delay should be for.
  */
-static
-char __initdata eeprom_index_to_delay_map[] = { 1, 3, 5, 10, 16, 30, 60, 120 };
+static char __initdata eeprom_index_to_delay_map[] = 
+	{ 1, 3, 5, 10, 16, 30, 60, 120 };
 
 
 /**
@@ -744,25 +625,24 @@
  *
  * @eeprom: The eeprom structure in which we find the delay index to map.
  **/
-static
-void __init eeprom_index_to_delay(struct NvRamType *eeprom)
+static void __init eeprom_index_to_delay(struct NvRamType *eeprom)
 {
 	eeprom->delay_time = eeprom_index_to_delay_map[eeprom->delay_time];
 }
 
 
 /**
- * delay_to_eeprom_index - Take a delay in seconds and return the closest
- * eeprom index which will delay for at least that amount of seconds.
+ * delay_to_eeprom_index - Take a delay in seconds and return the
+ * closest eeprom index which will delay for at least that amount of
+ * seconds.
  *
  * @delay: The delay, in seconds, to find the eeprom index for.
  **/
 static int __init delay_to_eeprom_index(int delay)
 {
 	u8 idx = 0;
-	while (idx < 7 && eeprom_index_to_delay_map[idx] < delay) {
+	while (idx < 7 && eeprom_index_to_delay_map[idx] < delay)
 		idx++;
-	}
 	return idx;
 }
 
@@ -774,38 +654,34 @@
  *
  * @eeprom: The eeprom data to override with command line options.
  **/
-static
-void __init eeprom_override(struct NvRamType *eeprom)
+static void __init eeprom_override(struct NvRamType *eeprom)
 {
 	u8 id;
 
 	/* Adapter Settings */
-	if (cfg_data[CFG_ADAPTER_ID].value != CFG_PARAM_UNSET) {
-		eeprom->scsi_id =
-		    (u8)cfg_data[CFG_ADAPTER_ID].value;
-	}
-	if (cfg_data[CFG_ADAPTER_MODE].value != CFG_PARAM_UNSET) {
-		eeprom->channel_cfg =
-		    (u8)cfg_data[CFG_ADAPTER_MODE].value;
-	}
-	if (cfg_data[CFG_RESET_DELAY].value != CFG_PARAM_UNSET) {
-		eeprom->delay_time =
-		    delay_to_eeprom_index(cfg_data[CFG_RESET_DELAY].value);
-	}
-	if (cfg_data[CFG_TAGS].value != CFG_PARAM_UNSET) {
+	if (cfg_data[CFG_ADAPTER_ID].value != CFG_PARAM_UNSET)
+		eeprom->scsi_id = (u8)cfg_data[CFG_ADAPTER_ID].value;
+
+	if (cfg_data[CFG_ADAPTER_MODE].value != CFG_PARAM_UNSET)
+		eeprom->channel_cfg = (u8)cfg_data[CFG_ADAPTER_MODE].value;
+
+	if (cfg_data[CFG_RESET_DELAY].value != CFG_PARAM_UNSET)
+		eeprom->delay_time = delay_to_eeprom_index(
+					cfg_data[CFG_RESET_DELAY].value);
+
+	if (cfg_data[CFG_TAGS].value != CFG_PARAM_UNSET)
 		eeprom->max_tag = (u8)cfg_data[CFG_TAGS].value;
-	}
 
 	/* Device Settings */
 	for (id = 0; id < DC395x_MAX_SCSI_ID; id++) {
-		if (cfg_data[CFG_DEV_MODE].value != CFG_PARAM_UNSET) {
+		if (cfg_data[CFG_DEV_MODE].value != CFG_PARAM_UNSET)
 			eeprom->target[id].cfg0 =
-			    (u8)cfg_data[CFG_DEV_MODE].value;
-		}
-		if (cfg_data[CFG_MAX_SPEED].value != CFG_PARAM_UNSET) {
+				(u8)cfg_data[CFG_DEV_MODE].value;
+
+		if (cfg_data[CFG_MAX_SPEED].value != CFG_PARAM_UNSET)
 			eeprom->target[id].period =
-			    (u8)cfg_data[CFG_MAX_SPEED].value;
-		}
+				(u8)cfg_data[CFG_MAX_SPEED].value;
+
 	}
 }
 
@@ -813,39 +689,21 @@
 /*---------------------------------------------------------------------------
  ---------------------------------------------------------------------------*/
 
-/**
- * list_size - Returns the size (in number of entries) of the
- * supplied list.
- *
- * @head: The pointer to the head of the list to count the items in.
- **/
-static
-unsigned int list_size(struct list_head *head)
+static unsigned int list_size(struct list_head *head)
 {
 	unsigned int count = 0;
 	struct list_head *pos;
 	list_for_each(pos, head)
 		count++;
 	return count;
-}                                                                                        
+}
 
 
-/**
- * dcb_get_next - Given a dcb return the next dcb in the list of
- * dcb's, wrapping back to the start of the dcb list if required.
- * Returns the supplied dcb if there is only one dcb in the list.
- *
- * @head: The pointer to the head of the list to count the items in.
- * @pos: The pointer the dcb for which we are searching for the
- *       following dcb.
- **/
-static
-struct DeviceCtlBlk *dcb_get_next(
-		struct list_head *head,
+static struct DeviceCtlBlk *dcb_get_next(struct list_head *head,
 		struct DeviceCtlBlk *pos)
 {
 	int use_next = 0;
-	struct DeviceCtlBlk* next = NULL;	
+	struct DeviceCtlBlk* next = NULL;
 	struct DeviceCtlBlk* i;
 
 	if (list_empty(head))
@@ -870,22 +728,7 @@
 }
 
 
-/*
- * Queueing philosphy:
- * There are a couple of lists:
- * - Waiting: Contains a list of SRBs not yet sent (per DCB)
- * - Free: List of free SRB slots
- * 
- * If there are no waiting commands for the DCB, the new one is sent to the bus
- * otherwise the oldest one is taken from the Waiting list and the new one is 
- * queued to the Waiting List
- * 
- * Lists are managed using two pointers and eventually a counter
- */
-
-/* Nomen est omen ... */
-static inline
-void free_tag(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
+static void free_tag(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
 {
 	if (srb->tag_number < 255) {
 		dcb->tag_mask &= ~(1 << srb->tag_number);	/* free tag mask */
@@ -895,9 +738,8 @@
 
 
 /* Find cmd in SRB list */
-inline static
-struct ScsiReqBlk *find_cmd(Scsi_Cmnd *cmd,
-			    struct list_head *head)
+inline static struct ScsiReqBlk *find_cmd(Scsi_Cmnd *cmd, 
+		struct list_head *head)
 {
 	struct ScsiReqBlk *i;
 	list_for_each_entry(i, head, list)
@@ -907,88 +749,59 @@
 }
 
 
-/*
- * srb_get_free - Return a free srb from the list of free SRBs that
- * is stored with the acb.
- */
-static
-struct ScsiReqBlk *srb_get_free(struct AdapterCtlBlk *acb)
+static struct ScsiReqBlk *srb_get_free(struct AdapterCtlBlk *acb)
 {
 	struct list_head *head = &acb->srb_free_list;
-	struct ScsiReqBlk *srb;
+	struct ScsiReqBlk *srb = NULL;
 
 	if (!list_empty(head)) {
 		srb = list_entry(head->next, struct ScsiReqBlk, list);
 		list_del(head->next);
-		dprintkdbg(DBG_0, "srb_get_free: got srb %p\n", srb);
-	} else {
-		srb = NULL;
-		dprintkl(KERN_ERR, "Out of Free SRBs :-(\n");
+		dprintkdbg(DBG_0, "srb_get_free: srb=%p\n", srb);
 	}
 	return srb;
 }
 
 
-/*
- * srb_free_insert - Insert an srb to the head of the free list
- * stored in the acb.
- */
-static
-void srb_free_insert(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
+static void srb_free_insert(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
 {
-	dprintkdbg(DBG_0, "srb_free_insert: put srb %p\n", srb);
-        list_add_tail(&srb->list, &acb->srb_free_list);
+	dprintkdbg(DBG_0, "srb_free_insert: srb=%p\n", srb);
+	list_add_tail(&srb->list, &acb->srb_free_list);
 }
 
 
-/*
- * srb_waiting_insert - Insert an srb to the head of the wiating list
- * stored in the dcb.
- */
-static
-void srb_waiting_insert(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
+static void srb_waiting_insert(struct DeviceCtlBlk *dcb,
+		struct ScsiReqBlk *srb)
 {
-	dprintkdbg(DBG_0, "srb_waiting_insert: srb %p cmd %li\n", srb, srb->cmd->pid);
-        list_add(&srb->list, &dcb->srb_waiting_list);
+	dprintkdbg(DBG_0, "srb_waiting_insert: (pid#%li) <%02i-%i> srb=%p\n",
+		srb->cmd->pid, dcb->target_id, dcb->target_lun, srb);
+	list_add(&srb->list, &dcb->srb_waiting_list);
 }
 
 
-/*
- * srb_waiting_append - Append an srb to the tail of the waiting list
- * stored in the dcb.
- */
-static inline
-void srb_waiting_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
+static void srb_waiting_append(struct DeviceCtlBlk *dcb,
+		struct ScsiReqBlk *srb)
 {
-	dprintkdbg(DBG_0, "srb_waiting_append: srb %p cmd %li\n", srb, srb->cmd->pid);
-        list_add_tail(&srb->list, &dcb->srb_waiting_list);
+	dprintkdbg(DBG_0, "srb_waiting_append: (pid#%li) <%02i-%i> srb=%p\n",
+		 srb->cmd->pid, dcb->target_id, dcb->target_lun, srb);
+	list_add_tail(&srb->list, &dcb->srb_waiting_list);
 }
 
 
-/*
- * srb_going_append - Append an srb to the tail of the going list
- * stored in the dcb.
- */
-static inline
-void srb_going_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
+static void srb_going_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
 {
-	dprintkdbg(DBG_0, "srb_going_append: srb %p\n", srb);
-        list_add_tail(&srb->list, &dcb->srb_going_list);
+	dprintkdbg(DBG_0, "srb_going_append: (pid#%li) <%02i-%i> srb=%p\n",
+		srb->cmd->pid, dcb->target_id, dcb->target_lun, srb);
+	list_add_tail(&srb->list, &dcb->srb_going_list);
 }
 
 
-
-/*
- * srb_going_remove - Remove an srb from the going list stored in the
- * dcb.
- */
-static
-void srb_going_remove(struct DeviceCtlBlk *dcb,
-		      struct ScsiReqBlk *srb)
+static void srb_going_remove(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
 {
 	struct ScsiReqBlk *i;
 	struct ScsiReqBlk *tmp;
-	dprintkdbg(DBG_0, "srb_going_remove: srb %p\n", srb);
+	dprintkdbg(DBG_0, "srb_going_remove: (pid#%li) <%02i-%i> srb=%p\n",
+		srb->cmd->pid, dcb->target_id, dcb->target_lun, srb);
 
 	list_for_each_entry_safe(i, tmp, &dcb->srb_going_list, list)
 		if (i == srb) {
@@ -998,17 +811,13 @@
 }
 
 
-/*
- * srb_waiting_remove - Remove an srb from the waiting list stored in the
- * dcb.
- */
-static
-void srb_waiting_remove(struct DeviceCtlBlk *dcb,
-			struct ScsiReqBlk *srb)
+static void srb_waiting_remove(struct DeviceCtlBlk *dcb,
+		struct ScsiReqBlk *srb)
 {
 	struct ScsiReqBlk *i;
 	struct ScsiReqBlk *tmp;
-	dprintkdbg(DBG_0, "srb_waiting_remove: srb %p\n", srb);
+	dprintkdbg(DBG_0, "srb_waiting_remove: (pid#%li) <%02i-%i> srb=%p\n",
+		srb->cmd->pid, dcb->target_id, dcb->target_lun, srb);
 
 	list_for_each_entry_safe(i, tmp, &dcb->srb_waiting_list, list)
 		if (i == srb) {
@@ -1018,37 +827,28 @@
 }
 
 
-/*
- * srb_going_to_waiting_move - Remove an srb from the going list in
- * the dcb and insert it at the head of the waiting list in the dcb.
- */
-static
-void srb_going_to_waiting_move(struct DeviceCtlBlk *dcb,
-			       struct ScsiReqBlk *srb)
+static void srb_going_to_waiting_move(struct DeviceCtlBlk *dcb,
+		struct ScsiReqBlk *srb)
 {
-	dprintkdbg(DBG_0, "srb_going_waiting_move: srb %p, pid = %li\n", srb, srb->cmd->pid);
+	dprintkdbg(DBG_0,
+		"srb_going_to_waiting_move: (pid#%li) <%02i-%i> srb=%p\n",
+		srb->cmd->pid, dcb->target_id, dcb->target_lun, srb);
 	list_move(&srb->list, &dcb->srb_waiting_list);
 }
 
 
-/*
- * srb_waiting_to_going_move - Remove an srb from the waiting list in
- * the dcb and insert it at the head of the going list in the dcb.
- */
-static
-void srb_waiting_to_going_move(struct DeviceCtlBlk *dcb,
-			       struct ScsiReqBlk *srb)
-{
-	/* Remove from waiting list */
-	dprintkdbg(DBG_0, "srb_waiting_to_going: srb %p\n", srb);
-	TRACEPRINTF("WtG *");
+static void srb_waiting_to_going_move(struct DeviceCtlBlk *dcb,
+		struct ScsiReqBlk *srb)
+{
+	dprintkdbg(DBG_0,
+		"srb_waiting_to_going_move: (pid#%li) <%02i-%i> srb=%p\n",
+		srb->cmd->pid, dcb->target_id, dcb->target_lun, srb);
 	list_move(&srb->list, &dcb->srb_going_list);
 }
 
 
 /* Sets the timer to wake us up */
-static
-void waiting_set_timer(struct AdapterCtlBlk *acb, unsigned long to)
+static void waiting_set_timer(struct AdapterCtlBlk *acb, unsigned long to)
 {
 	if (timer_pending(&acb->waiting_timer))
 		return;
@@ -1065,8 +865,7 @@
 
 
 /* Send the next command from the waiting list to the bus */
-static
-void waiting_process_next(struct AdapterCtlBlk *acb)
+static void waiting_process_next(struct AdapterCtlBlk *acb)
 {
 	struct DeviceCtlBlk *start = NULL;
 	struct DeviceCtlBlk *pos;
@@ -1074,7 +873,7 @@
 	struct ScsiReqBlk *srb;
 	struct list_head *dcb_list_head = &acb->dcb_list;
 
-	if ((acb->active_dcb)
+	if (acb->active_dcb
 	    || (acb->acb_flag & (RESET_DETECT + RESET_DONE + RESET_DEV)))
 		return;
 
@@ -1135,8 +934,9 @@
 static void waiting_timeout(unsigned long ptr)
 {
 	unsigned long flags;
-	struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *) ptr;
-	dprintkdbg(DBG_KG, "Debug: Waiting queue woken up by timer.\n");
+	struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)ptr;
+	dprintkdbg(DBG_1,
+		"waiting_timeout: Queue woken up by timer. acb=%p\n", acb);
 	DC395x_LOCK_IO(acb->scsi_host, flags);
 	waiting_process_next(acb);
 	DC395x_UNLOCK_IO(acb->scsi_host, flags);
@@ -1144,28 +944,17 @@
 
 
 /* Get the DCB for a given ID/LUN combination */
-static inline
-struct DeviceCtlBlk *find_dcb(struct AdapterCtlBlk *acb, u8 id, u8 lun)
+static struct DeviceCtlBlk *find_dcb(struct AdapterCtlBlk *acb, u8 id, u8 lun)
 {
 	return acb->children[id][lun];
 }
 
 
-/***********************************************************************
- * Function: static void send_srb (struct AdapterCtlBlk* acb, struct ScsiReqBlk* srb)
- *
- * Purpose: Send SCSI Request Block (srb) to adapter (acb)
- *
- *            dc395x_queue_command
- *            waiting_process_next
- *
- ***********************************************************************/
-static
-void send_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
+/* Send SCSI Request Block (srb) to adapter (acb) */
+static void send_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
 {
-	struct DeviceCtlBlk *dcb;
+	struct DeviceCtlBlk *dcb = srb->dcb;
 
-	dcb = srb->dcb;
 	if (dcb->max_command <= list_size(&dcb->srb_going_list) ||
 	    acb->active_dcb ||
 	    (acb->acb_flag & (RESET_DETECT + RESET_DONE + RESET_DEV))) {
@@ -1174,130 +963,29 @@
 		return;
 	}
 
-	if (!start_scsi(acb, dcb, srb)) {
+	if (!start_scsi(acb, dcb, srb))
 		srb_going_append(dcb, srb);
-	} else {
+	else {
 		srb_waiting_insert(dcb, srb);
 		waiting_set_timer(acb, HZ / 50);
 	}
 }
 
 
-/*
- *********************************************************************
- *
- * Function: static void build_srb (Scsi_Cmd *cmd, struct DeviceCtlBlk* dcb, struct ScsiReqBlk* srb)
- *
- *  Purpose: Prepare SRB for being sent to Device DCB w/ command *cmd
- *
- *********************************************************************
- */
-static
-void build_srb(Scsi_Cmnd * cmd, struct DeviceCtlBlk *dcb,
-	       struct ScsiReqBlk *srb)
-{
-	int i, max;
-	struct SGentry *sgp;
-	struct scatterlist *sl;
-	u32 request_size;
-	int dir;
+/* Prepare SRB for being sent to Device DCB w/ command *cmd */
+static void build_srb(Scsi_Cmnd *cmd, struct DeviceCtlBlk *dcb,
+		struct ScsiReqBlk *srb)
+{
+	int dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+	dprintkdbg(DBG_0, "build_srb: (pid#%li) <%02i-%i>\n",
+		cmd->pid, dcb->target_id, dcb->target_lun);
 
-	dprintkdbg(DBG_0, "build_srb..............\n");
-	/*memset (srb, 0, sizeof (struct ScsiReqBlk)); */
 	srb->dcb = dcb;
 	srb->cmd = cmd;
-	/* Find out about direction */
-	dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
-
-	if (cmd->use_sg && dir != PCI_DMA_NONE) {
-		unsigned int len = 0;
-		/* TODO: In case usg_sg and the no of segments differ, things
-		 * will probably go wrong. */
-		max = srb->sg_count =
-		    pci_map_sg(dcb->acb->dev,
-			       (struct scatterlist *) cmd->request_buffer,
-			       cmd->use_sg, dir);
-		sgp = srb->segment_x;
-		request_size = cmd->request_bufflen;
-		dprintkdbg(DBG_SGPARANOIA, 
-		       "BuildSRB: Bufflen = %d, buffer = %p, use_sg = %d\n",
-		       cmd->request_bufflen, cmd->request_buffer,
-		       cmd->use_sg);
-		dprintkdbg(DBG_SGPARANOIA, 
-		       "Mapped %i Segments to %i\n", cmd->use_sg,
-		       srb->sg_count);
-		sl = (struct scatterlist *) cmd->request_buffer;
-
-		srb->virt_addr = page_address(sl->page);
-		for (i = 0; i < max; i++) {
-			u32 busaddr = (u32) sg_dma_address(&sl[i]);
-			u32 seglen = (u32) sl[i].length;
-			sgp[i].address = busaddr;
-			sgp[i].length = seglen;
-			len += seglen;
-			dprintkdbg(DBG_SGPARANOIA,
-			       "Setting up sgp %d, address = 0x%08x, length = %d, tot len = %d\n",
-			       i, busaddr, seglen, len);
-		}
-		sgp += max - 1;
-		/* Fixup for last buffer too big as it is allocated on even page boundaries */
-		if (len > request_size) {
-#if debug_enabled(DBG_KG) || debug_enabled(DBG_SGPARANOIA)
-			dprintkdbg(DBG_KG|DBG_SGPARANOIA,
-			       "Fixup SG total length: %d->%d, last seg %d->%d\n",
-			       len, request_size, sgp->length,
-			       sgp->length - (len - request_size));
-#endif
-			sgp->length -= (len - request_size);
-			len = request_size;
-		}
-		/* WIDE padding */
-		if (dcb->sync_period & WIDE_SYNC && len % 2) {
-			len++;
-			sgp->length++;
-		}
-		srb->total_xfer_length = len;	/*? */
-		/* Hopefully this does not cross a page boundary ... */
-		srb->sg_bus_addr =
-		    pci_map_single(dcb->acb->dev, srb->segment_x,
-				   sizeof(struct SGentry) *
-				   DC395x_MAX_SG_LISTENTRY,
-				   PCI_DMA_TODEVICE);
-		dprintkdbg(DBG_SGPARANOIA,
-		       "Map SG descriptor list %p (%05x) to %08x\n",
-		       srb->segment_x,
-		       sizeof(struct SGentry) * DC395x_MAX_SG_LISTENTRY,
-		       srb->sg_bus_addr);
-	} else {
-		if (cmd->request_buffer && dir != PCI_DMA_NONE) {
-			u32 len = cmd->request_bufflen;	/* Actual request size */
-			srb->sg_count = 1;
-			srb->segment_x[0].address =
-			    pci_map_single(dcb->acb->dev,
-					   cmd->request_buffer, len, dir);
-			/* WIDE padding */
-			if (dcb->sync_period & WIDE_SYNC && len % 2)
-				len++;
-			srb->segment_x[0].length = len;
-			srb->total_xfer_length = len;
-			srb->virt_addr = cmd->request_buffer;
-			srb->sg_bus_addr = 0;
-			dprintkdbg(DBG_SGPARANOIA,
-			       "BuildSRB: len = %d, buffer = %p, use_sg = %d, map %08x\n",
-			       len, cmd->request_buffer, cmd->use_sg,
-			       srb->segment_x[0].address);
-		} else {
-			srb->sg_count = 0;
-			srb->total_xfer_length = 0;
-			srb->sg_bus_addr = 0;
-			srb->virt_addr = 0;
-			dprintkdbg(DBG_SGPARANOIA,
-			       "BuildSRB: buflen = %d, buffer = %p, use_sg = %d, NOMAP %08x\n",
-			       cmd->bufflen, cmd->request_buffer,
-			       cmd->use_sg, srb->segment_x[0].address);
-		}
-	}
-
+	srb->sg_count = 0;
+	srb->total_xfer_length = 0;
+	srb->sg_bus_addr = 0;
+	srb->virt_addr = 0;
 	srb->sg_index = 0;
 	srb->adapter_status = 0;
 	srb->target_status = 0;
@@ -1306,29 +994,80 @@
 	srb->flag = 0;
 	srb->state = 0;
 	srb->retry_count = 0;
-
-#if debug_enabled(DBG_TRACE|DBG_TRACEALL) && debug_enabled(DBG_SGPARANOIA)
-	if ((unsigned long)srb->debugtrace & (DEBUGTRACEBUFSZ - 1)) {
-		dprintkdbg(DBG_SGPARANOIA,
-			"SRB %i (%p): debugtrace %p corrupt!\n",
-		       (srb - dcb->acb->srb_array) /
-		       sizeof(struct ScsiReqBlk), srb, srb->debugtrace);
-	}
-#endif
-#if debug_enabled(DBG_TRACE|DBG_TRACEALL)
-	srb->debugpos = 0;
-	srb->debugtrace = 0;
-#endif
-	TRACEPRINTF("pid %li(%li):%02x %02x..(%i-%i) *", cmd->pid,
-		    jiffies, cmd->cmnd[0], cmd->cmnd[1],
-		    cmd->device->id, cmd->device->lun);
 	srb->tag_number = TAG_NONE;
-
 	srb->scsi_phase = PH_BUS_FREE;	/* initial phase */
 	srb->end_message = 0;
-	return;
-}
 
+	if (dir == PCI_DMA_NONE || !cmd->request_buffer) {
+		dprintkdbg(DBG_0,
+			"build_srb: [0] len=%d buf=%p use_sg=%d !MAP=%08x\n",
+			cmd->bufflen, cmd->request_buffer,
+			cmd->use_sg, srb->segment_x[0].address);
+	} else if (cmd->use_sg) {
+		int i;
+		u32 reqlen = cmd->request_bufflen;
+		struct scatterlist *sl = (struct scatterlist *)
+					 cmd->request_buffer;
+		struct SGentry *sgp = srb->segment_x;
+		srb->sg_count = pci_map_sg(dcb->acb->dev, sl, cmd->use_sg,
+					   dir);
+		dprintkdbg(DBG_0,
+			"build_srb: [n] len=%d buf=%p use_sg=%d segs=%d\n",
+			reqlen, cmd->request_buffer, cmd->use_sg,
+			srb->sg_count);
+
+		srb->virt_addr = page_address(sl->page);
+		for (i = 0; i < srb->sg_count; i++) {
+			u32 busaddr = (u32)sg_dma_address(&sl[i]);
+			u32 seglen = (u32)sl[i].length;
+			sgp[i].address = busaddr;
+			sgp[i].length = seglen;
+			srb->total_xfer_length += seglen;
+		}
+		sgp += srb->sg_count - 1;
+
+		/*
+		 * adjust last page if too big as it is allocated
+		 * on even page boundaries
+		 */
+		if (srb->total_xfer_length > reqlen) {
+			sgp->length -= (srb->total_xfer_length - reqlen);
+			srb->total_xfer_length = reqlen;
+		}
+
+		/* Fixup for WIDE padding - make sure length is even */
+		if (dcb->sync_period & WIDE_SYNC &&
+		    srb->total_xfer_length % 2) {
+			srb->total_xfer_length++;
+			sgp->length++;
+		}
+
+		srb->sg_bus_addr = pci_map_single(dcb->acb->dev,
+						srb->segment_x,
+				            	SEGMENTX_LEN,
+				            	PCI_DMA_TODEVICE);
+
+		dprintkdbg(DBG_SG, "build_srb: [n] map sg %p->%08x(%05x)\n",
+			srb->segment_x, srb->sg_bus_addr, SEGMENTX_LEN);
+	} else {
+		srb->total_xfer_length = cmd->request_bufflen;
+		srb->sg_count = 1;
+		srb->segment_x[0].address =
+			pci_map_single(dcb->acb->dev, cmd->request_buffer,
+				       srb->total_xfer_length, dir);
+
+		/* Fixup for WIDE padding - make sure length is even */
+		if (dcb->sync_period & WIDE_SYNC && srb->total_xfer_length % 2)
+			srb->total_xfer_length++;
+
+		srb->segment_x[0].length = srb->total_xfer_length;
+		srb->virt_addr = cmd->request_buffer;
+		dprintkdbg(DBG_0,
+			"build_srb: [1] len=%d buf=%p use_sg=%d map=%08x\n",
+			srb->total_xfer_length, cmd->request_buffer,
+			cmd->use_sg, srb->segment_x[0].address);
+	}
+}
 
 
 /**
@@ -1350,27 +1089,14 @@
  *        and is expected to be held on return.
  *
  **/
-static int
-dc395x_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+static int dc395x_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
 	struct DeviceCtlBlk *dcb;
 	struct ScsiReqBlk *srb;
 	struct AdapterCtlBlk *acb =
 	    (struct AdapterCtlBlk *)cmd->device->host->hostdata;
-
-	dprintkdbg(DBG_0, "Queue Cmd=%02x,Tgt=%d,LUN=%d (pid=%li)\n",
-		   cmd->cmnd[0],
-		   cmd->device->id,
-		   cmd->device->lun,
-		   cmd->pid);
-
-#if debug_enabled(DBG_RECURSION)
-	if (dbg_in_driver++ > NORM_REC_LVL) {
-		dprintkl(KERN_DEBUG,
-			"%i queue_command () recursion? (pid=%li)\n",
-			dbg_in_driver, cmd->pid);
-	}
-#endif
+	dprintkdbg(DBG_0, "queue_command: (pid#%li) <%02i-%i> cmnd=0x%02x\n",
+		cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
 
 	/* Assume BAD_TARGET; will be cleared later */
 	cmd->result = DID_BAD_TARGET << 16;
@@ -1384,8 +1110,8 @@
 
 	/* does the specified lun on the specified device exist */
 	if (!(acb->dcb_map[cmd->device->id] & (1 << cmd->device->lun))) {
-		dprintkl(KERN_INFO, "Ignore target %02x lun %02x\n", cmd->device->id,
-		       cmd->device->lun);
+		dprintkl(KERN_INFO, "queue_command: Ignore target <%02i-%i>\n",
+			cmd->device->id, cmd->device->lun);
 		goto complete;
 	}
 
@@ -1393,9 +1119,8 @@
 	dcb = find_dcb(acb, cmd->device->id, cmd->device->lun);
 	if (!dcb) {
 		/* should never happen */
-		dprintkl(KERN_ERR, "no DCB failed, target %02x lun %02x\n",
-				   cmd->device->id, cmd->device->lun);
-		dprintkl(KERN_ERR, "No DCB in queuecommand (2)!\n");
+		dprintkl(KERN_ERR, "queue_command: No such device <%02i-%i>",
+			cmd->device->id, cmd->device->lun);
 		goto complete;
 	}
 
@@ -1403,7 +1128,6 @@
 	cmd->scsi_done = done;
 	cmd->result = 0;
 
-	/* get a free SRB */
 	srb = srb_get_free(acb);
 	if (!srb)
 	{
@@ -1411,11 +1135,10 @@
 		 * Return 1 since we are unable to queue this command at this
 		 * point in time.
 		 */
-		dprintkdbg(DBG_0, "No free SRB's in queuecommand\n");
+		dprintkdbg(DBG_0, "queue_command: No free srb's\n");
 		return 1;
 	}
 
-	/* build srb for the command */
 	build_srb(cmd, dcb, srb);
 
 	if (!list_empty(&dcb->srb_waiting_list)) {
@@ -1426,11 +1149,7 @@
 		/* process immediately */
 		send_srb(acb, srb);
 	}
-	dprintkdbg(DBG_1, "... command (pid %li) queued successfully.\n", cmd->pid);
-
-#if debug_enabled(DBG_RECURSION)
-	dbg_in_driver--
-#endif
+	dprintkdbg(DBG_1, "queue_command: (pid#%li) done\n", cmd->pid);
 	return 0;
 
 complete:
@@ -1440,28 +1159,16 @@
 	 * done when the commad is for things like non existent
 	 * devices.
 	 */
-#if debug_enabled(DBG_RECURSION)
-		dbg_in_driver--
-#endif
 	done(cmd);
 	return 0;
 }
 
 
-
-
 /*
- *********************************************************************
- *
- * Function   : dc395x_bios_param
- * Description: Return the disk geometry for the given SCSI device.
- *********************************************************************
+ * Return the disk geometry for the given SCSI device.
  */
-static
-int dc395x_bios_param(struct scsi_device *sdev,
-		      struct block_device *bdev,
-		      sector_t capacity,
-		      int *info)
+static int dc395x_bios_param(struct scsi_device *sdev,
+		struct block_device *bdev, sector_t capacity, int *info)
 {
 #ifdef CONFIG_SCSI_DC395x_TRMS1040_TRADMAP
 	int heads, sectors, cylinders;
@@ -1469,7 +1176,7 @@
 	int size = capacity;
 
 	dprintkdbg(DBG_0, "dc395x_bios_param..............\n");
-	acb = (struct AdapterCtlBlk *) sdev->host->hostdata;
+	acb = (struct AdapterCtlBlk *)sdev->host->hostdata;
 	heads = 64;
 	sectors = 32;
 	cylinders = size / (heads * sectors);
@@ -1489,12 +1196,8 @@
 }
 
 
-/*
- * DC395x register dump
- */
-static
-void dump_register_info(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
-			struct ScsiReqBlk *srb)
+static void dump_register_info(struct AdapterCtlBlk *acb,
+		struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
 {
 	u16 pstat;
 	struct pci_dev *dev = acb->dev;
@@ -1504,64 +1207,58 @@
 	if (!srb && dcb)
 		srb = dcb->active_srb;
 	if (srb) {
-		if (!(srb->cmd))
-			dprintkl(KERN_INFO, "dump: SRB %p: cmd %p OOOPS!\n", srb,
-			       srb->cmd);
+		if (!srb->cmd)
+			dprintkl(KERN_INFO, "dump: srb=%p cmd=%p OOOPS!\n",
+				srb, srb->cmd);
 		else
-			dprintkl(KERN_INFO, "dump: SRB %p: cmd %p pid %li: %02x (%02i-%i)\n",
-			       srb, srb->cmd, srb->cmd->pid,
-			       srb->cmd->cmnd[0], srb->cmd->device->id,
-			       srb->cmd->device->lun);
-		printk("              SGList %p Cnt %i Idx %i Len %i\n",
+			dprintkl(KERN_INFO, "dump: srb=%p cmd=%p (pid#%li) "
+				 "cmnd=0x%02x <%02i-%i>\n",
+			    	srb, srb->cmd, srb->cmd->pid,
+				srb->cmd->cmnd[0], srb->cmd->device->id,
+			       	srb->cmd->device->lun);
+		printk("  sglist=%p cnt=%i idx=%i len=%i\n",
 		       srb->segment_x, srb->sg_count, srb->sg_index,
 		       srb->total_xfer_length);
-		printk
-		    ("              State %04x Status %02x Phase %02x (%sconn.)\n",
-		     srb->state, srb->status, srb->scsi_phase,
-		     (acb->active_dcb) ? "" : "not");
-		TRACEOUT("        %s\n", srb->debugtrace);
-	}
-	dprintkl(KERN_INFO, "dump: SCSI block\n");
-	printk
-	    ("              Status %04x FIFOCnt %02x Signals %02x IRQStat %02x\n",
-	     DC395x_read16(acb, TRM_S1040_SCSI_STATUS),
-	     DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),
-	     DC395x_read8(acb, TRM_S1040_SCSI_SIGNAL),
-	     DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS));
-	printk
-	    ("              Sync %02x Target %02x RSelID %02x SCSICtr %08x\n",
-	     DC395x_read8(acb, TRM_S1040_SCSI_SYNC),
-	     DC395x_read8(acb, TRM_S1040_SCSI_TARGETID),
-	     DC395x_read8(acb, TRM_S1040_SCSI_IDMSG),
-	     DC395x_read32(acb, TRM_S1040_SCSI_COUNTER));
-	printk
-	    ("              IRQEn %02x Config %04x Cfg2 %02x Cmd %02x SelTO %02x\n",
-	     DC395x_read8(acb, TRM_S1040_SCSI_INTEN),
-	     DC395x_read16(acb, TRM_S1040_SCSI_CONFIG0),
-	     DC395x_read8(acb, TRM_S1040_SCSI_CONFIG2),
-	     DC395x_read8(acb, TRM_S1040_SCSI_COMMAND),
-	     DC395x_read8(acb, TRM_S1040_SCSI_TIMEOUT));
-	dprintkl(KERN_INFO, "dump: DMA block\n");
-	printk
-	    ("              Cmd %04x FIFOCnt %02x FStat %02x IRQStat %02x IRQEn %02x Cfg %04x\n",
-	     DC395x_read16(acb, TRM_S1040_DMA_COMMAND),
-	     DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),
-	     DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT),
-	     DC395x_read8(acb, TRM_S1040_DMA_STATUS),
-	     DC395x_read8(acb, TRM_S1040_DMA_INTEN),
-	     DC395x_read16(acb, TRM_S1040_DMA_CONFIG));
-	printk("              TCtr %08x CTCtr %08x Addr %08x%08x\n",
-	       DC395x_read32(acb, TRM_S1040_DMA_XCNT),
-	       DC395x_read32(acb, TRM_S1040_DMA_CXCNT),
-	       DC395x_read32(acb, TRM_S1040_DMA_XHIGHADDR),
-	       DC395x_read32(acb, TRM_S1040_DMA_XLOWADDR));
-	dprintkl(KERN_INFO, "dump: Misc: GCtrl %02x GStat %02x GTmr %02x\n",
-	       DC395x_read8(acb, TRM_S1040_GEN_CONTROL),
-	       DC395x_read8(acb, TRM_S1040_GEN_STATUS),
-	       DC395x_read8(acb, TRM_S1040_GEN_TIMER));
-	dprintkl(KERN_INFO, "dump: PCI Status %04x\n", pstat);
-
-
+		printk("  state=0x%04x status=0x%02x phase=0x%02x (%sconn.)\n",
+		       srb->state, srb->status, srb->scsi_phase,
+		       (acb->active_dcb) ? "" : "not");
+	}
+	dprintkl(KERN_INFO, "dump: SCSI{status=0x%04x fifocnt=0x%02x "
+		"signals=0x%02x irqstat=0x%02x sync=0x%02x target=0x%02x "
+		"rselid=0x%02x ctr=0x%08x irqen=0x%02x config=0x%04x "
+		"config2=0x%02x cmd=0x%02x selto=0x%02x}\n",
+		DC395x_read16(acb, TRM_S1040_SCSI_STATUS),
+		DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),
+		DC395x_read8(acb, TRM_S1040_SCSI_SIGNAL),
+		DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS),
+		DC395x_read8(acb, TRM_S1040_SCSI_SYNC),
+		DC395x_read8(acb, TRM_S1040_SCSI_TARGETID),
+		DC395x_read8(acb, TRM_S1040_SCSI_IDMSG),
+		DC395x_read32(acb, TRM_S1040_SCSI_COUNTER),
+		DC395x_read8(acb, TRM_S1040_SCSI_INTEN),
+		DC395x_read16(acb, TRM_S1040_SCSI_CONFIG0),
+		DC395x_read8(acb, TRM_S1040_SCSI_CONFIG2),
+		DC395x_read8(acb, TRM_S1040_SCSI_COMMAND),
+		DC395x_read8(acb, TRM_S1040_SCSI_TIMEOUT));
+	dprintkl(KERN_INFO, "dump: DMA{cmd=0x%04x fifocnt=0x%02x fstat=0x%02x "
+		"irqstat=0x%02x irqen=0x%02x cfg=0x%04x tctr=0x%08x "
+		"ctctr=0x%08x addr=0x%08x:0x%08x}\n",
+		DC395x_read16(acb, TRM_S1040_DMA_COMMAND),
+		DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),
+		DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT),
+		DC395x_read8(acb, TRM_S1040_DMA_STATUS),
+		DC395x_read8(acb, TRM_S1040_DMA_INTEN),
+		DC395x_read16(acb, TRM_S1040_DMA_CONFIG),
+		DC395x_read32(acb, TRM_S1040_DMA_XCNT),
+		DC395x_read32(acb, TRM_S1040_DMA_CXCNT),
+		DC395x_read32(acb, TRM_S1040_DMA_XHIGHADDR),
+		DC395x_read32(acb, TRM_S1040_DMA_XLOWADDR));
+	dprintkl(KERN_INFO, "dump: gen{gctrl=0x%02x gstat=0x%02x gtmr=0x%02x} "
+		"pci{status=0x%04x}\n",
+		DC395x_read8(acb, TRM_S1040_GEN_CONTROL),
+		DC395x_read8(acb, TRM_S1040_GEN_STATUS),
+		DC395x_read8(acb, TRM_S1040_GEN_TIMER),
+		pstat);
 }
 
 
@@ -1572,32 +1269,19 @@
 	u8 fifocnt = DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT);
 	if (!(fifocnt & 0x40))
 		dprintkdbg(DBG_FIFO,
-		       "Clr FIFO (%i bytes) on phase %02x in %s\n",
+			"clear_fifo: (%i bytes) on phase %02x in %s\n",
 			fifocnt & 0x3f, lines, txt);
 #endif
-#if debug_enabled(DBG_TRACE)   
-	if (acb->active_dcb && acb->active_dcb->active_srb) {
-		struct ScsiReqBlk *srb = acb->active_dcb->active_srb;
-		TRACEPRINTF("#*");
-	}
-#endif
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_CLRFIFO);
 }
 
 
-/*
- ********************************************************************
- *
- *		DC395x_reset      scsi_reset_detect
- *
- ********************************************************************
- */
 static void reset_dev_param(struct AdapterCtlBlk *acb)
 {
 	struct DeviceCtlBlk *dcb;
 	struct NvRamType *eeprom = &acb->eeprom;
+	dprintkdbg(DBG_0, "reset_dev_param: acb=%p\n", acb);
 
-	dprintkdbg(DBG_0, "reset_dev_param..............\n");
 	list_for_each_entry(dcb, &acb->dcb_list, list) {
 		u8 period_index;
 
@@ -1616,22 +1300,17 @@
 
 
 /*
- *********************************************************************
- * Function : int dc395x_eh_bus_reset(Scsi_Cmnd *cmd)
- * Purpose  : perform a hard reset on the SCSI bus
- * Inputs   : cmd - some command for this host (for fetching hooks)
- * Returns  : SUCCESS (0x2002) on success, else FAILED (0x2003).
- *********************************************************************
+ * perform a hard reset on the SCSI bus
+ * @cmd - some command for this host (for fetching hooks)
+ * Returns: SUCCESS (0x2002) on success, else FAILED (0x2003).
  */
-static int dc395x_eh_bus_reset(Scsi_Cmnd * cmd)
+static int dc395x_eh_bus_reset(Scsi_Cmnd *cmd)
 {
-	struct AdapterCtlBlk *acb;
-	/*u32         acb_flags=0; */
-
-	dprintkl(KERN_INFO, "reset requested!\n");
-	acb = (struct AdapterCtlBlk *) cmd->device->host->hostdata;
-	/* mid level guarantees no recursion */
-	/*DC395x_ACB_LOCK(acb,acb_flags); */
+	struct AdapterCtlBlk *acb =
+		(struct AdapterCtlBlk *)cmd->device->host->hostdata;
+	dprintkl(KERN_INFO,
+		"eh_bus_reset: (pid#%li) target=<%02i-%i> cmd=%p\n",
+		cmd->pid, cmd->device->id, cmd->device->lun, cmd);
 
 	if (timer_pending(&acb->waiting_timer))
 		del_timer(&acb->waiting_timer);
@@ -1657,52 +1336,42 @@
 	 */
 	/* Clear SCSI FIFO          */
 	DC395x_write8(acb, TRM_S1040_DMA_CONTROL, CLRXFIFO);
-	clear_fifo(acb, "reset");
+	clear_fifo(acb, "eh_bus_reset");
 	/* Delete pending IRQ */
 	DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS);
 	set_basic_config(acb);
 
 	reset_dev_param(acb);
 	doing_srb_done(acb, DID_RESET, cmd, 0);
-
 	acb->active_dcb = NULL;
-
 	acb->acb_flag = 0;	/* RESET_DETECT, RESET_DONE ,RESET_DEV */
 	waiting_process_next(acb);
 
-	/*DC395x_ACB_LOCK(acb,acb_flags); */
 	return SUCCESS;
 }
 
 
 /*
- *********************************************************************
- * Function : int dc395x_eh_abort(Scsi_Cmnd *cmd)
- * Purpose  : abort an errant SCSI command
- * Inputs   : cmd - command to be aborted
- * Returns  : SUCCESS (0x2002) on success, else FAILED (0x2003).
- *********************************************************************
+ * abort an errant SCSI command
+ * @cmd - command to be aborted
+ * Returns: SUCCESS (0x2002) on success, else FAILED (0x2003).
  */
-static int dc395x_eh_abort(Scsi_Cmnd * cmd)
+static int dc395x_eh_abort(Scsi_Cmnd *cmd)
 {
 	/*
 	 * Look into our command queues: If it has not been sent already,
 	 * we remove it and return success. Otherwise fail.
 	 */
 	struct AdapterCtlBlk *acb =
-	    (struct AdapterCtlBlk *) cmd->device->host->hostdata;
+	    (struct AdapterCtlBlk *)cmd->device->host->hostdata;
 	struct DeviceCtlBlk *dcb;
 	struct ScsiReqBlk *srb;
-
-	dprintkl(KERN_INFO, "eh abort: cmd %p (pid %li, %02i-%i) ",
-			     cmd,
-			     cmd->pid,
-			     cmd->device->id,
-			     cmd->device->lun);
+	dprintkl(KERN_INFO, "eh_abort: (pid#%li) target=<%02i-%i> cmd=%p\n",
+		cmd->pid, cmd->device->id, cmd->device->lun, cmd);
 
 	dcb = find_dcb(acb, cmd->device->id, cmd->device->lun);
 	if (!dcb) {
-		dprintkl(KERN_DEBUG, "abort - no DCB found");
+		dprintkl(KERN_DEBUG, "eh_abort: No such device\n");
 		return FAILED;
 	}
 
@@ -1713,32 +1382,31 @@
 		pci_unmap_srb(acb, srb);
 		free_tag(dcb, srb);
 		srb_free_insert(acb, srb);
-		dprintkl(KERN_DEBUG, "abort - command found in waiting commands queue");
+		dprintkl(KERN_DEBUG, "eh_abort: Command was waiting\n");
 		cmd->result = DID_ABORT << 16;
 		return SUCCESS;
 	}
 	srb = find_cmd(cmd, &dcb->srb_going_list);
 	if (srb) {
-		dprintkl(KERN_DEBUG, "abort - command currently in progress");
+		dprintkl(KERN_DEBUG, "eh_abort: Command in progress");
 		/* XXX: Should abort the command here */
 	} else {
-		dprintkl(KERN_DEBUG, "abort - command not found");
+		dprintkl(KERN_DEBUG, "eh_abort: Command not found");
 	}
 	return FAILED;
 }
 
 
 /* SDTR */
-static
-void build_sdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
+static void build_sdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
 		struct ScsiReqBlk *srb)
 {
 	u8 *ptr = srb->msgout_buf + srb->msg_count;
 	if (srb->msg_count > 1) {
 		dprintkl(KERN_INFO,
-		       "Build_SDTR: msgout_buf BUSY (%i: %02x %02x)\n",
-		       srb->msg_count, srb->msgout_buf[0],
-		       srb->msgout_buf[1]);
+			"build_sdtr: msgout_buf BUSY (%i: %02x %02x)\n",
+			srb->msg_count, srb->msgout_buf[0],
+			srb->msgout_buf[1]);
 		return;
 	}
 	if (!(dcb->dev_mode & NTC_DO_SYNC_NEGO)) {
@@ -1754,25 +1422,21 @@
 	*ptr++ = dcb->sync_offset;	/* Transfer period (max. REQ/ACK dist) */
 	srb->msg_count += 5;
 	srb->state |= SRB_DO_SYNC_NEGO;
-	TRACEPRINTF("S *");
 }
 
 
-/* SDTR */
-static
-void build_wdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
+/* WDTR */
+static void build_wdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
 		struct ScsiReqBlk *srb)
 {
-	u8 wide =
-	    ((dcb->dev_mode & NTC_DO_WIDE_NEGO) & (acb->
-						   config & HCC_WIDE_CARD))
-	    ? 1 : 0;
+	u8 wide = ((dcb->dev_mode & NTC_DO_WIDE_NEGO) &
+		   (acb->config & HCC_WIDE_CARD)) ? 1 : 0;
 	u8 *ptr = srb->msgout_buf + srb->msg_count;
 	if (srb->msg_count > 1) {
 		dprintkl(KERN_INFO,
-		       "Build_WDTR: msgout_buf BUSY (%i: %02x %02x)\n",
-		       srb->msg_count, srb->msgout_buf[0],
-		       srb->msgout_buf[1]);
+			"build_wdtr: msgout_buf BUSY (%i: %02x %02x)\n",
+			srb->msg_count, srb->msgout_buf[0],
+			srb->msgout_buf[1]);
 		return;
 	}
 	*ptr++ = MSG_EXTENDED;	/* (01h) */
@@ -1781,7 +1445,6 @@
 	*ptr++ = wide;
 	srb->msg_count += 4;
 	srb->state |= SRB_DO_WIDE_NEGO;
-	TRACEPRINTF("W *");
 }
 
 
@@ -1809,7 +1472,7 @@
 void selection_timeout_missed(unsigned long ptr)
 {
 	unsigned long flags;
-	struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *) ptr;
+	struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)ptr;
 	struct ScsiReqBlk *srb;
 	dprintkl(KERN_DEBUG, "Chip forgot to produce SelTO IRQ!\n");
 	if (!acb->active_dcb || !acb->active_dcb->active_srb) {
@@ -1818,39 +1481,30 @@
 	}
 	DC395x_LOCK_IO(acb->scsi_host, flags);
 	srb = acb->active_dcb->active_srb;
-	TRACEPRINTF("N/TO *");
 	disconnect(acb);
 	DC395x_UNLOCK_IO(acb->scsi_host, flags);
 }
 #endif
 
 
-/*
- * scsiio
- *		DC395x_DoWaitingSRB    srb_done 
- *		send_srb         request_sense
- */
-static
-u8 start_scsi(struct AdapterCtlBlk * acb, struct DeviceCtlBlk * dcb,
-	      struct ScsiReqBlk * srb)
+static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
+		struct ScsiReqBlk* srb)
 {
 	u16 s_stat2, return_code;
 	u8 s_stat, scsicommand, i, identify_message;
 	u8 *ptr;
+	dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> srb=%p\n",
+		srb->cmd->pid, dcb->target_id, dcb->target_lun, srb);
 
-	dprintkdbg(DBG_0, "start_scsi..............\n");
 	srb->tag_number = TAG_NONE;	/* acb->tag_max_num: had error read in eeprom */
 
 	s_stat = DC395x_read8(acb, TRM_S1040_SCSI_SIGNAL);
 	s_stat2 = 0;
 	s_stat2 = DC395x_read16(acb, TRM_S1040_SCSI_STATUS);
-	TRACEPRINTF("Start %02x *", s_stat);
 #if 1
 	if (s_stat & 0x20 /* s_stat2 & 0x02000 */ ) {
-		dprintkdbg(DBG_KG,
-		       "StartSCSI: pid %li(%02i-%i): BUSY %02x %04x\n",
-		       srb->cmd->pid, dcb->target_id, dcb->target_lun,
-		       s_stat, s_stat2);
+		dprintkdbg(DBG_KG, "start_scsi: (pid#%li) BUSY %02x %04x\n",
+			srb->cmd->pid, s_stat, s_stat2);
 		/*
 		 * Try anyway?
 		 *
@@ -1861,41 +1515,32 @@
 		 * Instead let this fail and have the timer make sure the command is 
 		 * tried again after a short time
 		 */
-		TRACEPRINTF("^*");
 		/*selto_timer (acb); */
-		/*monitor_next_irq = 1; */
 		return 1;
 	}
 #endif
 	if (acb->active_dcb) {
-		dprintkl(KERN_DEBUG, "We try to start a SCSI command (%li)!\n",
-		       srb->cmd->pid);
-		dprintkl(KERN_DEBUG, "While another one (%li) is active!!\n",
-		       (acb->active_dcb->active_srb ? acb->active_dcb->
-			active_srb->cmd->pid : 0));
-		TRACEOUT(" %s\n", srb->debugtrace);
-		if (acb->active_dcb->active_srb)
-			TRACEOUT(" %s\n",
-				 acb->active_dcb->active_srb->debugtrace);
+		dprintkl(KERN_DEBUG, "start_scsi: (pid#%li) Attempt to start a"
+			"command while another command (pid#%li) is active.",
+			srb->cmd->pid,
+			acb->active_dcb->active_srb ?
+			    acb->active_dcb->active_srb->cmd->pid : 0);
 		return 1;
 	}
 	if (DC395x_read16(acb, TRM_S1040_SCSI_STATUS) & SCSIINTERRUPT) {
-		dprintkdbg(DBG_KG,
-		       "StartSCSI failed (busy) for pid %li(%02i-%i)\n",
-		       srb->cmd->pid, dcb->target_id, dcb->target_lun);
-		TRACEPRINTF("°*");
+		dprintkdbg(DBG_KG, "start_scsi: (pid#%li) Failed (busy)\n",
+			srb->cmd->pid);
 		return 1;
 	}
 	/* Allow starting of SCSI commands half a second before we allow the mid-level
 	 * to queue them again after a reset */
 	if (time_before(jiffies, acb->scsi_host->last_reset - HZ / 2)) {
-		dprintkdbg(DBG_KG, 
-		       "We were just reset and don't accept commands yet!\n");
+		dprintkdbg(DBG_KG, "start_scsi: Refuse cmds (reset wait)\n");
 		return 1;
 	}
 
 	/* Flush FIFO */
-	clear_fifo(acb, "Start");
+	clear_fifo(acb, "start_scsi");
 	DC395x_write8(acb, TRM_S1040_SCSI_HOSTID, acb->scsi_host->this_id);
 	DC395x_write8(acb, TRM_S1040_SCSI_TARGETID, dcb->target_id);
 	DC395x_write8(acb, TRM_S1040_SCSI_SYNC, dcb->sync_period);
@@ -1939,9 +1584,7 @@
 		}
 		srb->msg_count = 0;
 	}
-	/* 
-	 ** Send identify message   
-	 */
+	/* Send identify message */
 	DC395x_write8(acb, TRM_S1040_SCSI_FIFO, identify_message);
 
 	scsicommand = SCMD_SEL_ATN;
@@ -1958,37 +1601,29 @@
 			tag_number++;
 		}
 		if (tag_number >= dcb->max_command) {
-			dprintkl(KERN_WARNING,
-			       "Start_SCSI: Out of tags for pid %li (%i-%i)\n",
-			       srb->cmd->pid, srb->cmd->device->id,
-			       srb->cmd->device->lun);
+			dprintkl(KERN_WARNING, "start_scsi: (pid#%li) "
+				"Out of tags target=<%02i-%i>)\n",
+				srb->cmd->pid, srb->cmd->device->id,
+				srb->cmd->device->lun);
 			srb->state = SRB_READY;
 			DC395x_write16(acb, TRM_S1040_SCSI_CONTROL,
 				       DO_HWRESELECT);
 			return 1;
 		}
-		/* 
-		 ** Send Tag id
-		 */
+		/* Send Tag id */
 		DC395x_write8(acb, TRM_S1040_SCSI_FIFO, MSG_SIMPLE_QTAG);
 		DC395x_write8(acb, TRM_S1040_SCSI_FIFO, tag_number);
 		dcb->tag_mask |= tag_mask;
 		srb->tag_number = tag_number;
-		TRACEPRINTF("Tag %i *", tag_number);
-
 		scsicommand = SCMD_SEL_ATN3;
 		srb->state = SRB_START_;
 	}
 #endif
 /*polling:*/
-	/*
-	 *          Send CDB ..command block .........                     
-	 */
-	dprintkdbg(DBG_KG, 
-	       "StartSCSI (pid %li) %02x (%i-%i): Tag %i\n",
-	       srb->cmd->pid, srb->cmd->cmnd[0],
-	       srb->cmd->device->id, srb->cmd->device->lun,
-	       srb->tag_number);
+	/* Send CDB ..command block ......... */
+	dprintkdbg(DBG_KG, "start_scsi: (pid#%li) <%02i-%i> cmnd=0x%02x tag=%i\n",
+		srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun,
+		srb->cmd->cmnd[0], srb->tag_number);
 	if (srb->flag & AUTO_REQSENSE) {
 		DC395x_write8(acb, TRM_S1040_SCSI_FIFO, REQUEST_SENSE);
 		DC395x_write8(acb, TRM_S1040_SCSI_FIFO, (dcb->target_lun << 5));
@@ -1998,7 +1633,7 @@
 			      sizeof(srb->cmd->sense_buffer));
 		DC395x_write8(acb, TRM_S1040_SCSI_FIFO, 0);
 	} else {
-		ptr = (u8 *) srb->cmd->cmnd;
+		ptr = (u8 *)srb->cmd->cmnd;
 		for (i = 0; i < srb->cmd->cmd_len; i++)
 			DC395x_write8(acb, TRM_S1040_SCSI_FIFO, *ptr++);
 	}
@@ -2011,10 +1646,8 @@
 		 * we caught an interrupt (must be reset or reselection ... )
 		 * : Let's process it first!
 		 */
-		dprintkdbg(DBG_0, "Debug: StartSCSI failed (busy) for pid %li(%02i-%i)!\n",
+		dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> Failed - busy\n",
 			srb->cmd->pid, dcb->target_id, dcb->target_lun);
-		/*clear_fifo (acb, "Start2"); */
-		/*DC395x_write16 (TRM_S1040_SCSI_CONTROL, DO_HWRESELECT | DO_DATALATCH); */
 		srb->state = SRB_READY;
 		free_tag(dcb, srb);
 		srb->msg_count = 0;
@@ -2032,23 +1665,13 @@
 		/* it's important for atn stop */
 		DC395x_write16(acb, TRM_S1040_SCSI_CONTROL,
 			       DO_DATALATCH | DO_HWRESELECT);
-		/*
-		 ** SCSI command
-		 */
-		TRACEPRINTF("%02x *", scsicommand);
+		/* SCSI command */
 		DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, scsicommand);
 	}
 	return return_code;
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *		init_adapter
- ********************************************************************
- */
-
 /**
  * dc395x_handle_interrupt - Handle an interrupt that has been confirmed to
  *                           have been triggered for this card.
@@ -2056,37 +1679,29 @@
  * @acb:	 a pointer to the adpter control block
  * @scsi_status: the status return when we checked the card
  **/
-static void dc395x_handle_interrupt(struct AdapterCtlBlk *acb, u16 scsi_status)
+static void dc395x_handle_interrupt(struct AdapterCtlBlk *acb,
+		u16 scsi_status)
 {
 	struct DeviceCtlBlk *dcb;
 	struct ScsiReqBlk *srb;
 	u16 phase;
 	u8 scsi_intstatus;
 	unsigned long flags;
-	void (*dc395x_statev) (struct AdapterCtlBlk *, struct ScsiReqBlk *,
-			       u16 *);
+	void (*dc395x_statev)(struct AdapterCtlBlk *, struct ScsiReqBlk *, 
+			      u16 *);
 
 	DC395x_LOCK_IO(acb->scsi_host, flags);
 
 	/* This acknowledges the IRQ */
 	scsi_intstatus = DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS);
 	if ((scsi_status & 0x2007) == 0x2002)
-		dprintkl(KERN_DEBUG, "COP after COP completed? %04x\n",
-		       scsi_status);
-#if 1				/*def DBG_0 */
-	if (monitor_next_irq) {
-		dprintkl(KERN_INFO,
-		       "status=%04x intstatus=%02x\n", scsi_status,
-		       scsi_intstatus);
-		monitor_next_irq--;
-	}
-#endif
-	/*DC395x_ACB_LOCK(acb,acb_flags); */
+		dprintkl(KERN_DEBUG,
+			"COP after COP completed? %04x\n", scsi_status);
 	if (debug_enabled(DBG_KG)) {
 		if (scsi_intstatus & INT_SELTIMEOUT)
-		dprintkdbg(DBG_KG, "Sel Timeout IRQ\n");
+			dprintkdbg(DBG_KG, "handle_interrupt: Selection timeout\n");
 	}
-	/*dprintkl(KERN_DEBUG, "DC395x_IRQ: intstatus = %02x ", scsi_intstatus); */
+	/*dprintkl(KERN_DEBUG, "handle_interrupt: intstatus = 0x%02x ", scsi_intstatus); */
 
 	if (timer_pending(&acb->selto_timer))
 		del_timer(&acb->selto_timer);
@@ -2111,8 +1726,8 @@
 		dcb = acb->active_dcb;
 		if (!dcb) {
 			dprintkl(KERN_DEBUG,
-			       "Oops: BusService (%04x %02x) w/o ActiveDCB!\n",
-			       scsi_status, scsi_intstatus);
+				"Oops: BusService (%04x %02x) w/o ActiveDCB!\n",
+				scsi_status, scsi_intstatus);
 			goto out_unlock;
 		}
 		srb = dcb->active_srb;
@@ -2120,12 +1735,10 @@
 			dprintkdbg(DBG_0, "MsgOut Abort Device.....\n");
 			enable_msgout_abort(acb, srb);
 		}
-		/*
-		 ************************************************************
-		 * software sequential machine
-		 ************************************************************
-		 */
-		phase = (u16) srb->scsi_phase;
+
+		/* software sequential machine */
+		phase = (u16)srb->scsi_phase;
+
 		/* 
 		 * 62037 or 62137
 		 * call  dc395x_scsi_phase0[]... "phase entry"
@@ -2139,22 +1752,20 @@
 		/* nop0,		phase:5 PH_BUS_FREE .. initial phase */
 		/* msgout_phase0,	phase:6 */
 		/* msgin_phase0,	phase:7 */
-		dc395x_statev = (void *) dc395x_scsi_phase0[phase];
+		dc395x_statev = dc395x_scsi_phase0[phase];
 		dc395x_statev(acb, srb, &scsi_status);
+
 		/* 
-		 *$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 
-		 *
-		 *        if there were any exception occured
-		 *        scsi_status will be modify to bus free phase
-		 * new scsi_status transfer out from ... previous dc395x_statev
-		 *
-		 *$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 
+		 * if there were any exception occured scsi_status
+		 * will be modify to bus free phase new scsi_status
+		 * transfer out from ... previous dc395x_statev
 		 */
 		srb->scsi_phase = scsi_status & PHASEMASK;
-		phase = (u16) scsi_status & PHASEMASK;
+		phase = (u16)scsi_status & PHASEMASK;
+
 		/* 
-		 * call  dc395x_scsi_phase1[]... "phase entry"
-		 * handle every phase do transfer
+		 * call  dc395x_scsi_phase1[]... "phase entry" handle
+		 * every phase to do transfer
 		 */
 		/* data_out_phase1,	phase:0 */
 		/* data_in_phase1,	phase:1 */
@@ -2164,30 +1775,22 @@
 		/* nop1,		phase:5 PH_BUS_FREE .. initial phase */
 		/* msgout_phase1,	phase:6 */
 		/* msgin_phase1,	phase:7 */
-		dc395x_statev = (void *) dc395x_scsi_phase1[phase];
+		dc395x_statev = dc395x_scsi_phase1[phase];
 		dc395x_statev(acb, srb, &scsi_status);
 	}
       out_unlock:
 	DC395x_UNLOCK_IO(acb->scsi_host, flags);
-	return;
 }
 
 
-static
-irqreturn_t dc395x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dc395x_interrupt(int irq, void *dev_id,
+		struct pt_regs *regs)
 {
 	struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)dev_id;
 	u16 scsi_status;
 	u8 dma_status;
 	irqreturn_t handled = IRQ_NONE;
 
-	dprintkdbg(DBG_0, "dc395x_interrupt..............\n");
-#if debug_enabled(DBG_RECURSION)
-        if (dbg_in_driver++ > NORM_REC_LVL) {
-		dprintkl(KERN_DEBUG, "%i interrupt recursion?\n", dbg_in_driver);
-	}
-#endif
-
 	/*
 	 * Check for pending interupt
 	 */
@@ -2200,7 +1803,7 @@
 	}
 	else if (dma_status & 0x20) {
 		/* Error from the DMA engine */
-		dprintkl(KERN_INFO, "Interrupt from DMA engine: %02x!\n", dma_status);
+		dprintkl(KERN_INFO, "Interrupt from DMA engine: 0x%02x!\n", dma_status);
 #if 0
 		dprintkl(KERN_INFO, "This means DMA error! Try to handle ...\n");
 		if (acb->active_dcb) {
@@ -2216,135 +1819,75 @@
 		handled = IRQ_HANDLED;
 	}
 
-#if debug_enabled(DBG_RECURSION)
-	dbg_in_driver--
-#endif
 	return handled;
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *	msgout_phase0: one of dc395x_scsi_phase0[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase0[phase]
- *			           if phase =6
- ********************************************************************
- */
-static
-void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		    u16 * pscsi_status)
+static void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
 {
-	dprintkdbg(DBG_0, "msgout_phase0.....\n");
-	if (srb->state & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT)) {
+	dprintkdbg(DBG_0, "msgout_phase0: (pid#%li)\n", srb->cmd->pid);
+	if (srb->state & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT))
 		*pscsi_status = PH_BUS_FREE;	/*.. initial phase */
-	}
+
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
 	srb->state &= ~SRB_MSGOUT;
-	TRACEPRINTF("MOP0 *");
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *	msgout_phase1: one of dc395x_scsi_phase0[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase0[phase]
- *					if phase =6	    
- ********************************************************************
- */
-static
-void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		    u16 * pscsi_status)
+static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
 {
 	u16 i;
 	u8 *ptr;
-	struct DeviceCtlBlk *dcb;
+	dprintkdbg(DBG_0, "msgout_phase1: (pid#%li)\n", srb->cmd->pid);
 
-	dprintkdbg(DBG_0, "msgout_phase1..............\n");
-	TRACEPRINTF("MOP1*");
-	dcb = acb->active_dcb;
-	clear_fifo(acb, "MOP1");
+	clear_fifo(acb, "msgout_phase1");
 	if (!(srb->state & SRB_MSGOUT)) {
 		srb->state |= SRB_MSGOUT;
-		dprintkl(KERN_DEBUG, "Debug: pid %li: MsgOut Phase unexpected.\n", srb->cmd->pid);	/* So what ? */
+		dprintkl(KERN_DEBUG,
+			"msgout_phase1: (pid#%li) Phase unexpected\n",
+			srb->cmd->pid);	/* So what ? */
 	}
 	if (!srb->msg_count) {
-		dprintkdbg(DBG_0, "Debug: pid %li: NOP Msg (no output message there).\n",
+		dprintkdbg(DBG_0, "msgout_phase1: (pid#%li) NOP msg\n",
 			srb->cmd->pid);
 		DC395x_write8(acb, TRM_S1040_SCSI_FIFO, MSG_NOP);
 		DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
 		DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT);
-		TRACEPRINTF("\\*");
-		TRACEOUT(" %s\n", srb->debugtrace);
 		return;
 	}
-	ptr = (u8 *) srb->msgout_buf;
-	TRACEPRINTF("(*");
-	/*dprintkl(KERN_DEBUG, "Send msg: "); print_msg (ptr, srb->msg_count); */
-	/*dprintkl(KERN_DEBUG, "MsgOut: "); */
-	for (i = 0; i < srb->msg_count; i++) {
-		TRACEPRINTF("%02x *", *ptr);
+	ptr = (u8 *)srb->msgout_buf;
+	for (i = 0; i < srb->msg_count; i++)
 		DC395x_write8(acb, TRM_S1040_SCSI_FIFO, *ptr++);
-	}
-	TRACEPRINTF(")*");
 	srb->msg_count = 0;
-	/*printk("\n"); */
-	if (/*(dcb->flag & ABORT_DEV_) && */
-	    (srb->msgout_buf[0] == MSG_ABORT))
+	if (srb->msgout_buf[0] == MSG_ABORT)
 		srb->state = SRB_ABORT_SENT;
 
-	/*1.25 */
-	/*DC395x_write16 (TRM_S1040_SCSI_CONTROL, DO_DATALATCH); *//* it's important for atn stop */
-	/*
-	 ** SCSI command 
-	 */
-	/*TRACEPRINTF (".*"); */
 	DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT);
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *	command_phase0: one of dc395x_scsi_phase0[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase0[phase]
- *				if phase =2 
- ********************************************************************
- */
-static
-void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		    u16 * pscsi_status)
+static void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
 {
-	TRACEPRINTF("COP0 *");
-	/*1.25 */
-	/*clear_fifo (acb, COP0); */
+	dprintkdbg(DBG_0, "command_phase0: (pid#%li)\n", srb->cmd->pid);
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *	command_phase1: one of dc395x_scsi_phase1[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase1[phase]
- *				if phase =2    	 
- ********************************************************************
- */
-static
-void command_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		    u16 * pscsi_status)
+static void command_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
 {
 	struct DeviceCtlBlk *dcb;
 	u8 *ptr;
 	u16 i;
+	dprintkdbg(DBG_0, "command_phase1: (pid#%li)\n", srb->cmd->pid);
 
-	dprintkdbg(DBG_0, "command_phase1..............\n");
-	TRACEPRINTF("COP1*");
-	clear_fifo(acb, "COP1");
+	clear_fifo(acb, "command_phase1");
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_CLRATN);
 	if (!(srb->flag & AUTO_REQSENSE)) {
-		ptr = (u8 *) srb->cmd->cmnd;
+		ptr = (u8 *)srb->cmd->cmnd;
 		for (i = 0; i < srb->cmd->cmd_len; i++) {
 			DC395x_write8(acb, TRM_S1040_SCSI_FIFO, *ptr);
 			ptr++;
@@ -2364,22 +1907,24 @@
 	/* it's important for atn stop */
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
 	/* SCSI command */
-	TRACEPRINTF(".*");
 	DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT);
 }
 
 
-/* Do sanity checks for S/G list */
-static inline void check_sg_list(struct ScsiReqBlk *srb)
+/*
+ * Verify that the remaining space in the hw sg lists is the same as
+ * the count of remaining bytes in srb->total_xfer_length
+ */
+static void sg_verify_length(struct ScsiReqBlk *srb)
 {
-	if (debug_enabled(DBG_SGPARANOIA)) {
+	if (debug_enabled(DBG_SG)) {
 		unsigned len = 0;
 		unsigned idx = srb->sg_index;
 		struct SGentry *psge = srb->segment_x + idx;
 		for (; idx < srb->sg_count; psge++, idx++)
 			len += psge->length;
 		if (len != srb->total_xfer_length)
-			dprintkdbg(DBG_SGPARANOIA,
+			dprintkdbg(DBG_SG,
 			       "Inconsistent SRB S/G lengths (Tot=%i, Count=%i) !!\n",
 			       srb->total_xfer_length, len);
 	}			       
@@ -2390,75 +1935,90 @@
  * Compute the next Scatter Gather list index and adjust its length
  * and address if necessary; also compute virt_addr
  */
-static void update_sg_list(struct ScsiReqBlk *srb, u32 left)
+static void sg_update_list(struct ScsiReqBlk *srb, u32 left)
 {
-	struct SGentry *psge;
-	u32 xferred = 0;
 	u8 idx;
-	Scsi_Cmnd *cmd = srb->cmd;
 	struct scatterlist *sg;
+	Scsi_Cmnd *cmd = srb->cmd;
 	int segment = cmd->use_sg;
+	u32 xferred = srb->total_xfer_length - left; /* bytes transfered */
+	struct SGentry *psge = srb->segment_x + srb->sg_index;
 
-	dprintkdbg(DBG_KG, "Update SG: Total %i, Left %i\n",
-	       srb->total_xfer_length, left);
-	check_sg_list(srb);
-	psge = srb->segment_x + srb->sg_index;
-	/* data that has already been transferred */
-	xferred = srb->total_xfer_length - left;
-	if (srb->total_xfer_length != left) {
-		/*check_sg_list_TX (srb, xferred); */
-		/* Remaining */
-		srb->total_xfer_length = left;
-		/* parsing from last time disconnect SGIndex */
-		for (idx = srb->sg_index; idx < srb->sg_count; idx++) {
+	dprintkdbg(DBG_0,
+		"sg_update_list: Transfered %i of %i bytes, %i remain\n",
+		xferred, srb->total_xfer_length, left);
+	if (xferred == 0) {
+		/* nothing to update since we did not transfer any data */
+		return;
+	}
+
+	sg_verify_length(srb);
+	srb->total_xfer_length = left;	/* update remaining count */
+	for (idx = srb->sg_index; idx < srb->sg_count; idx++) {
+		if (xferred >= psge->length) {
 			/* Complete SG entries done */
-			if (xferred >= psge->length)
-				xferred -= psge->length;
-			/* Partial SG entries done */
-			else {
-				psge->length -= xferred;	/* residue data length  */
-				psge->address += xferred;	/* residue data pointer */
-				srb->sg_index = idx;
-				pci_dma_sync_single(srb->dcb->
-						    acb->dev,
-						    srb->sg_bus_addr,
-						    sizeof(struct SGentry)
-						    *
-						    DC395x_MAX_SG_LISTENTRY,
-						    PCI_DMA_TODEVICE);
-				break;
-			}
-			psge++;
+			xferred -= psge->length;
+		} else {
+			/* Partial SG entry done */
+			psge->length -= xferred;
+			psge->address += xferred;
+			srb->sg_index = idx;
+			pci_dma_sync_single(srb->dcb->
+					    acb->dev,
+					    srb->sg_bus_addr,
+					    SEGMENTX_LEN,
+					    PCI_DMA_TODEVICE);
+			break;
 		}
-		check_sg_list(srb);
+		psge++;
 	}
-	/* We need the corresponding virtual address sg_to_virt */
-	/*dprintkl(KERN_DEBUG, "sg_to_virt: bus %08x -> virt ", psge->address); */
+	sg_verify_length(srb);
+
+	/* we need the corresponding virtual address */
 	if (!segment) {
 		srb->virt_addr += xferred;
-		/*printk("%p\n", srb->virt_addr); */
 		return;
 	}
+
 	/* We have to walk the scatterlist to find it */
-	sg = (struct scatterlist *) cmd->request_buffer;
+	sg = (struct scatterlist *)cmd->request_buffer;
 	while (segment--) {
-		/*printk("(%08x)%p ", BUS_ADDR(*sg), PAGE_ADDRESS(sg)); */
 		unsigned long mask =
-		    ~((unsigned long) sg->length - 1) & PAGE_MASK;
-		if ((BUS_ADDR(*sg) & mask) == (psge->address & mask)) {
-			srb->virt_addr = (PAGE_ADDRESS(sg)
+		    ~((unsigned long)sg->length - 1) & PAGE_MASK;
+		if ((sg_dma_address(sg) & mask) == (psge->address & mask)) {
+			srb->virt_addr = (page_address(sg->page)
 					   + psge->address -
 					   (psge->address & PAGE_MASK));
-			/*printk("%p\n", srb->virt_addr); */
 			return;
 		}
 		++sg;
 	}
-	dprintkl(KERN_ERR, "sg_to_virt failed!\n");
+
+	dprintkl(KERN_ERR, "sg_update_list: sg_to_virt failed\n");
 	srb->virt_addr = 0;
 }
 
 
+/*
+ * We have transfered a single byte (PIO mode?) and need to update
+ * the count of bytes remaining (total_xfer_length) and update the sg
+ * entry to either point to next byte in the current sg entry, or of
+ * already at the end to point to the start of the next sg entry
+ */
+static void sg_subtract_one(struct ScsiReqBlk *srb)
+{
+	srb->total_xfer_length--;
+	srb->segment_x[srb->sg_index].length--;
+	if (srb->total_xfer_length &&
+	    !srb->segment_x[srb->sg_index].length) {
+		if (debug_enabled(DBG_PIO))
+			printk(" (next segment)");
+		srb->sg_index++;
+		sg_update_list(srb, srb->total_xfer_length);
+	}
+}
+
+
 /* 
  * cleanup_after_transfer
  * 
@@ -2467,27 +2027,21 @@
  * Should probably also be called from other places
  * Best might be to call it in DataXXPhase0, if new phase will differ 
  */
-static
-void cleanup_after_transfer(struct AdapterCtlBlk *acb,
-			    struct ScsiReqBlk *srb)
+static void cleanup_after_transfer(struct AdapterCtlBlk *acb,
+		struct ScsiReqBlk *srb)
 {
-	TRACEPRINTF(" Cln*");
 	/*DC395x_write8 (TRM_S1040_DMA_STATUS, FORCEDMACOMP); */
 	if (DC395x_read16(acb, TRM_S1040_DMA_COMMAND) & 0x0001) {	/* read */
 		if (!(DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x40))
-			clear_fifo(acb, "ClnIn");
-
+			clear_fifo(acb, "cleanup/in");
 		if (!(DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT) & 0x80))
 			DC395x_write8(acb, TRM_S1040_DMA_CONTROL, CLRXFIFO);
 	} else {		/* write */
 		if (!(DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT) & 0x80))
 			DC395x_write8(acb, TRM_S1040_DMA_CONTROL, CLRXFIFO);
-
 		if (!(DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x40))
-			clear_fifo(acb, "ClnOut");
-
+			clear_fifo(acb, "cleanup/out");
 	}
-	/*1.25 */
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
 }
 
@@ -2497,26 +2051,16 @@
  * Seems to be needed for unknown reasons; could be a hardware bug :-(
  */
 #define DC395x_LASTPIO 4
-/*
- ********************************************************************
- * scsiio
- *	data_out_phase0: one of dc395x_scsi_phase0[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase0[phase]
- *				if phase =0 
- ********************************************************************
- */
-static
-void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		     u16 * pscsi_status)
+
+
+static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
 {
-	u16 scsi_status;
-	u32 d_left_counter = 0;
 	struct DeviceCtlBlk *dcb = srb->dcb;
-
-	dprintkdbg(DBG_0, "data_out_phase0.....\n");
-	TRACEPRINTF("DOP0*");
-	dcb = srb->dcb;
-	scsi_status = *pscsi_status;
+	u16 scsi_status = *pscsi_status;
+	u32 d_left_counter = 0;
+	dprintkdbg(DBG_0, "data_out_phase0: (pid#%li) <%02i-%i>\n",
+		srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun);
 
 	/*
 	 * KG: We need to drain the buffers before we draw any conclusions!
@@ -2530,12 +2074,14 @@
 	 * KG: Stop DMA engine pushing more data into the SCSI FIFO
 	 * If we need more data, the DMA SG list will be freshly set up, anyway
 	 */
-	dprintkdbg(DBG_PIO, "DOP0: DMA_FCNT: %02x, DMA_FSTAT: %02x, SCSI_FCNT: %02x, CTR %06x, stat %04x, Tot: %06x\n",
-	       DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),
-	       DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT),
-	       DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),
-	       DC395x_read32(acb, TRM_S1040_SCSI_COUNTER), scsi_status,
-	       srb->total_xfer_length);
+	dprintkdbg(DBG_PIO, "data_out_phase0: "
+		"DMA{fifcnt=0x%02x fifostat=0x%02x} "
+		"SCSI{fifocnt=0x%02x cnt=0x%06x status=0x%04x} total=0x%06x\n",
+		DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),
+		DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT),
+		DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),
+		DC395x_read32(acb, TRM_S1040_SCSI_COUNTER), scsi_status,
+		srb->total_xfer_length);
 	DC395x_write8(acb, TRM_S1040_DMA_CONTROL, STOPDMAXFER | CLRXFIFO);
 
 	if (!(srb->state & SRB_XFERPAD)) {
@@ -2554,31 +2100,21 @@
 			 * if there was some data left in SCSI FIFO
 			 */
 			d_left_counter =
-			    (u32) (DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) &
-				   0x1F);
+			    (u32)(DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) &
+				  0x1F);
 			if (dcb->sync_period & WIDE_SYNC)
 				d_left_counter <<= 1;
 
-			dprintkdbg(DBG_KG,
-			       "Debug: SCSI FIFO contains %i %s in DOP0\n",
-			       DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),
-			       (dcb->
-				sync_period & WIDE_SYNC) ? "words" :
-			       "bytes");
-			dprintkdbg(DBG_KG,
-			       "SCSI FIFOCNT %02x, SCSI CTR %08x\n",
-			       DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),
-			       DC395x_read32(acb, TRM_S1040_SCSI_COUNTER));
-			dprintkdbg(DBG_KG,
-			       "DMA FIFOCNT %04x, FIFOSTAT %02x, DMA CTR %08x\n",
-			       DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),
-			       DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT),
-			       DC395x_read32(acb, TRM_S1040_DMA_CXCNT));
-
-			/*
-			 * if WIDE scsi SCSI FIFOCNT unit is word !!!
-			 * so need to *= 2
-			 */
+			dprintkdbg(DBG_KG, "data_out_phase0: FIFO contains %i %s\n"
+				"SCSI{fifocnt=0x%02x cnt=0x%08x} "
+				"DMA{fifocnt=0x%04x cnt=0x%02x ctr=0x%08x}\n",
+				DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),
+				(dcb->sync_period & WIDE_SYNC) ? "words" : "bytes",
+				DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),
+				DC395x_read32(acb, TRM_S1040_SCSI_COUNTER),
+				DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),
+				DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT),
+				DC395x_read32(acb, TRM_S1040_DMA_CXCNT));
 		}
 		/*
 		 * calculate all the residue data that not yet tranfered
@@ -2592,16 +2128,16 @@
 		if (srb->total_xfer_length > DC395x_LASTPIO)
 			d_left_counter +=
 			    DC395x_read32(acb, TRM_S1040_SCSI_COUNTER);
-		TRACEPRINTF("%06x *", d_left_counter);
 
 		/* Is this a good idea? */
-		/*clear_fifo (acb, "DOP1"); */
+		/*clear_fifo(acb, "DOP1"); */
 		/* KG: What is this supposed to be useful for? WIDE padding stuff? */
 		if (d_left_counter == 1 && dcb->sync_period & WIDE_SYNC
 		    && srb->cmd->request_bufflen % 2) {
 			d_left_counter = 0;
-			dprintkl(KERN_INFO, "DOP0: Discard 1 byte. (%02x)\n",
-			       scsi_status);
+			dprintkl(KERN_INFO,
+				"data_out_phase0: Discard 1 byte (0x%02x)\n",
+				scsi_status);
 		}
 		/*
 		 * KG: Oops again. Same thinko as above: The SCSI might have been
@@ -2613,19 +2149,9 @@
 		 * KG: This is nonsense: We have been WRITING data to the bus
 		 * If the SCSI engine has no bytes left, how should the DMA engine?
 		 */
-		if ((d_left_counter ==
-		     0) /*|| (scsi_status & SCSIXFERCNT_2_ZERO) ) */ ) {
-			/*
-			 * int ctr = 6000000; u8 TempDMAstatus;
-			 * do
-			 * {
-			 *  TempDMAstatus = DC395x_read8(acb, TRM_S1040_DMA_STATUS);
-			 * } while( !(TempDMAstatus & DMAXFERCOMP) && --ctr);
-			 * if (ctr < 6000000-1) dprintkl(KERN_DEBUG, "DMA should be complete ... in DOP1\n");
-			 * if (!ctr) dprintkl(KERN_ERR, "Deadlock in DataOutPhase0 !!\n");
-			 */
+		if (d_left_counter == 0) {
 			srb->total_xfer_length = 0;
-		} else {	/* Update SG list         */
+		} else {
 			/*
 			 * if transfer not yet complete
 			 * there were some data residue in SCSI FIFO or
@@ -2635,18 +2161,18 @@
 			    srb->total_xfer_length - d_left_counter;
 			const int diff =
 			    (dcb->sync_period & WIDE_SYNC) ? 2 : 1;
-			update_sg_list(srb, d_left_counter);
+			sg_update_list(srb, d_left_counter);
 			/* KG: Most ugly hack! Apparently, this works around a chip bug */
 			if ((srb->segment_x[srb->sg_index].length ==
 			     diff && srb->cmd->use_sg)
 			    || ((oldxferred & ~PAGE_MASK) ==
 				(PAGE_SIZE - diff))
 			    ) {
-				dprintkl(KERN_INFO,
-				       "Work around chip bug (%i)?\n", diff);
+				dprintkl(KERN_INFO, "data_out_phase0: "
+					"Work around chip bug (%i)?\n", diff);
 				d_left_counter =
 				    srb->total_xfer_length - diff;
-				update_sg_list(srb, d_left_counter);
+				sg_update_list(srb, d_left_counter);
 				/*srb->total_xfer_length -= diff; */
 				/*srb->virt_addr += diff; */
 				/*if (srb->cmd->use_sg) */
@@ -2654,71 +2180,30 @@
 			}
 		}
 	}
-#if 0
-	if (!(DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x40))
-		dprintkl(KERN_DEBUG,
-			"DOP0(%li): %i bytes in SCSI FIFO! (Clear!)\n",
-			srb->cmd->pid,
-			DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x1f);
-#endif
-	/*clear_fifo (acb, "DOP0"); */
-	/*DC395x_write8 (TRM_S1040_DMA_CONTROL, CLRXFIFO | ABORTXFER); */
-#if 1
 	if ((*pscsi_status & PHASEMASK) != PH_DATA_OUT) {
-		/*dprintkl(KERN_DEBUG, "Debug: Clean up after Data Out ...\n"); */
 		cleanup_after_transfer(acb, srb);
 	}
-#endif
-	TRACEPRINTF(".*");
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *	data_out_phase1: one of dc395x_scsi_phase0[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase0[phase]
- *				if phase =0    
- *		62037
- ********************************************************************
- */
-static
-void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		     u16 * pscsi_status)
+static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
 {
-
-	dprintkdbg(DBG_0, "data_out_phase1.....\n");
-	/*1.25 */
-	TRACEPRINTF("DOP1*");
-	clear_fifo(acb, "DOP1");
-	/*
-	 ** do prepare befor transfer when data out phase
-	 */
+	dprintkdbg(DBG_0, "data_out_phase1: (pid#%li) <%02i-%i>\n",
+		srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun);
+	clear_fifo(acb, "data_out_phase1");
+	/* do prepare before transfer when data out phase */
 	data_io_transfer(acb, srb, XFERDATAOUT);
-	TRACEPRINTF(".*");
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *	data_in_phase0: one of dc395x_scsi_phase1[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase1[phase]
- *				if phase =1  
- ********************************************************************
- */
-static
-void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		    u16 * pscsi_status)
+static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
 {
-	u16 scsi_status;
+	u16 scsi_status = *pscsi_status;
 	u32 d_left_counter = 0;
-	/*struct DeviceCtlBlk*   dcb = srb->dcb; */
-	/*u8 bval; */
-
-	dprintkdbg(DBG_0, "data_in_phase0..............\n");
-	TRACEPRINTF("DIP0*");
-	scsi_status = *pscsi_status;
+	dprintkdbg(DBG_0, "data_in_phase0: (pid#%li) <%02i-%i>\n",
+		srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun);
 
 	/*
 	 * KG: DataIn is much more tricky than DataOut. When the device is finished
@@ -2735,10 +2220,8 @@
 	 */
 	if (!(srb->state & SRB_XFERPAD)) {
 		if (scsi_status & PARITYERROR) {
-			dprintkl(KERN_INFO,
-			       "Parity Error (pid %li, target %02i-%i)\n",
-			       srb->cmd->pid, srb->cmd->device->id,
-			       srb->cmd->device->lun);
+			dprintkl(KERN_INFO, "data_in_phase0: (pid#%li) "
+				"Parity Error\n", srb->cmd->pid);
 			srb->status |= PARITY_ERROR;
 		}
 		/*
@@ -2751,7 +2234,7 @@
 #if 0
 			int ctr = 6000000;
 			dprintkl(KERN_DEBUG,
-			       "DIP0: Wait for DMA FIFO to flush ...\n");
+				"DIP0: Wait for DMA FIFO to flush ...\n");
 			/*DC395x_write8  (TRM_S1040_DMA_CONTROL, STOPDMAXFER); */
 			/*DC395x_write32 (TRM_S1040_SCSI_COUNTER, 7); */
 			/*DC395x_write8  (TRM_S1040_SCSI_COMMAND, SCMD_DMA_IN); */
@@ -2766,73 +2249,56 @@
 				       "Deadlock in DIP0 waiting for DMA FIFO empty!!\n");
 			/*DC395x_write32 (TRM_S1040_SCSI_COUNTER, 0); */
 #endif
-			dprintkdbg(DBG_KG, "DIP0: DMA_FIFO: %02x %02x\n",
-			       DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),
-			       DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT));
+			dprintkdbg(DBG_KG, "data_in_phase0: "
+				"DMA{fifocnt=0x%02x fifostat=0x%02x}\n",
+				DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),
+				DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT));
 		}
 		/* Now: Check remainig data: The SCSI counters should tell us ... */
 		d_left_counter = DC395x_read32(acb, TRM_S1040_SCSI_COUNTER)
 		    + ((DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x1f)
 		       << ((srb->dcb->sync_period & WIDE_SYNC) ? 1 :
 			   0));
-
-		dprintkdbg(DBG_KG, "SCSI FIFO contains %i %s in DIP0\n",
-			  DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x1f,
-			  (srb->dcb->
-			  sync_period & WIDE_SYNC) ? "words" : "bytes");
-		dprintkdbg(DBG_KG, "SCSI FIFOCNT %02x, SCSI CTR %08x\n",
-			  DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),
-			  DC395x_read32(acb, TRM_S1040_SCSI_COUNTER));
-		dprintkdbg(DBG_KG, "DMA FIFOCNT %02x,%02x DMA CTR %08x\n",
-			  DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),
-			  DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT),
-			  DC395x_read32(acb, TRM_S1040_DMA_CXCNT));
-		dprintkdbg(DBG_KG, "Remaining: TotXfer: %i, SCSI FIFO+Ctr: %i\n",
-			  srb->total_xfer_length, d_left_counter);
+		dprintkdbg(DBG_KG, "data_in_phase0: "
+			"SCSI{fifocnt=0x%02x%s ctr=0x%08x} "
+			"DMA{fifocnt=0x%02x fifostat=0x%02x ctr=0x%08x} "
+			"Remain{totxfer=%i scsi_fifo+ctr=%i}\n",
+			DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),
+			(srb->dcb->sync_period & WIDE_SYNC) ? "words" : "bytes",
+			DC395x_read32(acb, TRM_S1040_SCSI_COUNTER),
+			DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),
+			DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT),
+			DC395x_read32(acb, TRM_S1040_DMA_CXCNT),
+			srb->total_xfer_length, d_left_counter);
 #if DC395x_LASTPIO
 		/* KG: Less than or equal to 4 bytes can not be transfered via DMA, it seems. */
 		if (d_left_counter
 		    && srb->total_xfer_length <= DC395x_LASTPIO) {
 			/*u32 addr = (srb->segment_x[srb->sg_index].address); */
-			/*update_sg_list (srb, d_left_counter); */
-			dprintkdbg(DBG_PIO, "DIP0: PIO (%i %s) to %p for remaining %i bytes:",
-				  DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) &
-				  0x1f,
-				  (srb->dcb->
-				   sync_period & WIDE_SYNC) ? "words" :
-				  "bytes", srb->virt_addr,
-				  srb->total_xfer_length);
-
+			/*sg_update_list (srb, d_left_counter); */
+			dprintkdbg(DBG_PIO, "data_in_phase0: PIO (%i %s) to "
+				"%p for remaining %i bytes:",
+				DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x1f,
+				(srb->dcb->sync_period & WIDE_SYNC) ?
+				    "words" : "bytes",
+				srb->virt_addr,
+				srb->total_xfer_length);
 			if (srb->dcb->sync_period & WIDE_SYNC)
 				DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2,
 					      CFG2_WIDEFIFO);
-
-			while (DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) !=
-			       0x40) {
-				u8 byte =
-				    DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
+			while (DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) != 0x40) {
+				u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
 				*(srb->virt_addr)++ = byte;
 				if (debug_enabled(DBG_PIO))
 					printk(" %02x", byte);
-				srb->total_xfer_length--;
 				d_left_counter--;
-				srb->segment_x[srb->sg_index].length--;
-				if (srb->total_xfer_length
-				    && !srb->segment_x[srb->sg_index].
-				    length) {
-				    	if (debug_enabled(DBG_PIO))
-						printk(" (next segment)");
-					srb->sg_index++;
-					update_sg_list(srb,
-							     d_left_counter);
-				}
+				sg_subtract_one(srb);
 			}
 			if (srb->dcb->sync_period & WIDE_SYNC) {
-#if 1				/* Read the last byte ... */
+#if 1
+                /* Read the last byte ... */
 				if (srb->total_xfer_length > 0) {
-					u8 byte =
-					    DC395x_read8
-					    (acb, TRM_S1040_SCSI_FIFO);
+					u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
 					*(srb->virt_addr)++ = byte;
 					srb->total_xfer_length--;
 					if (debug_enabled(DBG_PIO))
@@ -2859,8 +2325,8 @@
 			 * if there was some data left in SCSI FIFO
 			 */
 			d_left_counter =
-			    (u32) (DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) &
-				   0x1F);
+			    (u32)(DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) &
+				  0x1F);
 			if (srb->dcb->sync_period & WIDE_SYNC)
 				d_left_counter <<= 1;
 			/*
@@ -2870,19 +2336,8 @@
 			 */
 		}
 #endif
-		/*d_left_counter += DC395x_read32(acb, TRM_S1040_SCSI_COUNTER); */
-#if 0
-		dprintkl(KERN_DEBUG,
-		       "DIP0: ctr=%08x, DMA_FIFO=%02x,%02x SCSI_FIFO=%02x\n",
-		       d_left_counter, DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),
-		       DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT),
-		       DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT));
-		dprintkl(KERN_DEBUG, "DIP0: DMAStat %02x\n",
-		       DC395x_read8(acb, TRM_S1040_DMA_STATUS));
-#endif
-
 		/* KG: This should not be needed any more! */
-		if ((d_left_counter == 0)
+		if (d_left_counter == 0
 		    || (scsi_status & SCSIXFERCNT_2_ZERO)) {
 #if 0
 			int ctr = 6000000;
@@ -2896,12 +2351,6 @@
 				       "Deadlock in DataInPhase0 waiting for DMA!!\n");
 			srb->total_xfer_length = 0;
 #endif
-#if 0				/*def DBG_KG             */
-			dprintkl(KERN_DEBUG,
-			       "DIP0: DMA not yet ready: %02x: %i -> %i bytes\n",
-			       DC395x_read8(acb, TRM_S1040_DMA_STATUS),
-			       srb->total_xfer_length, d_left_counter);
-#endif
 			srb->total_xfer_length = d_left_counter;
 		} else {	/* phase changed */
 			/*
@@ -2912,333 +2361,209 @@
 			 * there were some data residue in SCSI FIFO or
 			 * SCSI transfer counter not empty
 			 */
-			update_sg_list(srb, d_left_counter);
+			sg_update_list(srb, d_left_counter);
 		}
 	}
 	/* KG: The target may decide to disconnect: Empty FIFO before! */
 	if ((*pscsi_status & PHASEMASK) != PH_DATA_IN) {
-		/*dprintkl(KERN_DEBUG, "Debug: Clean up after Data In  ...\n"); */
 		cleanup_after_transfer(acb, srb);
 	}
-#if 0
-	/* KG: Make sure, no previous transfers are pending! */
-	bval = DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT);
-	if (!(bval & 0x40)) {
-		bval &= 0x1f;
-		dprintkl(KERN_DEBUG,
-		       "DIP0(%li): %i bytes in SCSI FIFO (stat %04x) (left %08x)!!\n",
-		       srb->cmd->pid, bval & 0x1f, scsi_status,
-		       d_left_counter);
-		if ((d_left_counter == 0)
-		    || (scsi_status & SCSIXFERCNT_2_ZERO)) {
-			dprintkl(KERN_DEBUG, "Clear FIFO!\n");
-			clear_fifo(acb, "DIP0");
-		}
-	}
-#endif
-	/*DC395x_write8 (TRM_S1040_DMA_CONTROL, CLRXFIFO | ABORTXFER); */
-
-	/*clear_fifo (acb, "DIP0"); */
-	/*DC395x_write16 (TRM_S1040_SCSI_CONTROL, DO_DATALATCH); */
-	TRACEPRINTF(".*");
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *	data_in_phase1: one of dc395x_scsi_phase0[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase0[phase]
- *				if phase =1 
- ********************************************************************
- */
-static
-void data_in_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		    u16 * pscsi_status)
-{
-	dprintkdbg(DBG_0, "data_in_phase1.....\n");
-	/* FIFO should be cleared, if previous phase was not DataPhase */
-	/*clear_fifo (acb, "DIP1"); */
-	/* Allow data in! */
-	/*DC395x_write16 (TRM_S1040_SCSI_CONTROL, DO_DATALATCH); */
-	TRACEPRINTF("DIP1:*");
-	/*
-	 ** do prepare before transfer when data in phase
-	 */
+static void data_in_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
+{
+	dprintkdbg(DBG_0, "data_in_phase1: (pid#%li) <%02i-%i>\n",
+		srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun);
 	data_io_transfer(acb, srb, XFERDATAIN);
-	TRACEPRINTF(".*");
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *		data_out_phase1
- *		data_in_phase1
- ********************************************************************
- */
-static
-void data_io_transfer(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		      u16 io_dir)
+static void data_io_transfer(struct AdapterCtlBlk *acb, 
+		struct ScsiReqBlk *srb, u16 io_dir)
 {
+	struct DeviceCtlBlk *dcb = srb->dcb;
 	u8 bval;
-	struct DeviceCtlBlk *dcb;
-
-	dprintkdbg(DBG_0, "DataIO_transfer %c (pid %li): len = %i, SG: %i/%i\n",
-	       ((io_dir & DMACMD_DIR) ? 'r' : 'w'), srb->cmd->pid,
-	       srb->total_xfer_length, srb->sg_index,
-	       srb->sg_count);
-	TRACEPRINTF("%05x(%i/%i)*", srb->total_xfer_length,
-		    srb->sg_index, srb->sg_count);
-	dcb = srb->dcb;
-	if (srb == acb->tmp_srb) {
-		dprintkl(KERN_ERR, "Using tmp_srb in DataPhase!\n");
-	}
-	if (srb->sg_index < srb->sg_count) {
-		if (srb->total_xfer_length > DC395x_LASTPIO) {
-			u8 dma_status = DC395x_read8(acb, TRM_S1040_DMA_STATUS);
-			/*
-			 * KG: What should we do: Use SCSI Cmd 0x90/0x92?
-			 * Maybe, even ABORTXFER would be appropriate
-			 */
-			if (dma_status & XFERPENDING) {
-				dprintkl(KERN_DEBUG, "Xfer pending! Expect trouble!!\n");
-				dump_register_info(acb, dcb, srb);
-				DC395x_write8(acb, TRM_S1040_DMA_CONTROL,
-					      CLRXFIFO);
-			}
-			/*clear_fifo (acb, "IO"); */
-			/* 
-			 * load what physical address of Scatter/Gather list table want to be
-			 * transfer 
-			 */
-			srb->state |= SRB_DATA_XFER;
-			DC395x_write32(acb, TRM_S1040_DMA_XHIGHADDR, 0);
-			if (srb->cmd->use_sg) {	/* with S/G */
-				io_dir |= DMACMD_SG;
-				DC395x_write32(acb, TRM_S1040_DMA_XLOWADDR,
-					       srb->sg_bus_addr +
-					       sizeof(struct SGentry) *
-					       srb->sg_index);
-				/* load how many bytes in the Scatter/Gather list table */
-				DC395x_write32(acb, TRM_S1040_DMA_XCNT,
-					       ((u32)
-						(srb->sg_count -
-						 srb->sg_index) << 3));
-			} else {	/* without S/G */
-				io_dir &= ~DMACMD_SG;
-				DC395x_write32(acb, TRM_S1040_DMA_XLOWADDR,
-					       srb->segment_x[0].address);
-				DC395x_write32(acb, TRM_S1040_DMA_XCNT,
-					       srb->segment_x[0].length);
-			}
-			/* load total transfer length (24bits) max value 16Mbyte */
-			DC395x_write32(acb, TRM_S1040_SCSI_COUNTER,
-				       srb->total_xfer_length);
-			DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
-			if (io_dir & DMACMD_DIR) {	/* read */
-				DC395x_write8(acb, TRM_S1040_SCSI_COMMAND,
-					      SCMD_DMA_IN);
-				DC395x_write16(acb, TRM_S1040_DMA_COMMAND,
-					       io_dir);
-			} else {
-				DC395x_write16(acb, TRM_S1040_DMA_COMMAND,
-					       io_dir);
-				DC395x_write8(acb, TRM_S1040_SCSI_COMMAND,
-					      SCMD_DMA_OUT);
-			}
+	dprintkdbg(DBG_0,
+		"data_io_transfer: (pid#%li) <%02i-%i> %c len=%i, sg=(%i/%i)\n",
+		srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun,
+		((io_dir & DMACMD_DIR) ? 'r' : 'w'),
+		srb->total_xfer_length, srb->sg_index, srb->sg_count);
+	if (srb == acb->tmp_srb)
+		dprintkl(KERN_ERR, "data_io_transfer: Using tmp_srb!\n");
+	if (srb->sg_index >= srb->sg_count) {
+		/* can't happen? out of bounds error */
+		return;
+	}
 
+	if (srb->total_xfer_length > DC395x_LASTPIO) {
+		u8 dma_status = DC395x_read8(acb, TRM_S1040_DMA_STATUS);
+		/*
+		 * KG: What should we do: Use SCSI Cmd 0x90/0x92?
+		 * Maybe, even ABORTXFER would be appropriate
+		 */
+		if (dma_status & XFERPENDING) {
+			dprintkl(KERN_DEBUG, "data_io_transfer: Xfer pending! "
+				"Expect trouble!\n");
+			dump_register_info(acb, dcb, srb);
+			DC395x_write8(acb, TRM_S1040_DMA_CONTROL, CLRXFIFO);
 		}
+		/* clear_fifo(acb, "IO"); */
+		/* 
+		 * load what physical address of Scatter/Gather list table
+		 * want to be transfer
+		 */
+		srb->state |= SRB_DATA_XFER;
+		DC395x_write32(acb, TRM_S1040_DMA_XHIGHADDR, 0);
+		if (srb->cmd->use_sg) {	/* with S/G */
+			io_dir |= DMACMD_SG;
+			DC395x_write32(acb, TRM_S1040_DMA_XLOWADDR,
+				       srb->sg_bus_addr +
+				       sizeof(struct SGentry) *
+				       srb->sg_index);
+			/* load how many bytes in the sg list table */
+			DC395x_write32(acb, TRM_S1040_DMA_XCNT,
+				       ((u32)(srb->sg_count -
+					      srb->sg_index) << 3));
+		} else {	/* without S/G */
+			io_dir &= ~DMACMD_SG;
+			DC395x_write32(acb, TRM_S1040_DMA_XLOWADDR,
+				       srb->segment_x[0].address);
+			DC395x_write32(acb, TRM_S1040_DMA_XCNT,
+				       srb->segment_x[0].length);
+		}
+		/* load total transfer length (24bits) max value 16Mbyte */
+		DC395x_write32(acb, TRM_S1040_SCSI_COUNTER,
+			       srb->total_xfer_length);
+		DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
+		if (io_dir & DMACMD_DIR) {	/* read */
+			DC395x_write8(acb, TRM_S1040_SCSI_COMMAND,
+				      SCMD_DMA_IN);
+			DC395x_write16(acb, TRM_S1040_DMA_COMMAND, io_dir);
+		} else {
+			DC395x_write16(acb, TRM_S1040_DMA_COMMAND, io_dir);
+			DC395x_write8(acb, TRM_S1040_SCSI_COMMAND,
+				      SCMD_DMA_OUT);
+		}
+
+	}
 #if DC395x_LASTPIO
-		else if (srb->total_xfer_length > 0) {	/* The last four bytes: Do PIO */
-			/*clear_fifo (acb, "IO"); */
-			/* 
-			 * load what physical address of Scatter/Gather list table want to be
-			 * transfer 
-			 */
-			srb->state |= SRB_DATA_XFER;
-			/* load total transfer length (24bits) max value 16Mbyte */
-			DC395x_write32(acb, TRM_S1040_SCSI_COUNTER,
-				       srb->total_xfer_length);
-			DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
-			if (io_dir & DMACMD_DIR) {	/* read */
-				DC395x_write8(acb, TRM_S1040_SCSI_COMMAND,
-					      SCMD_FIFO_IN);
-			} else {	/* write */
-				int ln = srb->total_xfer_length;
-				if (srb->dcb->sync_period & WIDE_SYNC)
-					DC395x_write8
-					    (acb, TRM_S1040_SCSI_CONFIG2,
-					     CFG2_WIDEFIFO);
-				dprintkdbg(DBG_PIO, "DOP1: PIO %i bytes from %p:",
-					  srb->total_xfer_length,
-					  srb->virt_addr);
-				while (srb->total_xfer_length) {
-					if (debug_enabled(DBG_PIO))
-						printk(" %02x", (unsigned char) *(srb->virt_addr));
-					DC395x_write8
-					    (acb, TRM_S1040_SCSI_FIFO,
-					     *(srb->virt_addr)++);
-					srb->total_xfer_length--;
-					srb->segment_x[srb->sg_index].
-					    length--;
-					if (srb->total_xfer_length
-					    && !srb->segment_x[srb->
-							       sg_index].
-					    length) {
-						if (debug_enabled(DBG_PIO))
-							printk(" (next segment)");
-						srb->sg_index++;
-						update_sg_list(srb,
-							       srb->total_xfer_length);
-					}
-				}
-				if (srb->dcb->sync_period & WIDE_SYNC) {
-					if (ln % 2) {
-						DC395x_write8(acb, TRM_S1040_SCSI_FIFO, 0);
-						if (debug_enabled(DBG_PIO))
-							printk(" |00");
-					}
-					DC395x_write8
-					    (acb, TRM_S1040_SCSI_CONFIG2, 0);
-				}
-				/*DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, ln); */
+	else if (srb->total_xfer_length > 0) {	/* The last four bytes: Do PIO */
+		/* 
+		 * load what physical address of Scatter/Gather list table
+		 * want to be transfer
+		 */
+		srb->state |= SRB_DATA_XFER;
+		/* load total transfer length (24bits) max value 16Mbyte */
+		DC395x_write32(acb, TRM_S1040_SCSI_COUNTER,
+			       srb->total_xfer_length);
+		DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
+		if (io_dir & DMACMD_DIR) {	/* read */
+			DC395x_write8(acb, TRM_S1040_SCSI_COMMAND,
+				      SCMD_FIFO_IN);
+		} else {	/* write */
+			int ln = srb->total_xfer_length;
+			if (srb->dcb->sync_period & WIDE_SYNC)
+				DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2,
+				     CFG2_WIDEFIFO);
+			dprintkdbg(DBG_PIO,
+				"data_io_transfer: PIO %i bytes from %p:",
+				srb->total_xfer_length, srb->virt_addr);
+
+			while (srb->total_xfer_length) {
 				if (debug_enabled(DBG_PIO))
-					printk("\n");
-				DC395x_write8(acb, TRM_S1040_SCSI_COMMAND,
-						  SCMD_FIFO_OUT);
-			}
-		}
-#endif				/* DC395x_LASTPIO */
-		else {		/* xfer pad */
+					printk(" %02x", (unsigned char) *(srb->virt_addr));
 
-			u8 data = 0, data2 = 0;
-			if (srb->sg_count) {
-				srb->adapter_status = H_OVER_UNDER_RUN;
-				srb->status |= OVER_RUN;
+				DC395x_write8(acb, TRM_S1040_SCSI_FIFO, 
+				     *(srb->virt_addr)++);
+
+				sg_subtract_one(srb);
 			}
-			/*
-			 * KG: despite the fact that we are using 16 bits I/O ops
-			 * the SCSI FIFO is only 8 bits according to the docs
-			 * (we can set bit 1 in 0x8f to serialize FIFO access ...)
-			 */
-			if (dcb->sync_period & WIDE_SYNC) {
-				DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 2);
-				DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2,
-					      CFG2_WIDEFIFO);
-				if (io_dir & DMACMD_DIR) {	/* read */
-					data =
-					    DC395x_read8
-					    (acb, TRM_S1040_SCSI_FIFO);
-					data2 =
-					    DC395x_read8
-					    (acb, TRM_S1040_SCSI_FIFO);
-					/*dprintkl(KERN_DEBUG, "DataIO: Xfer pad: %02x %02x\n", data, data2); */
-				} else {
-					/* Danger, Robinson: If you find KGs scattered over the wide
-					 * disk, the driver or chip is to blame :-( */
-					DC395x_write8(acb, TRM_S1040_SCSI_FIFO,
-						      'K');
-					DC395x_write8(acb, TRM_S1040_SCSI_FIFO,
-						      'G');
+			if (srb->dcb->sync_period & WIDE_SYNC) {
+				if (ln % 2) {
+					DC395x_write8(acb, TRM_S1040_SCSI_FIFO, 0);
+					if (debug_enabled(DBG_PIO))
+						printk(" |00");
 				}
 				DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, 0);
+			}
+			/*DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, ln); */
+			if (debug_enabled(DBG_PIO))
+				printk("\n");
+			DC395x_write8(acb, TRM_S1040_SCSI_COMMAND,
+					  SCMD_FIFO_OUT);
+		}
+	}
+#endif				/* DC395x_LASTPIO */
+	else {		/* xfer pad */
+		u8 data = 0, data2 = 0;
+		if (srb->sg_count) {
+			srb->adapter_status = H_OVER_UNDER_RUN;
+			srb->status |= OVER_RUN;
+		}
+		/*
+		 * KG: despite the fact that we are using 16 bits I/O ops
+		 * the SCSI FIFO is only 8 bits according to the docs
+		 * (we can set bit 1 in 0x8f to serialize FIFO access ...)
+		 */
+		if (dcb->sync_period & WIDE_SYNC) {
+			DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 2);
+			DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2,
+				      CFG2_WIDEFIFO);
+			if (io_dir & DMACMD_DIR) {
+				data = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
+				data2 = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
 			} else {
-				DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 1);
-				/* Danger, Robinson: If you find a collection of Ks on your disk
-				 * something broke :-( */
-				if (io_dir & DMACMD_DIR) {	/* read */
-					data =
-					    DC395x_read8
-					    (acb, TRM_S1040_SCSI_FIFO);
-					/*dprintkl(KERN_DEBUG, "DataIO: Xfer pad: %02x\n", data); */
-				} else {
-					DC395x_write8(acb, TRM_S1040_SCSI_FIFO,
-						      'K');
-				}
+				/* Danger, Robinson: If you find KGs
+				 * scattered over the wide disk, the driver
+				 * or chip is to blame :-( */
+				DC395x_write8(acb, TRM_S1040_SCSI_FIFO, 'K');
+				DC395x_write8(acb, TRM_S1040_SCSI_FIFO, 'G');
 			}
-			srb->state |= SRB_XFERPAD;
-			DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
-			/*
-			 * SCSI command 
-			 */
-			bval =
-			    (io_dir & DMACMD_DIR) ? SCMD_FIFO_IN :
-			    SCMD_FIFO_OUT;
-			DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, bval);
+			DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, 0);
+		} else {
+			DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 1);
+			/* Danger, Robinson: If you find a collection of Ks on your disk
+			 * something broke :-( */
+			if (io_dir & DMACMD_DIR)
+				data = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
+			else
+				DC395x_write8(acb, TRM_S1040_SCSI_FIFO, 'K');
 		}
+		srb->state |= SRB_XFERPAD;
+		DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
+		/* SCSI command */
+		bval = (io_dir & DMACMD_DIR) ? SCMD_FIFO_IN : SCMD_FIFO_OUT;
+		DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, bval);
 	}
-	/*monitor_next_irq = 2; */
-	/*printk(" done\n"); */
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *	status_phase0: one of dc395x_scsi_phase0[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase0[phase]
- *				if phase =3  
- ********************************************************************
- */
-static
-void status_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		   u16 * pscsi_status)
+static void status_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
 {
-	dprintkdbg(DBG_0, "StatusPhase0 (pid %li)\n", srb->cmd->pid);
-	TRACEPRINTF("STP0 *");
+	dprintkdbg(DBG_0, "status_phase0: (pid#%li) <%02i-%i>\n",
+		srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun);
 	srb->target_status = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
 	srb->end_message = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);	/* get message */
 	srb->state = SRB_COMPLETED;
 	*pscsi_status = PH_BUS_FREE;	/*.. initial phase */
-	/*1.25 */
-	/*clear_fifo (acb, "STP0"); */
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
-	/*
-	 ** SCSI command 
-	 */
 	DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_MSGACCEPT);
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *	status_phase1: one of dc395x_scsi_phase1[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase1[phase]
- *				if phase =3 
- ********************************************************************
- */
-static
-void status_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		   u16 * pscsi_status)
-{
-	dprintkdbg(DBG_0, "StatusPhase1 (pid=%li)\n", srb->cmd->pid);
-	TRACEPRINTF("STP1 *");
-	/* Cleanup is now done at the end of DataXXPhase0 */
-	/*cleanup_after_transfer (acb, srb); */
-
+static void status_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
+{
+	dprintkdbg(DBG_0, "status_phase1: (pid#%li) <%02i-%i>\n",
+		srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun);
 	srb->state = SRB_STATUS;
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
-	/*
-	 * SCSI command 
-	 */
 	DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_COMP);
 }
 
-/* Message handling */
-
-#if 0
-/* Print received message */
-static void print_msg(u8 * msg_buf, u32 len)
-{
-	int i;
-	printk(" %02x", msg_buf[0]);
-	for (i = 1; i < len; i++)
-		printk(" %02x", msg_buf[i]);
-	printk("\n");
-}
-#endif
 
 /* Check if the message is complete */
 static inline u8 msgin_completed(u8 * msgbuf, u32 len)
@@ -3260,53 +2585,44 @@
 
 
 /* reject_msg */
-static inline
-void msgin_reject(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
+static inline void msgin_reject(struct AdapterCtlBlk *acb,
+		struct ScsiReqBlk *srb)
 {
 	srb->msgout_buf[0] = MESSAGE_REJECT;
 	srb->msg_count = 1;
 	DC395x_ENABLE_MSGOUT;
 	srb->state &= ~SRB_MSGIN;
 	srb->state |= SRB_MSGOUT;
-	dprintkl(KERN_INFO,
-	       "Reject message %02x from %02i-%i\n", srb->msgin_buf[0],
-	       srb->dcb->target_id, srb->dcb->target_lun);
-	TRACEPRINTF("\\*");
+	dprintkl(KERN_INFO, "msgin_reject: 0x%02x <%02i-%i>\n",
+		srb->msgin_buf[0],
+		srb->dcb->target_id, srb->dcb->target_lun);
 }
 
 
 /* abort command */
-static inline
-void enable_msgout_abort(struct AdapterCtlBlk *acb,
-			 struct ScsiReqBlk *srb)
+static inline void enable_msgout_abort(struct AdapterCtlBlk *acb,
+		struct ScsiReqBlk *srb)
 {
 	srb->msgout_buf[0] = ABORT;
 	srb->msg_count = 1;
 	DC395x_ENABLE_MSGOUT;
 	srb->state &= ~SRB_MSGIN;
 	srb->state |= SRB_MSGOUT;
-	/*
-	   if (srb->dcb)
-	   srb->dcb->flag &= ~ABORT_DEV_;
-	 */
-	TRACEPRINTF("#*");
 }
 
 
-static
-struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb,
-			      struct DeviceCtlBlk *dcb,
-			      u8 tag)
+static struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb,
+		struct DeviceCtlBlk *dcb, u8 tag)
 {
 	struct ScsiReqBlk *srb = NULL;
 	struct ScsiReqBlk *i;
-	        
+	dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) tag=%i srb=%p\n",
+		   srb->cmd->pid, tag, srb);
 
-	dprintkdbg(DBG_0, "QTag Msg (SRB %p): %i\n", srb, tag);
 	if (!(dcb->tag_mask & (1 << tag)))
 		dprintkl(KERN_DEBUG,
-		       "MsgIn_QTag: tag_mask (%08x) does not reserve tag %i!\n",
-		       dcb->tag_mask, tag);
+			"msgin_qtag: tag_mask=0x%08x does not reserve tag %i!\n",
+			dcb->tag_mask, tag);
 
 	if (list_empty(&dcb->srb_going_list))
 		goto mingx0;
@@ -3319,8 +2635,8 @@
 	if (!srb)
 		goto mingx0;
 
-	dprintkdbg(DBG_0, "pid %li (%i-%i)\n", srb->cmd->pid,
-	       srb->dcb->target_id, srb->dcb->target_lun);
+	dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) <%02i-%i>\n",
+		srb->cmd->pid, srb->dcb->target_id, srb->dcb->target_lun);
 	if (dcb->flag & ABORT_DEV_) {
 		/*srb->state = SRB_ABORT_SENT; */
 		enable_msgout_abort(acb, srb);
@@ -3329,20 +2645,6 @@
 	if (!(srb->state & SRB_DISCONNECT))
 		goto mingx0;
 
-	/* Tag found */
-	{
-		struct ScsiReqBlk *last_srb;
-		        
-		TRACEPRINTF("[%s]*", dcb->active_srb->debugtrace);
-		TRACEPRINTF("RTag*");
-		/* Just for debugging ... */
-		
-		last_srb = srb;
-		srb = dcb->active_srb;
-		TRACEPRINTF("Found.*");
-		srb = last_srb;
-	}
-
 	memcpy(srb->msgin_buf, dcb->active_srb->msgin_buf, acb->msg_len);
 	srb->state |= dcb->active_srb->state;
 	srb->state |= SRB_DATA_XFER;
@@ -3357,15 +2659,13 @@
 	srb->msgout_buf[0] = MSG_ABORT_TAG;
 	srb->msg_count = 1;
 	DC395x_ENABLE_MSGOUT;
-	TRACEPRINTF("?*");
-	dprintkl(KERN_DEBUG, "Unknown tag received: %i: abort !!\n", tag);
+	dprintkl(KERN_DEBUG, "msgin_qtag: Unknown tag %i - abort\n", tag);
 	return srb;
 }
 
 
-/* Reprogram registers */
-static inline void
-reprogram_regs(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb)
+static inline void reprogram_regs(struct AdapterCtlBlk *acb,
+		struct DeviceCtlBlk *dcb)
 {
 	DC395x_write8(acb, TRM_S1040_SCSI_TARGETID, dcb->target_id);
 	DC395x_write8(acb, TRM_S1040_SCSI_SYNC, dcb->sync_period);
@@ -3375,12 +2675,12 @@
 
 
 /* set async transfer mode */
-static
-void msgin_set_async(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
+static void msgin_set_async(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
 {
 	struct DeviceCtlBlk *dcb = srb->dcb;
-	dprintkl(KERN_DEBUG, "Target %02i: No sync transfers\n", dcb->target_id);
-	TRACEPRINTF("!S *");
+	dprintkl(KERN_DEBUG, "msgin_set_async: No sync transfers <%02i-%i>\n",
+		dcb->target_id, dcb->target_lun);
+
 	dcb->sync_mode &= ~(SYNC_NEGO_ENABLE);
 	dcb->sync_mode |= SYNC_NEGO_DONE;
 	/*dcb->sync_period &= 0; */
@@ -3392,26 +2692,23 @@
 	    && !(dcb->sync_mode & WIDE_NEGO_DONE)) {
 		build_wdtr(acb, dcb, srb);
 		DC395x_ENABLE_MSGOUT;
-		dprintkdbg(DBG_0, "SDTR(rej): Try WDTR anyway ...\n");
+		dprintkdbg(DBG_0, "msgin_set_async(rej): Try WDTR anyway\n");
 	}
 }
 
 
 /* set sync transfer mode */
-static
-void msgin_set_sync(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
+static void msgin_set_sync(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
 {
+	struct DeviceCtlBlk *dcb = srb->dcb;
 	u8 bval;
 	int fact;
-	struct DeviceCtlBlk *dcb = srb->dcb;
-	/*u8 oldsyncperiod = dcb->sync_period; */
-	/*u8 oldsyncoffset = dcb->sync_offset; */
-
-	dprintkdbg(DBG_1, "Target %02i: Sync: %ins (%02i.%01i MHz) Offset %i\n",
-	       dcb->target_id, srb->msgin_buf[3] << 2,
-	       (250 / srb->msgin_buf[3]),
-	       ((250 % srb->msgin_buf[3]) * 10) / srb->msgin_buf[3],
-	       srb->msgin_buf[4]);
+	dprintkdbg(DBG_1, "msgin_set_sync: <%02i> Sync: %ins "
+		"(%02i.%01i MHz) Offset %i\n",
+		dcb->target_id, srb->msgin_buf[3] << 2,
+		(250 / srb->msgin_buf[3]),
+		((250 % srb->msgin_buf[3]) * 10) / srb->msgin_buf[3],
+		srb->msgin_buf[4]);
 
 	if (srb->msgin_buf[4] > 15)
 		srb->msgin_buf[4] = 15;
@@ -3430,8 +2727,8 @@
 		bval++;
 	if (srb->msgin_buf[3] < clock_period[bval])
 		dprintkl(KERN_INFO,
-		       "Increase sync nego period to %ins\n",
-		       clock_period[bval] << 2);
+			"msgin_set_sync: Increase sync nego period to %ins\n",
+			clock_period[bval] << 2);
 	srb->msgin_buf[3] = clock_period[bval];
 	dcb->sync_period &= 0xf0;
 	dcb->sync_period |= ALT_SYNC | bval;
@@ -3443,18 +2740,17 @@
 		fact = 250;
 
 	dprintkl(KERN_INFO,
-	       "Target %02i: %s Sync: %ins Offset %i (%02i.%01i MB/s)\n",
-	       dcb->target_id, (fact == 500) ? "Wide16" : "",
-	       dcb->min_nego_period << 2, dcb->sync_offset,
-	       (fact / dcb->min_nego_period),
-	       ((fact % dcb->min_nego_period) * 10 +
+		"Target %02i: %s Sync: %ins Offset %i (%02i.%01i MB/s)\n",
+		dcb->target_id, (fact == 500) ? "Wide16" : "",
+		dcb->min_nego_period << 2, dcb->sync_offset,
+		(fact / dcb->min_nego_period),
+		((fact % dcb->min_nego_period) * 10 +
 		dcb->min_nego_period / 2) / dcb->min_nego_period);
 
-	TRACEPRINTF("S%i *", dcb->min_nego_period << 2);
 	if (!(srb->state & SRB_DO_SYNC_NEGO)) {
 		/* Reply with corrected SDTR Message */
-		dprintkl(KERN_DEBUG, " .. answer w/  %ins %i\n",
-		       srb->msgin_buf[3] << 2, srb->msgin_buf[4]);
+		dprintkl(KERN_DEBUG, "msgin_set_sync: answer w/%ins %i\n",
+			srb->msgin_buf[3] << 2, srb->msgin_buf[4]);
 
 		memcpy(srb->msgout_buf, srb->msgin_buf, 5);
 		srb->msg_count = 5;
@@ -3465,7 +2761,7 @@
 		    && !(dcb->sync_mode & WIDE_NEGO_DONE)) {
 			build_wdtr(acb, dcb, srb);
 			DC395x_ENABLE_MSGOUT;
-			dprintkdbg(DBG_0, "SDTR: Also try WDTR ...\n");
+			dprintkdbg(DBG_0, "msgin_set_sync: Also try WDTR\n");
 		}
 	}
 	srb->state &= ~SRB_DO_SYNC_NEGO;
@@ -3475,14 +2771,12 @@
 }
 
 
-static inline
-void msgin_set_nowide(struct AdapterCtlBlk *acb,
-		      struct ScsiReqBlk *srb)
+static inline void msgin_set_nowide(struct AdapterCtlBlk *acb,
+		struct ScsiReqBlk *srb)
 {
 	struct DeviceCtlBlk *dcb = srb->dcb;
-	dprintkdbg(DBG_KG, "WDTR got rejected from target %02i\n",
-	       dcb->target_id);
-	TRACEPRINTF("!W *");
+	dprintkdbg(DBG_1, "msgin_set_nowide: <%02i>\n", dcb->target_id);
+
 	dcb->sync_period &= ~WIDE_SYNC;
 	dcb->sync_mode &= ~(WIDE_NEGO_ENABLE);
 	dcb->sync_mode |= WIDE_NEGO_DONE;
@@ -3492,23 +2786,24 @@
 	    && !(dcb->sync_mode & SYNC_NEGO_DONE)) {
 		build_sdtr(acb, dcb, srb);
 		DC395x_ENABLE_MSGOUT;
-		dprintkdbg(DBG_0, "WDTR(rej): Try SDTR anyway ...\n");
+		dprintkdbg(DBG_0, "msgin_set_nowide: Rejected. Try SDTR anyway\n");
 	}
 }
 
-static
-void msgin_set_wide(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
+static void msgin_set_wide(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
 {
 	struct DeviceCtlBlk *dcb = srb->dcb;
 	u8 wide = (dcb->dev_mode & NTC_DO_WIDE_NEGO
 		   && acb->config & HCC_WIDE_CARD) ? 1 : 0;
+	dprintkdbg(DBG_1, "msgin_set_wide: <%02i>\n", dcb->target_id);
+
 	if (srb->msgin_buf[3] > wide)
 		srb->msgin_buf[3] = wide;
 	/* Completed */
 	if (!(srb->state & SRB_DO_WIDE_NEGO)) {
 		dprintkl(KERN_DEBUG,
-		       "Target %02i initiates Wide Nego ...\n",
-		       dcb->target_id);
+			"msgin_set_wide: Wide nego initiated <%02i>\n",
+			dcb->target_id);
 		memcpy(srb->msgout_buf, srb->msgin_buf, 4);
 		srb->msg_count = 4;
 		srb->state |= SRB_DO_WIDE_NEGO;
@@ -3521,28 +2816,21 @@
 	else
 		dcb->sync_period &= ~WIDE_SYNC;
 	srb->state &= ~SRB_DO_WIDE_NEGO;
-	TRACEPRINTF("W%i *", (dcb->sync_period & WIDE_SYNC ? 1 : 0));
 	/*dcb->sync_mode &= ~(WIDE_NEGO_ENABLE+WIDE_NEGO_DONE); */
-	dprintkdbg(DBG_KG,
-	       "Wide transfers (%i bit) negotiated with target %02i\n",
-	       (8 << srb->msgin_buf[3]), dcb->target_id);
+	dprintkdbg(DBG_1,
+		"msgin_set_wide: Wide (%i bit) negotiated <%02i>\n",
+		(8 << srb->msgin_buf[3]), dcb->target_id);
 	reprogram_regs(acb, dcb);
 	if ((dcb->sync_mode & SYNC_NEGO_ENABLE)
 	    && !(dcb->sync_mode & SYNC_NEGO_DONE)) {
 		build_sdtr(acb, dcb, srb);
 		DC395x_ENABLE_MSGOUT;
-		dprintkdbg(DBG_0, "WDTR: Also try SDTR ...\n");
+		dprintkdbg(DBG_0, "msgin_set_wide: Also try SDTR.\n");
 	}
 }
 
 
 /*
- ********************************************************************
- * scsiio
- *	msgin_phase0: one of dc395x_scsi_phase0[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase0[phase]
- *				if phase =7   
- *
  * extended message codes:
  *
  *	code	description
@@ -3553,25 +2841,15 @@
  *	03h	WIDE DATA TRANSFER REQUEST
  *   04h - 7Fh	Reserved
  *   80h - FFh	Vendor specific
- *  
- ********************************************************************
  */
-static
-void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		  u16 * pscsi_status)
+static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
 {
-	struct DeviceCtlBlk *dcb;
-
-	dprintkdbg(DBG_0, "msgin_phase0..............\n");
-	TRACEPRINTF("MIP0*");
-	dcb = acb->active_dcb;
+	struct DeviceCtlBlk *dcb = acb->active_dcb;
+	dprintkdbg(DBG_0, "msgin_phase0: (pid#%li)\n", srb->cmd->pid);
 
 	srb->msgin_buf[acb->msg_len++] = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
 	if (msgin_completed(srb->msgin_buf, acb->msg_len)) {
-		TRACEPRINTF("(%02x)*", srb->msgin_buf[0]);
-		/*dprintkl(KERN_INFO, "MsgIn:"); */
-		/*print_msg (srb->msgin_buf, acb->msg_len); */
-
 		/* Now eval the msg */
 		switch (srb->msgin_buf[0]) {
 		case DISCONNECT:
@@ -3581,7 +2859,6 @@
 		case SIMPLE_QUEUE_TAG:
 		case HEAD_OF_QUEUE_TAG:
 		case ORDERED_QUEUE_TAG:
-			TRACEPRINTF("(%02x)*", srb->msgin_buf[1]);
 			srb =
 			    msgin_qtag(acb, dcb,
 					      srb->msgin_buf[1]);
@@ -3605,7 +2882,6 @@
 			break;
 
 		case EXTENDED_MESSAGE:
-			TRACEPRINTF("(%02x)*", srb->msgin_buf[2]);
 			/* SDTR */
 			if (srb->msgin_buf[1] == 3
 			    && srb->msgin_buf[2] == EXTENDED_SDTR) {
@@ -3613,52 +2889,51 @@
 				break;
 			}
 			/* WDTR */
-			if (srb->msgin_buf[1] == 2 && srb->msgin_buf[2] == EXTENDED_WDTR && srb->msgin_buf[3] <= 2) {	/* sanity check ... */
+			if (srb->msgin_buf[1] == 2
+			    && srb->msgin_buf[2] == EXTENDED_WDTR
+			    && srb->msgin_buf[3] <= 2) { /* sanity check ... */
 				msgin_set_wide(acb, srb);
 				break;
 			}
 			msgin_reject(acb, srb);
 			break;
 
-			/* Discard  wide residual */
 		case MSG_IGNOREWIDE:
-			dprintkdbg(DBG_0, "Ignore Wide Residual!\n");
-			/*DC395x_write32 (TRM_S1040_SCSI_COUNTER, 1); */
-			/*DC395x_read8 (TRM_S1040_SCSI_FIFO); */
+			/* Discard  wide residual */
+			dprintkdbg(DBG_0, "msgin_phase0: Ignore Wide Residual!\n");
 			break;
 
-			/* nothing has to be done */
 		case COMMAND_COMPLETE:
+			/* nothing has to be done */
 			break;
 
+		case SAVE_POINTERS:
 			/*
-			 * SAVE POINTER may be ignored as we have the struct ScsiReqBlk* associated with the
-			 * scsi command. Thanks, Gérard, for pointing it out.
+			 * SAVE POINTER may be ignored as we have the struct
+			 * ScsiReqBlk* associated with the scsi command.
 			 */
-		case SAVE_POINTERS:
-			dprintkdbg(DBG_0, "SAVE POINTER message received (pid %li: rem.%i) ... ignore :-(\n",
-			       srb->cmd->pid, srb->total_xfer_length);
-			/*srb->Saved_Ptr = srb->TotalxferredLen; */
+			dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) "
+				"SAVE POINTER rem=%i Ignore\n",
+				srb->cmd->pid, srb->total_xfer_length);
 			break;
-			/* The device might want to restart transfer with a RESTORE */
+
 		case RESTORE_POINTERS:
-			dprintkl(KERN_DEBUG,
-			       "RESTORE POINTER message received ... ignore :-(\n");
-			/*dc395x_restore_ptr (acb, srb); */
+			dprintkdbg(DBG_0, "msgin_phase0: RESTORE POINTER. Ignore\n");
 			break;
+
 		case ABORT:
-			dprintkl(KERN_DEBUG,
-			       "ABORT msg received (pid %li %02i-%i)\n",
-			       srb->cmd->pid, dcb->target_id,
-			       dcb->target_lun);
+			dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) "
+				"<%02i-%i> ABORT msg\n",
+				srb->cmd->pid, dcb->target_id,
+				dcb->target_lun);
 			dcb->flag |= ABORT_DEV_;
 			enable_msgout_abort(acb, srb);
 			break;
-			/* reject unknown messages */
+
 		default:
+			/* reject unknown messages */
 			if (srb->msgin_buf[0] & IDENTIFY_BASE) {
-				dprintkl(KERN_DEBUG, "Identify Message received?\n");
-				/*TRACEOUT (" %s\n", srb->debugtrace); */
+				dprintkdbg(DBG_0, "msgin_phase0: Identify msg\n");
 				srb->msg_count = 1;
 				srb->msgout_buf[0] = dcb->identify_msg;
 				DC395x_ENABLE_MSGOUT;
@@ -3666,104 +2941,51 @@
 				/*break; */
 			}
 			msgin_reject(acb, srb);
-			TRACEOUT(" %s\n", srb->debugtrace);
 		}
-		TRACEPRINTF(".*");
 
 		/* Clear counter and MsgIn state */
 		srb->state &= ~SRB_MSGIN;
 		acb->msg_len = 0;
 	}
-
-	/*1.25 */
-	if ((*pscsi_status & PHASEMASK) != PH_MSG_IN)
-#if 0
-		clear_fifo(acb, "MIP0_");
-#else
-		TRACEPRINTF("N/Cln *");
-#endif
 	*pscsi_status = PH_BUS_FREE;
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important ... you know! */
 	DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_MSGACCEPT);
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *	msgin_phase1: one of dc395x_scsi_phase1[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase1[phase]
- *				if phase =7	   
- ********************************************************************
- */
-static
-void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-		  u16 * pscsi_status)
-{
-	dprintkdbg(DBG_0, "msgin_phase1..............\n");
-	TRACEPRINTF("MIP1 *");
-	clear_fifo(acb, "MIP1");
+static void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
+{
+	dprintkdbg(DBG_0, "msgin_phase1: (pid#%li)\n", srb->cmd->pid);
+	clear_fifo(acb, "msgin_phase1");
 	DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 1);
 	if (!(srb->state & SRB_MSGIN)) {
 		srb->state &= ~SRB_DISCONNECT;
 		srb->state |= SRB_MSGIN;
 	}
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
-	/*
-	 * SCSI command 
-	 */
+	/* SCSI command */
 	DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_IN);
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *	nop0: one of dc395x_scsi_phase1[] ,dc395x_scsi_phase0[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase0[phase]
- *	 dc395x_statev = (void *)dc395x_scsi_phase1[phase]
- *				if phase =4 ..PH_BUS_FREE
- ********************************************************************
- */
-static
-void nop0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-	  u16 * pscsi_status)
+static void nop0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
 {
-	/*TRACEPRINTF("NOP0 *"); */
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *	nop1: one of dc395x_scsi_phase0[] ,dc395x_scsi_phase1[] vectors
- *	 dc395x_statev = (void *)dc395x_scsi_phase0[phase]
- *	 dc395x_statev = (void *)dc395x_scsi_phase1[phase]
- *				if phase =5
- ********************************************************************
- */
-static
-void nop1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
-	  u16 * pscsi_status)
+static void nop1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
+		u16 *pscsi_status)
 {
-	/*TRACEPRINTF("NOP1 *"); */
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *		msgin_phase0
- ********************************************************************
- */
-static
-void set_xfer_rate(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb)
+static void set_xfer_rate(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb)
 {
 	struct DeviceCtlBlk *i;
 
-	/*
-	 * set all lun device's  period , offset
-	 */
+	/* set all lun device's  period, offset */
 	if (dcb->identify_msg & 0x07)
 		return;
 
@@ -3782,47 +3004,39 @@
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *		dc395x_interrupt
- ********************************************************************
- */
 static void disconnect(struct AdapterCtlBlk *acb)
 {
-	struct DeviceCtlBlk *dcb;
+	struct DeviceCtlBlk *dcb = acb->active_dcb;
 	struct ScsiReqBlk *srb;
 
-	dprintkdbg(DBG_0, "Disconnect (pid=%li)\n", acb->active_dcb->active_srb->cmd->pid);
-	dcb = acb->active_dcb;
 	if (!dcb) {
-		dprintkl(KERN_ERR, "Disc: Exception Disconnect dcb=NULL !!\n ");
+		dprintkl(KERN_ERR, "disconnect: No such device\n");
 		udelay(500);
 		/* Suspend queue for a while */
 		acb->scsi_host->last_reset =
 		    jiffies + HZ / 2 +
 		    HZ * acb->eeprom.delay_time;
-		clear_fifo(acb, "DiscEx");
+		clear_fifo(acb, "disconnectEx");
 		DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_HWRESELECT);
 		return;
 	}
 	srb = dcb->active_srb;
 	acb->active_dcb = NULL;
-	TRACEPRINTF("DISC *");
+	dprintkdbg(DBG_0, "disconnect: (pid#%li)\n", srb->cmd->pid);
 
 	srb->scsi_phase = PH_BUS_FREE;	/* initial phase */
-	clear_fifo(acb, "Disc");
+	clear_fifo(acb, "disconnect");
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_HWRESELECT);
 	if (srb->state & SRB_UNEXPECT_RESEL) {
-		dprintkl(KERN_ERR, "Disc: Unexpected Reselection (%i-%i)\n",
-		       dcb->target_id, dcb->target_lun);
+		dprintkl(KERN_ERR,
+			"disconnect: Unexpected reselection <%02i-%i>\n",
+			dcb->target_id, dcb->target_lun);
 		srb->state = 0;
 		waiting_process_next(acb);
 	} else if (srb->state & SRB_ABORT_SENT) {
-		/*Scsi_Cmnd* cmd = srb->cmd; */
 		dcb->flag &= ~ABORT_DEV_;
 		acb->scsi_host->last_reset = jiffies + HZ / 2 + 1;
-		dprintkl(KERN_ERR, "Disc: SRB_ABORT_SENT!\n");
+		dprintkl(KERN_ERR, "disconnect: SRB_ABORT_SENT\n");
 		doing_srb_done(acb, DID_ABORT, srb->cmd, 1);
 		waiting_process_next(acb);
 	} else {
@@ -3837,19 +3051,16 @@
 			if (srb->state != SRB_START_
 			    && srb->state != SRB_MSGOUT) {
 				srb->state = SRB_READY;
-				dprintkl(KERN_DEBUG, "Unexpected Disconnection (pid %li)!\n",
-				       srb->cmd->pid);
+				dprintkl(KERN_DEBUG,
+					"disconnect: (pid#%li) Unexpected\n",
+					srb->cmd->pid);
 				srb->target_status = SCSI_STAT_SEL_TIMEOUT;
-				TRACEPRINTF("UnExpD *");
-				TRACEOUT("%s\n", srb->debugtrace);
 				goto disc1;
 			} else {
 				/* Normal selection timeout */
-				TRACEPRINTF("SlTO *");
-				dprintkdbg(DBG_KG,
-				       "Disc: SelTO (pid=%li) for dev %02i-%i\n",
-				       srb->cmd->pid, dcb->target_id,
-				       dcb->target_lun);
+				dprintkdbg(DBG_KG, "disconnect: (pid#%li) "
+					"<%02i-%i> SelTO\n", srb->cmd->pid,
+					dcb->target_id, dcb->target_lun);
 				if (srb->retry_count++ > DC395x_MAX_RETRIES
 				    || acb->scan_devices) {
 					srb->target_status =
@@ -3858,8 +3069,9 @@
 				}
 				free_tag(dcb, srb);
 				srb_going_to_waiting_move(dcb, srb);
-				dprintkdbg(DBG_KG, "Retry pid %li ...\n",
-				       srb->cmd->pid);
+				dprintkdbg(DBG_KG,
+					"disconnect: (pid#%li) Retry\n",
+					srb->cmd->pid);
 				waiting_set_timer(acb, HZ / 20);
 			}
 		} else if (srb->state & SRB_DISCONNECT) {
@@ -3867,18 +3079,11 @@
 			/*
 			 * SRB_DISCONNECT (This is what we expect!)
 			 */
-			/* dprintkl(KERN_DEBUG, "DoWaitingSRB (pid=%li)\n", srb->cmd->pid); */
-			TRACEPRINTF("+*");
 			if (bval & 0x40) {
-				dprintkdbg(DBG_0, "Debug: DISC: SCSI bus stat %02x: ACK set! Other controllers?\n",
+				dprintkdbg(DBG_0, "disconnect: SCSI bus stat "
+					" 0x%02x: ACK set! Other controllers?\n",
 					bval);
 				/* It could come from another initiator, therefore don't do much ! */
-				TRACEPRINTF("ACK(%02x) *", bval);
-				/*dump_register_info (acb, dcb, srb); */
-				/*TRACEOUT (" %s\n", srb->debugtrace); */
-				/*dcb->flag |= ABORT_DEV_; */
-				/*enable_msgout_abort (acb, srb); */
-				/*DC395x_write16 (TRM_S1040_SCSI_CONTROL, DO_CLRFIFO | DO_CLRATN | DO_HWRESELECT); */
 			} else
 				waiting_process_next(acb);
 		} else if (srb->state & SRB_COMPLETED) {
@@ -3889,51 +3094,40 @@
 			free_tag(dcb, srb);
 			dcb->active_srb = NULL;
 			srb->state = SRB_FREE;
-			/*dprintkl(KERN_DEBUG, "done (pid=%li)\n", srb->cmd->pid); */
 			srb_done(acb, dcb, srb);
 		}
 	}
-	return;
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *		reselect
- ********************************************************************
- */
 static void reselect(struct AdapterCtlBlk *acb)
 {
-	struct DeviceCtlBlk *dcb;
+	struct DeviceCtlBlk *dcb = acb->active_dcb;
 	struct ScsiReqBlk *srb = NULL;
 	u16 rsel_tar_lun_id;
 	u8 id, lun;
 	u8 arblostflag = 0;
+	dprintkdbg(DBG_0, "reselect: acb=%p\n", acb);
 
-	dprintkdbg(DBG_0, "reselect..............\n");
-
-	clear_fifo(acb, "Resel");
+	clear_fifo(acb, "reselect");
 	/*DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_HWRESELECT | DO_DATALATCH); */
 	/* Read Reselected Target ID and LUN */
 	rsel_tar_lun_id = DC395x_read16(acb, TRM_S1040_SCSI_TARGETID);
-	dcb = acb->active_dcb;
 	if (dcb) {		/* Arbitration lost but Reselection win */
 		srb = dcb->active_srb;
 		if (!srb) {
-			dprintkl(KERN_DEBUG, "Arb lost Resel won, but active_srb == NULL!\n");
+			dprintkl(KERN_DEBUG, "reselect: Arb lost Resel won, "
+				"but active_srb == NULL\n");
 			DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
 			return;
 		}
 		/* Why the if ? */
-		if (!(acb->scan_devices)) {
-			dprintkdbg(DBG_KG,
-			       "Arb lost but Resel win pid %li (%02i-%i) Rsel %04x Stat %04x\n",
-			       srb->cmd->pid, dcb->target_id,
-			       dcb->target_lun, rsel_tar_lun_id,
-			       DC395x_read16(acb, TRM_S1040_SCSI_STATUS));
-			TRACEPRINTF("ArbLResel!*");
-			/*TRACEOUT (" %s\n", srb->debugtrace); */
+		if (!acb->scan_devices) {
+			dprintkdbg(DBG_KG, "reselect: (pid#%li) <%02i-%i> "
+				"Arb lost but Resel win rsel=%i stat=0x%04x\n",
+				srb->cmd->pid, dcb->target_id,
+				dcb->target_lun, rsel_tar_lun_id,
+				DC395x_read16(acb, TRM_S1040_SCSI_STATUS));
 			arblostflag = 1;
 			/*srb->state |= SRB_DISCONNECT; */
 
@@ -3947,47 +3141,37 @@
 	}
 	/* Read Reselected Target Id and LUN */
 	if (!(rsel_tar_lun_id & (IDENTIFY_BASE << 8)))
-		dprintkl(KERN_DEBUG, "Resel expects identify msg! Got %04x!\n",
-		       rsel_tar_lun_id);
+		dprintkl(KERN_DEBUG, "reselect: Expects identify msg. "
+			"Got %i!\n", rsel_tar_lun_id);
 	id = rsel_tar_lun_id & 0xff;
 	lun = (rsel_tar_lun_id >> 8) & 7;
 	dcb = find_dcb(acb, id, lun);
 	if (!dcb) {
-		dprintkl(KERN_ERR, "Reselect from non existing device (%02i-%i)\n",
-		       id, lun);
+		dprintkl(KERN_ERR, "reselect: From non existent device "
+			"<%02i-%i>\n", id, lun);
 		DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
 		return;
 	}
-
 	acb->active_dcb = dcb;
 
 	if (!(dcb->dev_mode & NTC_DO_DISCONNECT))
-		dprintkl(KERN_DEBUG, "Reselection in spite of forbidden disconnection? (%02i-%i)\n",
-		       dcb->target_id, dcb->target_lun);
+		dprintkl(KERN_DEBUG, "reselect: in spite of forbidden "
+			"disconnection? <%02i-%i>\n",
+			dcb->target_id, dcb->target_lun);
 
-	if ((dcb->sync_mode & EN_TAG_QUEUEING) /*&& !arblostflag */ ) {
-		struct ScsiReqBlk *oldSRB = srb;
+	if (dcb->sync_mode & EN_TAG_QUEUEING /*&& !arblostflag */) {
 		srb = acb->tmp_srb;
-#if debug_enabled(DBG_TRACE|DBG_TRACEALL)
-		srb->debugpos = 0;
-		srb->debugtrace[0] = 0;
-#endif
 		dcb->active_srb = srb;
-		if (oldSRB)
-			TRACEPRINTF("ArbLResel(%li):*", oldSRB->cmd->pid);
-		/*if (arblostflag) dprintkl(KERN_DEBUG, "Reselect: Wait for Tag ... \n"); */
 	} else {
 		/* There can be only one! */
 		srb = dcb->active_srb;
-		if (srb)
-			TRACEPRINTF("RSel *");
 		if (!srb || !(srb->state & SRB_DISCONNECT)) {
 			/*
 			 * abort command
 			 */
 			dprintkl(KERN_DEBUG,
-			       "Reselected w/o disconnected cmds from %02i-%i?\n",
-			       dcb->target_id, dcb->target_lun);
+				"reselect: w/o disconnected cmds <%02i-%i>\n",
+				dcb->target_id, dcb->target_lun);
 			srb = acb->tmp_srb;
 			srb->state = SRB_UNEXPECT_RESEL;
 			dcb->active_srb = srb;
@@ -4000,14 +3184,11 @@
 				srb->state = SRB_DATA_XFER;
 
 		}
-		/*if (arblostflag) TRACEOUT (" %s\n", srb->debugtrace); */
 	}
 	srb->scsi_phase = PH_BUS_FREE;	/* initial phase */
-	/* 
-	 ***********************************************
-	 ** Program HA ID, target ID, period and offset
-	 ***********************************************
-	 */
+
+	/* Program HA ID, target ID, period and offset */
+	dprintkdbg(DBG_0, "reselect: select <%i>\n", dcb->target_id);
 	DC395x_write8(acb, TRM_S1040_SCSI_HOSTID, acb->scsi_host->this_id);	/* host   ID */
 	DC395x_write8(acb, TRM_S1040_SCSI_TARGETID, dcb->target_id);		/* target ID */
 	DC395x_write8(acb, TRM_S1040_SCSI_OFFSET, dcb->sync_offset);		/* offset    */
@@ -4018,10 +3199,6 @@
 }
 
 
-
-
-
-
 static inline u8 tagq_blacklist(char *name)
 {
 #ifndef DC395x_NO_TAGQ
@@ -4038,8 +3215,7 @@
 }
 
 
-static
-void disc_tagq_set(struct DeviceCtlBlk *dcb, struct ScsiInqData *ptr)
+static void disc_tagq_set(struct DeviceCtlBlk *dcb, struct ScsiInqData *ptr)
 {
 	/* Check for SCSI format (ANSI and Response data format) */
 	if ((ptr->Vers & 0x07) >= 2 || (ptr->RDF & 0x0F) == 2) {
@@ -4048,7 +3224,7 @@
 		    /*(dcb->dev_mode & NTC_DO_DISCONNECT) */
 		    /* ((dcb->dev_type == TYPE_DISK) 
 		       || (dcb->dev_type == TYPE_MOD)) && */
-		    !tagq_blacklist(((char *) ptr) + 8)) {
+		    !tagq_blacklist(((char *)ptr) + 8)) {
 			if (dcb->max_command == 1)
 				dcb->max_command =
 				    dcb->acb->tag_max_num;
@@ -4060,9 +3236,8 @@
 }
 
 
-static
-void add_dev(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
-	     struct ScsiInqData *ptr)
+static void add_dev(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
+		struct ScsiInqData *ptr)
 {
 	u8 bval1 = ptr->DevType & SCSI_DEVTYPE;
 	dcb->dev_type = bval1;
@@ -4071,59 +3246,45 @@
 }
 
 
-/* 
- ********************************************************************
- * unmap mapped pci regions from SRB
- ********************************************************************
- */
-static
-void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
+/* unmap mapped pci regions from SRB */
+static void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
 {
-	int dir;
 	Scsi_Cmnd *cmd = srb->cmd;
-	dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+	int dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
 	if (cmd->use_sg && dir != PCI_DMA_NONE) {
 		/* unmap DC395x SG list */
-		dprintkdbg(DBG_SGPARANOIA,
-		       "Unmap SG descriptor list %08x (%05x)\n",
-		       srb->sg_bus_addr,
-		       sizeof(struct SGentry) * DC395x_MAX_SG_LISTENTRY);
+		dprintkdbg(DBG_SG, "pci_unmap_srb: list=%08x(%05x)\n",
+			srb->sg_bus_addr, SEGMENTX_LEN);
 		pci_unmap_single(acb->dev, srb->sg_bus_addr,
-				 sizeof(struct SGentry) *
-				 DC395x_MAX_SG_LISTENTRY,
+				 SEGMENTX_LEN,
 				 PCI_DMA_TODEVICE);
-		dprintkdbg(DBG_SGPARANOIA, "Unmap %i SG segments from %p\n",
-		       cmd->use_sg, cmd->request_buffer);
+		dprintkdbg(DBG_SG, "pci_unmap_srb: segs=%i buffer=%p\n",
+			cmd->use_sg, cmd->request_buffer);
 		/* unmap the sg segments */
 		pci_unmap_sg(acb->dev,
-			     (struct scatterlist *) cmd->request_buffer,
+			     (struct scatterlist *)cmd->request_buffer,
 			     cmd->use_sg, dir);
 	} else if (cmd->request_buffer && dir != PCI_DMA_NONE) {
-		dprintkdbg(DBG_SGPARANOIA, "Unmap buffer at %08x (%05x)\n",
-		       srb->segment_x[0].address, cmd->request_bufflen);
+		dprintkdbg(DBG_SG, "pci_unmap_srb: buffer=%08x(%05x)\n",
+			srb->segment_x[0].address, cmd->request_bufflen);
 		pci_unmap_single(acb->dev, srb->segment_x[0].address,
 				 cmd->request_bufflen, dir);
 	}
 }
 
 
-/* 
- ********************************************************************
- * unmap mapped pci sense buffer from SRB
- ********************************************************************
- */
-static
-void pci_unmap_srb_sense(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
+/* unmap mapped pci sense buffer from SRB */
+static void pci_unmap_srb_sense(struct AdapterCtlBlk *acb,
+		struct ScsiReqBlk *srb)
 {
 	if (!(srb->flag & AUTO_REQSENSE))
 		return;
 	/* Unmap sense buffer */
-	dprintkdbg(DBG_SGPARANOIA, "Unmap sense buffer from %08x\n",
+	dprintkdbg(DBG_SG, "pci_unmap_srb_sense: buffer=%08x\n",
 	       srb->segment_x[0].address);
 	pci_unmap_single(acb->dev, srb->segment_x[0].address,
 			 srb->segment_x[0].length, PCI_DMA_FROMDEVICE);
 	/* Restore SG stuff */
-	/*printk ("Auto_ReqSense finished: Restore Counters ...\n"); */
 	srb->total_xfer_length = srb->xferred;
 	srb->segment_x[0].address =
 	    srb->segment_x[DC395x_MAX_SG_LISTENTRY - 1].address;
@@ -4133,42 +3294,33 @@
 
 
 /*
- ********************************************************************
- * scsiio
- *		disconnect
- *	Complete execution of a SCSI command
- *	Signal completion to the generic SCSI driver  
- ********************************************************************
+ * Complete execution of a SCSI command
+ * Signal completion to the generic SCSI driver  
  */
-static
-void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
-	      struct ScsiReqBlk *srb)
+static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
+		struct ScsiReqBlk *srb)
 {
 	u8 tempcnt, status;
-	Scsi_Cmnd *cmd;
+	Scsi_Cmnd *cmd = srb->cmd;
 	struct ScsiInqData *ptr;
-	/*u32              drv_flags=0; */
 	int dir;
 
-	cmd = srb->cmd;
-	TRACEPRINTF("DONE *");
-
 	dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
-	ptr = (struct ScsiInqData *) (cmd->request_buffer);
-	if (cmd->use_sg)
-		ptr =
-		    (struct ScsiInqData *) CPU_ADDR(*(struct scatterlist *)
-						    ptr);
-	dprintkdbg(DBG_SGPARANOIA, 
-	       "SRBdone SG=%i (%i/%i), req_buf = %p, adr = %p\n",
-	       cmd->use_sg, srb->sg_index, srb->sg_count,
-	       cmd->request_buffer, ptr);
-	dprintkdbg(DBG_KG,
-	       "SRBdone (pid %li, target %02i-%i): ", srb->cmd->pid,
-	       srb->cmd->device->id, srb->cmd->device->lun);
+	if (cmd->use_sg) {
+		struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer;
+		ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset);
+	} else {
+		ptr = (struct ScsiInqData *)(cmd->request_buffer);
+	}
+
+	dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->pid,
+		srb->cmd->device->id, srb->cmd->device->lun);
+	dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p addr=%p\n",
+		srb, cmd->use_sg, srb->sg_index, srb->sg_count,
+		cmd->request_buffer, ptr);
 	status = srb->target_status;
 	if (srb->flag & AUTO_REQSENSE) {
-		dprintkdbg(DBG_0, "AUTO_REQSENSE1..............\n");
+		dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE1\n");
 		pci_unmap_srb_sense(acb, srb);
 		/*
 		 ** target status..........................
@@ -4176,61 +3328,60 @@
 		srb->flag &= ~AUTO_REQSENSE;
 		srb->adapter_status = 0;
 		srb->target_status = CHECK_CONDITION << 1;
-		if (debug_enabled(DBG_KG)) {
+		if (debug_enabled(DBG_1)) {
 			switch (cmd->sense_buffer[2] & 0x0f) {
 			case NOT_READY:
 				dprintkl(KERN_DEBUG,
-				     "ReqSense: NOT_READY (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i) ",
+				     "ReqSense: NOT_READY cmnd=0x%02x <%02i-%i> stat=%i scan=%i ",
 				     cmd->cmnd[0], dcb->target_id,
 				     dcb->target_lun, status, acb->scan_devices);
 				break;
 			case UNIT_ATTENTION:
 				dprintkl(KERN_DEBUG,
-				     "ReqSense: UNIT_ATTENTION (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i) ",
+				     "ReqSense: UNIT_ATTENTION cmnd=0x%02x <%02i-%i> stat=%i scan=%i ",
 				     cmd->cmnd[0], dcb->target_id,
 				     dcb->target_lun, status, acb->scan_devices);
 				break;
 			case ILLEGAL_REQUEST:
 				dprintkl(KERN_DEBUG,
-				     "ReqSense: ILLEGAL_REQUEST (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i) ",
+				     "ReqSense: ILLEGAL_REQUEST cmnd=0x%02x <%02i-%i> stat=%i scan=%i ",
 				     cmd->cmnd[0], dcb->target_id,
 				     dcb->target_lun, status, acb->scan_devices);
 				break;
 			case MEDIUM_ERROR:
 				dprintkl(KERN_DEBUG,
-				     "ReqSense: MEDIUM_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i) ",
+				     "ReqSense: MEDIUM_ERROR cmnd=0x%02x <%02i-%i> stat=%i scan=%i ",
 				     cmd->cmnd[0], dcb->target_id,
 				     dcb->target_lun, status, acb->scan_devices);
 				break;
 			case HARDWARE_ERROR:
 				dprintkl(KERN_DEBUG,
-				     "ReqSense: HARDWARE_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i) ",
+				     "ReqSense: HARDWARE_ERROR cmnd=0x%02x <%02i-%i> stat=%i scan=%i ",
 				     cmd->cmnd[0], dcb->target_id,
 				     dcb->target_lun, status, acb->scan_devices);
 				break;
 			}
 			if (cmd->sense_buffer[7] >= 6)
-				dprintkl(KERN_DEBUG, 
-				     "Sense=%02x, ASC=%02x, ASCQ=%02x (%08x %08x) ",
-				     cmd->sense_buffer[2], cmd->sense_buffer[12],
-				     cmd->sense_buffer[13],
-				     *((unsigned int *) (cmd->sense_buffer + 3)),
-				     *((unsigned int *) (cmd->sense_buffer + 8)));
+				printk("sense=0x%02x ASC=0x%02x ASCQ=0x%02x "
+					"(0x%08x 0x%08x)\n",
+					cmd->sense_buffer[2], cmd->sense_buffer[12],
+					cmd->sense_buffer[13],
+					*((unsigned int *)(cmd->sense_buffer + 3)),
+					*((unsigned int *)(cmd->sense_buffer + 8)));
 			else
-				dprintkl(KERN_DEBUG,
-				     "Sense=%02x, No ASC/ASCQ (%08x) ",
-				     cmd->sense_buffer[2],
-				     *((unsigned int *) (cmd->sense_buffer + 3)));
+				printk("sense=0x%02x No ASC/ASCQ (0x%08x)\n",
+					cmd->sense_buffer[2],
+					*((unsigned int *)(cmd->sense_buffer + 3)));
 		}
 
 		if (status == (CHECK_CONDITION << 1)) {
 			cmd->result = DID_BAD_TARGET << 16;
 			goto ckc_e;
 		}
-		dprintkdbg(DBG_0, "AUTO_REQSENSE2..............\n");
+		dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE2\n");
 
-		if ((srb->total_xfer_length)
-		    && (srb->total_xfer_length >= cmd->underflow))
+		if (srb->total_xfer_length
+		    && srb->total_xfer_length >= cmd->underflow)
 			cmd->result =
 			    MK_RES_LNX(DRIVER_SENSE, DID_OK,
 				       srb->end_message, CHECK_CONDITION);
@@ -4253,8 +3404,7 @@
 			return;
 		} else if (status_byte(status) == QUEUE_FULL) {
 			tempcnt = (u8)list_size(&dcb->srb_going_list);
-			printk
-			    ("\nDC395x:  QUEUE_FULL for dev %02i-%i with %i cmnds\n",
+			dprintkl(KERN_INFO, "QUEUE_FULL for dev <%02i-%i> with %i cmnds\n",
 			     dcb->target_id, dcb->target_lun, tempcnt);
 			if (tempcnt > 1)
 				tempcnt--;
@@ -4299,7 +3449,7 @@
 	if (dir != PCI_DMA_NONE) {
 		if (cmd->use_sg)
 			pci_dma_sync_sg(acb->dev,
-					(struct scatterlist *) cmd->
+					(struct scatterlist *)cmd->
 					request_buffer, cmd->use_sg, dir);
 		else if (cmd->request_buffer)
 			pci_dma_sync_single(acb->dev,
@@ -4336,48 +3486,35 @@
 	cmd->SCp.buffers_residual = 0;
 	if (debug_enabled(DBG_KG)) {
 		if (srb->total_xfer_length)
-			dprintkdbg(DBG_KG, "pid %li: %02x (%02i-%i): Missed %i bytes\n",
-			     cmd->pid, cmd->cmnd[0], cmd->device->id,
-			     cmd->device->lun, srb->total_xfer_length);
+			dprintkdbg(DBG_KG, "srb_done: (pid#%li) <%02i-%i> "
+				"cmnd=0x%02x Missed %i bytes\n",
+				cmd->pid, cmd->device->id, cmd->device->lun,
+				cmd->cmnd[0], srb->total_xfer_length);
 	}
 
 	srb_going_remove(dcb, srb);
 	/* Add to free list */
 	if (srb == acb->tmp_srb)
-		dprintkl(KERN_ERR, "ERROR! Completed Cmnd with tmp_srb!\n");
-	else
+		dprintkl(KERN_ERR, "srb_done: ERROR! Completed cmd with tmp_srb\n");
+	else {
+		dprintkdbg(DBG_0, "srb_done: (pid#%li) done result=0x%08x\n",
+			cmd->pid, cmd->result);
 		srb_free_insert(acb, srb);
-
-	dprintkdbg(DBG_0, "SRBdone: done pid %li\n", cmd->pid);
-	if (debug_enabled(DBG_KG)) {
-		printk(" 0x%08x\n", cmd->result);
 	}
-	TRACEPRINTF("%08x(%li)*", cmd->result, jiffies);
 	pci_unmap_srb(acb, srb);
-	/*DC395x_UNLOCK_ACB_NI; */
-	cmd->scsi_done(cmd);
-	/*DC395x_LOCK_ACB_NI; */
-	TRACEOUTALL(KERN_INFO " %s\n", srb->debugtrace);
 
+	cmd->scsi_done(cmd);
 	waiting_process_next(acb);
-	return;
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *		DC395x_reset
- * abort all cmds in our queues
- ********************************************************************
- */
-static
-void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
-		    Scsi_Cmnd * cmd, u8 force)
+/* abort all cmds in our queues */
+static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
+		Scsi_Cmnd *cmd, u8 force)
 {
 	struct DeviceCtlBlk *dcb;
-
 	dprintkl(KERN_INFO, "doing_srb_done: pids ");
+
 	list_for_each_entry(dcb, &acb->dcb_list, list) {
 		struct ScsiReqBlk *srb;
 		struct ScsiReqBlk *tmp;
@@ -4390,16 +3527,8 @@
 			p = srb->cmd;
 			dir = scsi_to_pci_dma_dir(p->sc_data_direction);
 			result = MK_RES(0, did_flag, 0, 0);
-
-			/*result = MK_RES(0,DID_RESET,0,0); */
-			TRACEPRINTF("Reset(%li):%08x*", jiffies, result);
-			printk(" (G)");
-#if 1				/*ndef DC395x_DEBUGTRACE */
-			printk("%li(%02i-%i) ", p->pid,
+			printk("G:%li(%02i-%i) ", p->pid,
 			       p->device->id, p->device->lun);
-#endif
-			TRACEOUT("%s\n", srb->debugtrace);
-
 			srb_going_remove(dcb, srb);
 			free_tag(dcb, srb);
 			srb_free_insert(acb, srb);
@@ -4414,11 +3543,11 @@
 		}
 		if (!list_empty(&dcb->srb_going_list))
 			dprintkl(KERN_DEBUG, 
-			       "How could the ML send cmnds to the Going queue? (%02i-%i)!!\n",
+			       "How could the ML send cmnds to the Going queue? <%02i-%i>\n",
 			       dcb->target_id, dcb->target_lun);
 		if (dcb->tag_mask)
 			dprintkl(KERN_DEBUG,
-			       "tag_mask for %02i-%i should be empty, is %08x!\n",
+			       "tag_mask for <%02i-%i> should be empty, is %08x!\n",
 			       dcb->target_id, dcb->target_lun,
 			       dcb->tag_mask);
 
@@ -4428,16 +3557,10 @@
 			p = srb->cmd;
 
 			result = MK_RES(0, did_flag, 0, 0);
-			TRACEPRINTF("Reset(%li):%08x*", jiffies, result);
-			printk(" (W)");
-#if 1				/*ndef DC395x_DEBUGTRACE */
-			printk("%li(%i-%i)", p->pid, p->device->id,
+			printk("W:%li<%02i-%i>", p->pid, p->device->id,
 			       p->device->lun);
-#endif
-			TRACEOUT("%s\n", srb->debugtrace);
 			srb_waiting_remove(dcb, srb);
 			srb_free_insert(acb, srb);
-
 			p->result = result;
 			pci_unmap_srb_sense(acb, srb);
 			pci_unmap_srb(acb, srb);
@@ -4448,41 +3571,26 @@
 			}
 		}
 		if (!list_empty(&dcb->srb_waiting_list))
-			printk
-			    ("\nDC395x: Debug: ML queued %i cmnds again to %02i-%i\n",
+			dprintkl(KERN_DEBUG, "ML queued %i cmnds again to <%02i-%i>\n",
 			     list_size(&dcb->srb_waiting_list), dcb->target_id,
 			     dcb->target_lun);
-
 		dcb->flag &= ~ABORT_DEV_;
 	}
 	printk("\n");
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *		DC395x_shutdown   DC395x_reset
- ********************************************************************
- */
 static void reset_scsi_bus(struct AdapterCtlBlk *acb)
 {
-	/*u32  drv_flags=0; */
-
-	dprintkdbg(DBG_0, "reset_scsi_bus..............\n");
-
-	/*DC395x_DRV_LOCK(drv_flags); */
+	dprintkdbg(DBG_0, "reset_scsi_bus: acb=%p\n", acb);
 	acb->acb_flag |= RESET_DEV;	/* RESET_DETECT, RESET_DONE, RESET_DEV */
-
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_RSTSCSI);
-	while (!(DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS) & INT_SCSIRESET));
 
-	/*DC395x_DRV_UNLOCK(drv_flags); */
-	return;
+	while (!(DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS) & INT_SCSIRESET))
+		/* nothing */;
 }
 
 
-/* Set basic config */
 static void set_basic_config(struct AdapterCtlBlk *acb)
 {
 	u8 bval;
@@ -4508,7 +3616,6 @@
 	wval = DC395x_read16(acb, TRM_S1040_DMA_CONFIG) & ~DMA_FIFO_CTRL;
 	wval |=
 	    DMA_FIFO_HALF_HALF | DMA_ENHANCE /*| DMA_MEM_MULTI_READ */ ;
-	/*dprintkl(KERN_INFO, "DMA_Config: %04x\n", wval); */
 	DC395x_write16(acb, TRM_S1040_DMA_CONFIG, wval);
 	/* Clear pending interrupt status */
 	DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS);
@@ -4520,15 +3627,9 @@
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *		dc395x_interrupt
- ********************************************************************
- */
 static void scsi_reset_detect(struct AdapterCtlBlk *acb)
 {
-	dprintkl(KERN_INFO, "scsi_reset_detect\n");
+	dprintkl(KERN_INFO, "scsi_reset_detect: acb=%p\n", acb);
 	/* delay half a second */
 	if (timer_pending(&acb->waiting_timer))
 		del_timer(&acb->waiting_timer);
@@ -4542,7 +3643,7 @@
 	    jiffies + 5 * HZ / 2 +
 	    HZ * acb->eeprom.delay_time;
 
-	clear_fifo(acb, "RstDet");
+	clear_fifo(acb, "scsi_reset_detect");
 	set_basic_config(acb);
 	/*1.25 */
 	/*DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_HWRESELECT); */
@@ -4558,28 +3659,16 @@
 		acb->acb_flag = 0;
 		waiting_process_next(acb);
 	}
-
-	return;
 }
 
 
-/*
- ********************************************************************
- * scsiio
- *		srb_done
- ********************************************************************
- */
-static
-void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
-		   struct ScsiReqBlk *srb)
+static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
+		struct ScsiReqBlk *srb)
 {
-	Scsi_Cmnd *cmd;
+	Scsi_Cmnd *cmd = srb->cmd;
+	dprintkdbg(DBG_1, "request_sense: (pid#%li) <%02i-%i>\n",
+		cmd->pid, cmd->device->id, cmd->device->lun);
 
-	cmd = srb->cmd;
-	dprintkdbg(DBG_KG,
-	       "request_sense for pid %li, target %02i-%i\n",
-	       cmd->pid, cmd->device->id, cmd->device->lun);
-	TRACEPRINTF("RqSn*");
 	srb->flag |= AUTO_REQSENSE;
 	srb->adapter_status = 0;
 	srb->target_status = 0;
@@ -4600,27 +3689,22 @@
 	srb->segment_x[0].address =
 	    pci_map_single(acb->dev, cmd->sense_buffer,
 			   sizeof(cmd->sense_buffer), PCI_DMA_FROMDEVICE);
-	dprintkdbg(DBG_SGPARANOIA, "Map sense buffer at %p (%05x) to %08x\n",
-	       cmd->sense_buffer, sizeof(cmd->sense_buffer),
-	       srb->segment_x[0].address);
+	dprintkdbg(DBG_SG, "request_sense: map buffer %p->%08x(%05x)\n",
+	       cmd->sense_buffer, srb->segment_x[0].address,
+	       sizeof(cmd->sense_buffer));
 	srb->sg_count = 1;
 	srb->sg_index = 0;
 
 	if (start_scsi(acb, dcb, srb)) {	/* Should only happen, if sb. else grabs the bus */
 		dprintkl(KERN_DEBUG,
-		       "Request Sense failed for pid %li (%02i-%i)!\n",
-		       srb->cmd->pid, dcb->target_id, dcb->target_lun);
-		TRACEPRINTF("?*");
+			"request_sense: (pid#%li) failed <%02i-%i>\n",
+			srb->cmd->pid, dcb->target_id, dcb->target_lun);
 		srb_going_to_waiting_move(dcb, srb);
 		waiting_set_timer(acb, HZ / 100);
 	}
-	TRACEPRINTF(".*");
 }
 
 
-
-
-
 /**
  * device_alloc - Allocate a new device instance. This create the
  * devices instance and sets up all the data items. The adapter
@@ -4634,18 +3718,17 @@
  *
  * Return the new device if succesfull or NULL on failure.
  **/
-static
-struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb, u8 target, u8 lun)
+static struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb,
+		u8 target, u8 lun)
 {
 	struct NvRamType *eeprom = &acb->eeprom;
 	u8 period_index = eeprom->target[target].period & 0x07;
 	struct DeviceCtlBlk *dcb;
 
-	dcb = dc395x_kmalloc(sizeof(struct DeviceCtlBlk), GFP_ATOMIC);
-	dprintkdbg(DBG_0, "device_alloc: device %p\n", dcb);
-	if (!dcb) {
+	dcb = kmalloc(sizeof(struct DeviceCtlBlk), GFP_ATOMIC);
+	dprintkdbg(DBG_0, "device_alloc: <%02i-%i>\n", target, lun);
+	if (!dcb)
 		return NULL;
-	}
 	dcb->acb = NULL;
 	INIT_LIST_HEAD(&dcb->srb_going_list);
 	INIT_LIST_HEAD(&dcb->srb_waiting_list);
@@ -4684,10 +3767,10 @@
 		list_for_each_entry(p, &acb->dcb_list, list)
 			if (p->target_id == dcb->target_id)
 				break;
-		dprintkdbg(DBG_KG, 
-		       "Copy settings from %02i-%02i to %02i-%02i\n",
-		       p->target_id, p->target_lun,
-		       dcb->target_id, dcb->target_lun);
+		dprintkdbg(DBG_1, 
+		       "device_alloc: <%02i-%i> copy from <%02i-%i>\n",
+		       dcb->target_id, dcb->target_lun,
+		       p->target_id, p->target_lun);
 		dcb->sync_mode = p->sync_mode;
 		dcb->sync_period = p->sync_period;
 		dcb->min_nego_period = p->min_nego_period;
@@ -4704,8 +3787,8 @@
  * @acb: The adapter device to be updated
  * @dcb: A newly created and intialised device instance to add.
  **/
-static
-void adapter_add_device(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb)
+static void adapter_add_device(struct AdapterCtlBlk *acb,
+		struct DeviceCtlBlk *dcb)
 {
 	/* backpointer to adapter */
 	dcb->acb = acb;
@@ -4732,13 +3815,13 @@
  * @acb: The adapter device to be updated
  * @dcb: A device that has previously been added to the adapter.
  **/
-static
-void adapter_remove_device(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb)
+static void adapter_remove_device(struct AdapterCtlBlk *acb,
+		struct DeviceCtlBlk *dcb)
 {
 	struct DeviceCtlBlk *i;
 	struct DeviceCtlBlk *tmp;
-	dprintkdbg(DBG_0, "adapter_remove_device: Remove device (ID %i, LUN %i): %p\n",
-		   dcb->target_id, dcb->target_lun, dcb);
+	dprintkdbg(DBG_0, "adapter_remove_device: <%02i-%i>\n",
+		dcb->target_id, dcb->target_lun);
 
 	/* fix up any pointers to this device that we have in the adapter */
 	if (acb->active_dcb == dcb)
@@ -4767,17 +3850,18 @@
  * @acb: The adapter device to be updated
  * @dcb: A device that has previously been added to the adapter.
  */
-static
-void adapter_remove_and_free_device(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb)
+static void adapter_remove_and_free_device(struct AdapterCtlBlk *acb,
+		struct DeviceCtlBlk *dcb)
 {
 	if (list_size(&dcb->srb_going_list) > 1) {
-		dprintkdbg(DBG_DCB, "adapter_remove_and_free_device: "
-		           "Won't remove because of %i active requests\n",
+		dprintkdbg(DBG_1, "adapter_remove_and_free_device: <%02i-%i> "
+		           "Won't remove because of %i active requests.\n",
+			   dcb->target_id, dcb->target_lun,
 			   list_size(&dcb->srb_going_list));
 		return;
 	}
 	adapter_remove_device(acb, dcb);
-	dc395x_kfree(dcb);
+	kfree(dcb);
 }
 
 
@@ -4787,12 +3871,11 @@
  *
  * @acb: The adapter from which all devices should be removed.
  **/
-static
-void adapter_remove_and_free_all_devices(struct AdapterCtlBlk* acb)
+static void adapter_remove_and_free_all_devices(struct AdapterCtlBlk* acb)
 {
 	struct DeviceCtlBlk *dcb;
 	struct DeviceCtlBlk *tmp;
-	dprintkdbg(DBG_DCB, "adapter_remove_and_free_all_devices: Free all devices (%i devices)\n",
+	dprintkdbg(DBG_1, "adapter_remove_and_free_all_devices: num=%i\n",
 		   list_size(&acb->dcb_list));
 
 	list_for_each_entry_safe(dcb, tmp, &acb->dcb_list, list)
@@ -4807,8 +3890,7 @@
  *
  * @scsi_device: The new scsi device that we need to handle.
  **/
-static
-int dc395x_slave_alloc(struct scsi_device *scsi_device)
+static int dc395x_slave_alloc(struct scsi_device *scsi_device)
 {
 	struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)scsi_device->host->hostdata;
 	struct DeviceCtlBlk *dcb;
@@ -4828,8 +3910,7 @@
  *
  * @scsi_device: The new scsi device that we need to handle.
  **/
-static
-void dc395x_slave_destroy(struct scsi_device *scsi_device)
+static void dc395x_slave_destroy(struct scsi_device *scsi_device)
 {
 	struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)scsi_device->host->hostdata;
 	struct DeviceCtlBlk *dcb = find_dcb(acb, scsi_device->id, scsi_device->lun);
@@ -4847,14 +3928,12 @@
  *
  * @io_port: base I/O address
  **/
-static
-void __init trms1040_wait_30us(u16 io_port)
+static void __init trms1040_wait_30us(u16 io_port)
 {
 	/* ScsiPortStallExecution(30); wait 30 us */
 	outb(5, io_port + TRM_S1040_GEN_TIMER);
 	while (!(inb(io_port + TRM_S1040_GEN_STATUS) & GTIMEOUT))
 		/* nothing */ ;
-	return;
 }
 
 
@@ -4866,8 +3945,7 @@
  * @cmd:	SB + op code (command) to send
  * @addr:	address to send
  **/
-static
-void __init trms1040_write_cmd(u16 io_port, u8 cmd, u8 addr)
+static void __init trms1040_write_cmd(u16 io_port, u8 cmd, u8 addr)
 {
 	int i;
 	u8 send_data;
@@ -4912,8 +3990,7 @@
  * @addr:	offset into EEPROM
  * @byte:	bytes to write
  **/
-static
-void __init trms1040_set_data(u16 io_port, u8 addr, u8 byte)
+static void __init trms1040_set_data(u16 io_port, u8 addr, u8 byte)
 {
 	int i;
 	u8 send_data;
@@ -4967,10 +4044,9 @@
  * @eeprom:	the data to write
  * @io_port:	the base io port
  **/
-static
-void __init trms1040_write_all(struct NvRamType *eeprom, u16 io_port)
+static void __init trms1040_write_all(struct NvRamType *eeprom, u16 io_port)
 {
-	u8 *b_eeprom = (u8 *) eeprom;
+	u8 *b_eeprom = (u8 *)eeprom;
 	u8 addr;
 
 	/* Enable SEEPROM */
@@ -4983,9 +4059,8 @@
 	trms1040_wait_30us(io_port);
 
 	/* write */
-	for (addr = 0; addr < 128; addr++, b_eeprom++) {
+	for (addr = 0; addr < 128; addr++, b_eeprom++)
 		trms1040_set_data(io_port, addr, *b_eeprom);
-	}
 
 	/* write disable */
 	trms1040_write_cmd(io_port, 0x04, 0x00);
@@ -5009,8 +4084,7 @@
  *
  * Returns the the byte read.
  **/
-static
-u8 __init trms1040_get_data(u16 io_port, u8 addr)
+static u8 __init trms1040_get_data(u16 io_port, u8 addr)
 {
 	int i;
 	u8 read_byte;
@@ -5048,10 +4122,9 @@
  * @eeprom:	where to store the data
  * @io_port:	the base io port
  **/
-static
-void __init trms1040_read_all(struct NvRamType *eeprom, u16 io_port)
+static void __init trms1040_read_all(struct NvRamType *eeprom, u16 io_port)
 {
-	u8 *b_eeprom = (u8 *) eeprom;
+	u8 *b_eeprom = (u8 *)eeprom;
 	u8 addr;
 
 	/* Enable SEEPROM */
@@ -5059,9 +4132,8 @@
 	     io_port + TRM_S1040_GEN_CONTROL);
 
 	/* read details */
-	for (addr = 0; addr < 128; addr++, b_eeprom++) {
+	for (addr = 0; addr < 128; addr++, b_eeprom++)
 		*b_eeprom = trms1040_get_data(io_port, addr);
-	}
 
 	/* Disable SEEPROM */
 	outb((inb(io_port + TRM_S1040_GEN_CONTROL) & ~EN_EEPROM),
@@ -5080,10 +4152,9 @@
  * @eeprom:	caller allocated strcuture to read the eeprom data into
  * @io_port:	io port to read from
  **/
-static
-void __init check_eeprom(struct NvRamType *eeprom, u16 io_port)
+static void __init check_eeprom(struct NvRamType *eeprom, u16 io_port)
 {
-	u16 *w_eeprom = (u16 *) eeprom;
+	u16 *w_eeprom = (u16 *)eeprom;
 	u16 w_addr;
 	u16 cksum;
 	u32 d_addr;
@@ -5092,7 +4163,7 @@
 	trms1040_read_all(eeprom, io_port);	/* read eeprom */
 
 	cksum = 0;
-	for (w_addr = 0, w_eeprom = (u16 *) eeprom; w_addr < 64;
+	for (w_addr = 0, w_eeprom = (u16 *)eeprom; w_addr < 64;
 	     w_addr++, w_eeprom++)
 		cksum += *w_eeprom;
 	if (cksum != 0x1234) {
@@ -5101,21 +4172,21 @@
 		 * Load a set of defaults into the eeprom buffer
 		 */
 		dprintkl(KERN_WARNING,
-		       "EEProm checksum error: using default values and options.\n");
-		eeprom->sub_vendor_id[0] = (u8) PCI_VENDOR_ID_TEKRAM;
-		eeprom->sub_vendor_id[1] = (u8) (PCI_VENDOR_ID_TEKRAM >> 8);
-		eeprom->sub_sys_id[0] = (u8) PCI_DEVICE_ID_TEKRAM_TRMS1040;
+			"EEProm checksum error: using default values and options.\n");
+		eeprom->sub_vendor_id[0] = (u8)PCI_VENDOR_ID_TEKRAM;
+		eeprom->sub_vendor_id[1] = (u8)(PCI_VENDOR_ID_TEKRAM >> 8);
+		eeprom->sub_sys_id[0] = (u8)PCI_DEVICE_ID_TEKRAM_TRMS1040;
 		eeprom->sub_sys_id[1] =
-		    (u8) (PCI_DEVICE_ID_TEKRAM_TRMS1040 >> 8);
+		    (u8)(PCI_DEVICE_ID_TEKRAM_TRMS1040 >> 8);
 		eeprom->sub_class = 0x00;
-		eeprom->vendor_id[0] = (u8) PCI_VENDOR_ID_TEKRAM;
-		eeprom->vendor_id[1] = (u8) (PCI_VENDOR_ID_TEKRAM >> 8);
-		eeprom->device_id[0] = (u8) PCI_DEVICE_ID_TEKRAM_TRMS1040;
+		eeprom->vendor_id[0] = (u8)PCI_VENDOR_ID_TEKRAM;
+		eeprom->vendor_id[1] = (u8)(PCI_VENDOR_ID_TEKRAM >> 8);
+		eeprom->device_id[0] = (u8)PCI_DEVICE_ID_TEKRAM_TRMS1040;
 		eeprom->device_id[1] =
-		    (u8) (PCI_DEVICE_ID_TEKRAM_TRMS1040 >> 8);
+		    (u8)(PCI_DEVICE_ID_TEKRAM_TRMS1040 >> 8);
 		eeprom->reserved = 0x00;
 
-		for (d_addr = 0, d_eeprom = (u32 *) eeprom->target;
+		for (d_addr = 0, d_eeprom = (u32 *)eeprom->target;
 		     d_addr < 16; d_addr++, d_eeprom++)
 			*d_eeprom = 0x00000077;	/* cfg3,cfg2,period,cfg0 */
 
@@ -5130,7 +4201,7 @@
 		eeprom_override(eeprom);
 
 		eeprom->cksum = 0x00;
-		for (w_addr = 0, cksum = 0, w_eeprom = (u16 *) eeprom;
+		for (w_addr = 0, cksum = 0, w_eeprom = (u16 *)eeprom;
 		     w_addr < 63; w_addr++, w_eeprom++)
 			cksum += *w_eeprom;
 
@@ -5145,113 +4216,47 @@
 }
 
 
-
-
 /**
  * print_eeprom_settings - output the eeprom settings
  * to the kernel log so people can see what they were.
  *
  * @eeprom: The eeprom data strucutre to show details for.
  **/
-static
-void __init print_eeprom_settings(struct NvRamType *eeprom)
+static void __init print_eeprom_settings(struct NvRamType *eeprom)
 {
 	dprintkl(KERN_INFO, "Used settings: AdapterID=%02i, Speed=%i(%02i.%01iMHz), dev_mode=0x%02x\n",
-	       eeprom->scsi_id,
-	       eeprom->target[0].period,
-	       clock_speed[eeprom->target[0].period] / 10,
-	       clock_speed[eeprom->target[0].period] % 10,
-	       eeprom->target[0].cfg0);
+		eeprom->scsi_id,
+		eeprom->target[0].period,
+		clock_speed[eeprom->target[0].period] / 10,
+		clock_speed[eeprom->target[0].period] % 10,
+		eeprom->target[0].cfg0);
 	dprintkl(KERN_INFO, "               AdaptMode=0x%02x, Tags=%i(%02i), DelayReset=%is\n",
-	       eeprom->channel_cfg,
-	       eeprom->max_tag,
-	       1 << eeprom->max_tag,
-	       eeprom->delay_time);
+		eeprom->channel_cfg, eeprom->max_tag,
+		1 << eeprom->max_tag, eeprom->delay_time);
 }
 
 
-
-#if debug_enabled(DBG_TRACE|DBG_TRACEALL)
-/*
- * Memory for trace buffers
- */
-static
-void free_tracebufs(struct AdapterCtlBlk *acb)
-{
-	int i;
-	const unsigned bufs_per_page = PAGE_SIZE / DEBUGTRACEBUFSZ;
-
-	for (i = 0; i < srb_idx; i += bufs_per_page)
-		if (acb->srb_array[i].debugtrace)
-			dc395x_kfree(acb->srb_array[i].debugtrace);
-}
-
-
-static
-int alloc_tracebufs(struct AdapterCtlBlk *acb)
-{
-	const unsigned mem_needed =
-	    (DC395x_MAX_SRB_CNT + 1) * DEBUGTRACEBUFSZ;
-	int pages = (mem_needed + (PAGE_SIZE - 1)) / PAGE_SIZE;
-	const unsigned bufs_per_page = PAGE_SIZE / DEBUGTRACEBUFSZ;
-	int srb_idx = 0;
-	unsigned i = 0;
-	unsigned char *ptr;
-
-	for (i = 0; i < DC395x_MAX_SRB_CNT; i++)
-		acb->srb_array[i].debugtrace = NULL;
-
-	while (pages--) {
-		ptr = dc395x_kmalloc(PAGE_SIZE, GFP_KERNEL);
-		if (!ptr) {
-			free_tracebufs(acb);
-			return 1;
-		}
-		/*dprintkl(KERN_DEBUG, "Alloc %li bytes at %p for tracebuf %i\n", */
-		/*      PAGE_SIZE, ptr, srb_idx); */
-		i = 0;
-		while (i < bufs_per_page && srb_idx < DC395x_MAX_SRB_CNT)
-			acb->srb_array[srb_idx++].debugtrace =
-			    ptr + (i++ * DEBUGTRACEBUFSZ);
-	}
-	if (i < bufs_per_page) {
-		acb->srb.debugtrace = ptr + (i * DEBUGTRACEBUFSZ);
-		acb->srb.debugtrace[0] = 0;
-	} else
-		dprintkl(KERN_DEBUG, "No space for tmsrb tracebuf reserved?!\n");
-	return 0;
-}
-#else
-static void free_tracebufs(struct AdapterCtlBlk *acb) {}
-static int alloc_tracebufs(struct AdapterCtlBlk *acb) { return 0; }
-#endif
-
 /* Free SG tables */
-static
-void adapter_sg_tables_free(struct AdapterCtlBlk *acb)
+static void adapter_sg_tables_free(struct AdapterCtlBlk *acb)
 {
 	int i;
-	const unsigned srbs_per_page = PAGE_SIZE/(DC395x_MAX_SG_LISTENTRY
-						  *sizeof(struct SGentry));
+	const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN;
 
 	for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page)
 		if (acb->srb_array[i].segment_x)
-			dc395x_kfree(acb->srb_array[i].segment_x);
+			kfree(acb->srb_array[i].segment_x);
 }
 
 
 /*
  * Allocate SG tables; as we have to pci_map them, an SG list (struct SGentry*)
  * should never cross a page boundary */
-static
-int __init adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
+static int __init adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
 {
 	const unsigned mem_needed = (DC395x_MAX_SRB_CNT+1)
-	                            *DC395x_MAX_SG_LISTENTRY
-	                            *sizeof(struct SGentry);
+	                            *SEGMENTX_LEN;
 	int pages = (mem_needed+(PAGE_SIZE-1))/PAGE_SIZE;
-	const unsigned srbs_per_page = PAGE_SIZE/(DC395x_MAX_SG_LISTENTRY
-	                                          *sizeof(struct SGentry));
+	const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN;
 	int srb_idx = 0;
 	unsigned i = 0;
 	struct SGentry *ptr;
@@ -5261,13 +4266,13 @@
 
 	dprintkdbg(DBG_1, "Allocate %i pages for SG tables\n", pages);
 	while (pages--) {
-		ptr = (struct SGentry *)dc395x_kmalloc(PAGE_SIZE, GFP_KERNEL);
+		ptr = (struct SGentry *)kmalloc(PAGE_SIZE, GFP_KERNEL);
 		if (!ptr) {
 			adapter_sg_tables_free(acb);
 			return 1;
 		}
 		dprintkdbg(DBG_1, "Allocate %li bytes at %p for SG segments %i\n",
-				  PAGE_SIZE, ptr, srb_idx);
+			PAGE_SIZE, ptr, srb_idx);
 		i = 0;
 		while (i < srbs_per_page && srb_idx < DC395x_MAX_SRB_CNT)
 			acb->srb_array[srb_idx++].segment_x =
@@ -5292,14 +4297,13 @@
  *
  * @acb: The adapter to print the information for.
  **/
-static
-void __init adapter_print_config(struct AdapterCtlBlk *acb)
+static void __init adapter_print_config(struct AdapterCtlBlk *acb)
 {
 	u8 bval;
 
 	bval = DC395x_read8(acb, TRM_S1040_GEN_STATUS);
-	dprintkl(KERN_INFO, "%s Connectors: ",
-	       ((bval & WIDESCSI) ? "(Wide)" : ""));
+	dprintkl(KERN_INFO, "%sConnectors: ",
+		((bval & WIDESCSI) ? "(Wide) " : ""));
 	if (!(bval & CON5068))
 		printk("ext%s ", !(bval & EXT68HIGH) ? "68" : "50");
 	if (!(bval & CON68))
@@ -5337,8 +4341,7 @@
  *
  * @acb: The adapter to initialize.
  **/
-static
-void __init adapter_init_params(struct AdapterCtlBlk *acb)
+static void __init adapter_init_params(struct AdapterCtlBlk *acb)
 {
 	struct NvRamType *eeprom = &acb->eeprom;
 	int i;
@@ -5400,8 +4403,7 @@
  *
  * @host: The scsi host instance to fill in the values for.
  **/
-static
-void __init adapter_init_scsi_host(struct Scsi_Host *host)
+static void __init adapter_init_scsi_host(struct Scsi_Host *host)
 {
         struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata;
 	struct NvRamType *eeprom = &acb->eeprom;
@@ -5495,8 +4497,8 @@
  * Returns 0 if the initialization succeeds, any other value on
  * failure.
  **/
-static
-int __init adapter_init(struct AdapterCtlBlk *acb, u32 io_port, u32 io_port_len, u8 irq)
+static int __init adapter_init(struct AdapterCtlBlk *acb, u32 io_port,
+		u32 io_port_len, u8 irq)
 {
 	if (!request_region(io_port, io_port_len, DC395X_NAME)) {
 		dprintkl(KERN_ERR, "Failed to reserve IO region 0x%x\n", io_port);
@@ -5528,19 +4530,15 @@
 		dprintkl(KERN_DEBUG, "Memory allocation for SG tables failed\n");
 		goto failed;
 	}
-	if (alloc_tracebufs(acb)) {
-		dprintkl(KERN_DEBUG, "Memory allocation for trace buffers failed\n");
-		goto failed;
-	}
 	adapter_init_scsi_host(acb->scsi_host);
 	adapter_init_chip(acb);
 	set_basic_config(acb);
 
-	dprintkdbg(DBG_0, "adapter_init: acb=%p, pdcb_map=%p "
-	                  "psrb_array=%p ACB size=%04x, DCB size=%04x "
-	                  "SRB size=%04x\n",
-		   acb, acb->dcb_map, acb->srb_array, sizeof(struct AdapterCtlBlk),
-		   sizeof(struct DeviceCtlBlk), sizeof(struct ScsiReqBlk));
+	dprintkdbg(DBG_0,
+		"adapter_init: acb=%p, pdcb_map=%p psrb_array=%p "
+		"size{acb=0x%04x dcb=0x%04x srb=0x%04x}\n",
+		acb, acb->dcb_map, acb->srb_array, sizeof(struct AdapterCtlBlk),
+		sizeof(struct DeviceCtlBlk), sizeof(struct ScsiReqBlk));
 	return 0;
 
 failed:
@@ -5549,7 +4547,6 @@
 	if (acb->io_port_base)
 		release_region(acb->io_port_base, acb->io_port_len);
 	adapter_sg_tables_free(acb);
-	free_tracebufs(acb);
 
 	return 1;
 }
@@ -5562,8 +4559,7 @@
  *
  * @acb: The adapter which we are to shutdown.
  **/
-static
-void adapter_uninit_chip(struct AdapterCtlBlk *acb)
+static void adapter_uninit_chip(struct AdapterCtlBlk *acb)
 {
 	/* disable interrupts */
 	DC395x_write8(acb, TRM_S1040_DMA_INTEN, 0);
@@ -5586,8 +4582,7 @@
  *
  * @acb: The adapter which we are to un-initialize.
  **/
-static
-void adapter_uninit(struct AdapterCtlBlk *acb)
+static void adapter_uninit(struct AdapterCtlBlk *acb)
 {
 	unsigned long flags;
 	DC395x_LOCK_IO(acb->scsi_host, flags);
@@ -5608,31 +4603,9 @@
 		release_region(acb->io_port_base, acb->io_port_len);
 
 	adapter_sg_tables_free(acb);
-	free_tracebufs(acb);
 }
 
 
-/*
- ******************************************************************
- * Function: dc395x_proc_info(char* buffer, char **start,
- *			 off_t offset, int length, int hostno, int inout)
- *  Purpose: return SCSI Adapter/Device Info
- *    Input:
- *          buffer: Pointer to a buffer where to write info
- *		 start :
- *		 offset:
- *		 hostno: Host adapter index
- *		 inout : Read (=0) or set(!=0) info
- *   Output:
- *          buffer: contains info length 
- *		         
- *    return value: length of info in buffer
- *
- ******************************************************************
- */
-
-/* KG: dc395x_proc_info taken from driver aha152x.c */
-
 #undef SPRINTF
 #define SPRINTF(args...) pos += sprintf(pos, args)
 
@@ -5641,9 +4614,8 @@
  if (YN) SPRINTF(" Yes ");\
  else SPRINTF(" No  ")
 
-static
-int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length,
-		     int inout)
+static int dc395x_proc_info(struct Scsi_Host *host, char *buffer,
+		char **start, off_t offset, int length, int inout)
 {
 	struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata;
 	int spd, spd1;
@@ -5741,16 +4713,12 @@
 				dcb->target_id, dcb->target_lun,
 				list_size(&dcb->srb_going_list));
 		list_for_each_entry(srb, &dcb->srb_going_list, list)
-#if debug_enabled(DBG_TRACE|DBG_TRACEALL)
-			SPRINTF("\n  %s", srb->debugtrace);
-#else
 			SPRINTF(" %li", srb->cmd->pid);
-#endif
 		if (!list_empty(&dcb->srb_waiting_list) || !list_empty(&dcb->srb_going_list))
 			SPRINTF("\n");
 	}
 
-	if (debug_enabled(DBG_DCB)) {
+	if (debug_enabled(DBG_1)) {
 		SPRINTF("DCB list for ACB %p:\n", acb);
 		list_for_each_entry(dcb, &acb->dcb_list, list) {
 			SPRINTF("%p -> ", dcb);
@@ -5770,11 +4738,6 @@
 }
 
 
-
-
-/*
- * SCSI host template
- */
 static Scsi_Host_Template dc395x_driver_template = {
 	.module                 = THIS_MODULE,
 	.proc_name              = DC395X_NAME,
@@ -5799,8 +4762,7 @@
  * banner_display - Display banner on first instance of driver
  * initialized.
  **/
-static
-void banner_display(void)
+static void banner_display(void)
 {
 	static int banner_done = 0;
 	if (!banner_done)
@@ -5824,9 +4786,8 @@
  *
  * Returns 0 on success, or an error code (-ve) on failure.
  **/
-static
-int __devinit dc395x_init_one(struct pci_dev *dev,
-			      const struct pci_device_id *id)
+static int __devinit dc395x_init_one(struct pci_dev *dev,
+		const struct pci_device_id *id)
 {
 	struct Scsi_Host *scsi_host;
 	struct AdapterCtlBlk *acb;
@@ -5859,7 +4820,7 @@
 
 	/* initialise the adapter and everything we need */
  	if (adapter_init(acb, io_port_base, io_port_len, irq)) {
-		dprintkl(KERN_INFO, "DC395x_initAdapter initial ERROR\n");
+		dprintkl(KERN_INFO, "adapter init failed\n");
 		scsi_host_put(scsi_host);
 		return -ENODEV;
 	}
@@ -5870,7 +4831,7 @@
 	if (scsi_add_host(scsi_host, &dev->dev)) {
 		dprintkl(KERN_ERR, "scsi_add_host failed\n");
 		adapter_uninit(acb);
-                scsi_host_put(scsi_host);
+		scsi_host_put(scsi_host);
 		return -ENODEV;
 	}
 	pci_set_drvdata(dev, scsi_host);
@@ -5891,7 +4852,7 @@
 	struct Scsi_Host *scsi_host = pci_get_drvdata(dev);
 	struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)(scsi_host->hostdata);
 
-	dprintkdbg(DBG_0, "Removing instance\n");
+	dprintkdbg(DBG_0, "dc395x_remove_one: acb=%p\n", acb);
 
 	scsi_remove_host(scsi_host);
 	adapter_uninit(acb);
@@ -5900,10 +4861,6 @@
 }
 
 
-/*
- * Table which identifies the PCI devices which
- * are handled by this device driver.
- */
 static struct pci_device_id dc395x_pci_table[] = {
 	{
 		.vendor		= PCI_VENDOR_ID_TEKRAM,
@@ -5916,10 +4873,6 @@
 MODULE_DEVICE_TABLE(pci, dc395x_pci_table);
 
 
-/*
- * PCI driver operations.
- * Tells the PCI sub system what can be done with the card.
- */
 static struct pci_driver dc395x_driver = {
 	.name           = DC395X_NAME,
 	.id_table       = dc395x_pci_table,
@@ -5933,8 +4886,7 @@
  *
  * Used by both module and built-in driver to initialise this driver.
  **/
-static
-int __init dc395x_module_init(void)
+static int __init dc395x_module_init(void)
 {
 	return pci_module_init(&dc395x_driver);
 }
@@ -5943,8 +4895,7 @@
 /**
  * dc395x_module_exit - Module cleanup function.
  **/
-static
-void __exit dc395x_module_exit(void)
+static void __exit dc395x_module_exit(void)
 {
 	pci_unregister_driver(&dc395x_driver);
 }
diff -Nru a/drivers/scsi/dc395x.h b/drivers/scsi/dc395x.h
--- a/drivers/scsi/dc395x.h	Wed Mar 10 21:09:43 2004
+++ b/drivers/scsi/dc395x.h	Wed Mar 10 21:09:43 2004
@@ -7,18 +7,8 @@
 /*	(SCSI chip set used Tekram ASIC TRM-S1040)			*/
 /*									*/
 /************************************************************************/
-
 #ifndef DC395x_H
 #define DC395x_H
-
-/************************************************************************/
-/*									*/
-/*	Name, Banner and Version					*/
-/*									*/
-/************************************************************************/
-#define DC395X_NAME			"dc395x"
-#define DC395X_BANNER			"Tekram DC395(U/UW/F), DC315(U) - ASIC TRM-S1040"
-#define DC395X_VERSION			"v2.04, 2003/05/19"
 
 /************************************************************************/
 /*									*/
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/hosts.c	Wed Mar 10 21:09:42 2004
@@ -32,6 +32,7 @@
 #include <linux/unistd.h>
 
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h>
 #include "scsi.h"
 
 #include "scsi_priv.h"
@@ -221,6 +222,11 @@
 	shost->max_channel = 0;
 	shost->max_id = 8;
 	shost->max_lun = 8;
+
+	/* Give each shost a default transportt if the driver
+	 * doesn't yet support Transport Attributes */
+	if (!shost->transportt) 
+		shost->transportt = &blank_transport_template;
 
 	/*
 	 * All drivers right now should be able to handle 12 byte
diff -Nru a/drivers/scsi/ini9100u.c b/drivers/scsi/ini9100u.c
--- a/drivers/scsi/ini9100u.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/ini9100u.c	Wed Mar 10 21:09:42 2004
@@ -180,15 +180,6 @@
 
 static char *setup_str = (char *) NULL;
 
-static irqreturn_t i91u_intr0(int irq, void *dev_id, struct pt_regs *);
-static irqreturn_t i91u_intr1(int irq, void *dev_id, struct pt_regs *);
-static irqreturn_t i91u_intr2(int irq, void *dev_id, struct pt_regs *);
-static irqreturn_t i91u_intr3(int irq, void *dev_id, struct pt_regs *);
-static irqreturn_t i91u_intr4(int irq, void *dev_id, struct pt_regs *);
-static irqreturn_t i91u_intr5(int irq, void *dev_id, struct pt_regs *);
-static irqreturn_t i91u_intr6(int irq, void *dev_id, struct pt_regs *);
-static irqreturn_t i91u_intr7(int irq, void *dev_id, struct pt_regs *);
-
 static void i91u_panic(char *msg);
 
 static void i91uSCBPost(BYTE * pHcb, BYTE * pScb);
@@ -278,7 +269,7 @@
 	unsigned long flags;
 	
 	spin_lock_irqsave(dev->host_lock, flags);
-	tul_isr((HCS *)hreg->base);
+	tul_isr((HCS *)dev->base);
 	spin_unlock_irqrestore(dev->host_lock, flags);
 	return IRQ_HANDLED;
 }
diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
--- a/drivers/scsi/megaraid.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/megaraid.c	Wed Mar 10 21:09:42 2004
@@ -5118,10 +5118,6 @@
 	if (max_mbox_busy_wait > MBOX_BUSY_WAIT)
 		max_mbox_busy_wait = MBOX_BUSY_WAIT;
 
-	error = pci_module_init(&megaraid_pci_driver);
-	if (error) 
-		return error;
-	
 #ifdef CONFIG_PROC_FS
 	mega_proc_dir_entry = proc_mkdir("megaraid", &proc_root);
 	if (!mega_proc_dir_entry) {
@@ -5129,6 +5125,13 @@
 				"megaraid: failed to create megaraid root\n");
 	}
 #endif
+	error = pci_module_init(&megaraid_pci_driver);
+	if (error) {
+#ifdef CONFIG_PROC_FS
+		remove_proc_entry("megaraid", &proc_root);
+#endif
+		return error;
+	}
 
 	/*
 	 * Register the driver as a character device, for applications
diff -Nru a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
--- a/drivers/scsi/pcmcia/qlogic_stub.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/pcmcia/qlogic_stub.c	Wed Mar 10 21:09:42 2004
@@ -43,9 +43,11 @@
 #include <linux/major.h>
 #include <linux/blkdev.h>
 #include <scsi/scsi_ioctl.h>
+#include <linux/interrupt.h>
 
 #include "scsi.h"
 #include "hosts.h"
+#include "../qlogicfas.h"
 
 #include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
@@ -57,8 +59,10 @@
 
 extern Scsi_Host_Template qlogicfas_driver_template;
 extern void qlogicfas_preset(int port, int irq);
-extern struct Scsi_Host *__qlogicfas_detect(Scsi_Host_Template *);
 extern int qlogicfas_bus_reset(Scsi_Cmnd *);
+extern irqreturn_t do_ql_ihandl(int irq, void *dev_id, struct pt_regs *regs);
+
+static char *qlogic_name = "qlogic_cs";
 
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
@@ -100,6 +104,71 @@
 
 static dev_info_t dev_info = "qlogic_cs";
 
+static struct Scsi_Host *qlogic_detect(Scsi_Host_Template *host,
+				dev_link_t *link, int qbase, int qlirq)
+{
+	int qltyp;		/* type of chip */
+	int qinitid;
+	struct Scsi_Host *shost;	/* registered host structure */
+	qlogicfas_priv_t priv;
+
+	qltyp = inb(qbase + 0xe) & 0xf8;
+	qinitid = host->this_id;
+	if (qinitid < 0)
+		qinitid = 7;	/* if no ID, use 7 */
+	outb(1, qbase + 8);	/* set for PIO pseudo DMA */
+	REG0;
+	outb(0x40 | qlcfg8 | qinitid, qbase + 8);	/* (ini) bus id, disable scsi rst */
+	outb(qlcfg5, qbase + 5);	/* select timer */
+	outb(qlcfg9, qbase + 9);	/* prescaler */
+
+#if QL_RESET_AT_START
+	outb(3, qbase + 3);
+	REG1;
+	/* FIXME: timeout */
+	while (inb(qbase + 0xf) & 4)
+		cpu_relax();
+	REG0;
+#endif
+
+	host->name = qlogic_name;
+	shost = scsi_host_alloc(host, sizeof(struct qlogicfas_priv));
+	if (!shost)
+		goto err;
+	shost->io_port = qbase;
+	shost->n_io_port = 16;
+	shost->dma_channel = -1;
+	if (qlirq != -1)
+		shost->irq = qlirq;
+
+	priv = (qlogicfas_priv_t)&(shost->hostdata[0]);
+	priv->qlirq = qlirq;
+	priv->qbase = qbase;
+	priv->qinitid = qinitid;
+
+	if (request_irq(qlirq, do_ql_ihandl, 0, qlogic_name, shost))
+		goto free_scsi_host;
+
+	sprintf(priv->qinfo,
+		"Qlogicfas Driver version 0.46, chip %02X at %03X, IRQ %d, TPdma:%d",
+		qltyp, qbase, qlirq, QL_TURBO_PDMA);
+
+	if (scsi_add_host(shost, NULL))
+		goto free_interrupt;
+
+	scsi_scan_host(shost);
+
+	return shost;
+
+free_interrupt:
+	free_irq(qlirq, shost);
+
+free_scsi_host:
+	scsi_host_put(shost);
+	
+err:
+	return NULL;
+}
 static dev_link_t *qlogic_attach(void)
 {
 	scsi_info_t *info;
@@ -238,18 +307,19 @@
 		outb(0x04, link->io.BasePort1 + 0xd);
 	}
 
-	/* A bad hack... */
-	release_region(link->io.BasePort1, link->io.NumPorts1);
+	qlogicfas_driver_template.name = qlogic_name;
+	qlogicfas_driver_template.proc_name = qlogic_name;
 
 	/* The KXL-810AN has a bigger IO port window */
 	if (link->io.NumPorts1 == 32)
-		qlogicfas_preset(link->io.BasePort1 + 16, link->irq.AssignedIRQ);
+		host = qlogic_detect(&qlogicfas_driver_template, link,
+			link->io.BasePort1 + 16, link->irq.AssignedIRQ);
 	else
-		qlogicfas_preset(link->io.BasePort1, link->irq.AssignedIRQ);
-
-	host = __qlogicfas_detect(&qlogicfas_driver_template);
+		host = qlogic_detect(&qlogicfas_driver_template, link,
+			link->io.BasePort1, link->irq.AssignedIRQ);
+	
 	if (!host) {
-		printk(KERN_INFO "qlogic_cs: no SCSI devices found\n");
+		printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name);
 		goto out;
 	}
 
@@ -257,16 +327,17 @@
 	link->dev = &info->node;
 	info->host = host;
 
-	scsi_add_host(host, NULL); /* XXX handle failure */
-	scsi_scan_host(host);
-
 out:
 	link->state &= ~DEV_CONFIG_PENDING;
 	return;
 
 cs_failed:
 	cs_error(link->handle, last_fn, last_ret);
-	qlogic_release(link);
+	link->dev = NULL;
+	pcmcia_release_configuration(link->handle);
+	pcmcia_release_io(link->handle, &link->io);
+	pcmcia_release_irq(link->handle, &link->irq);
+	link->state &= ~DEV_CONFIG;
 	return;
 
 }				/* qlogic_config */
@@ -282,11 +353,13 @@
 	scsi_remove_host(info->host);
 	link->dev = NULL;
 
+	free_irq(link->irq.AssignedIRQ, info->host);
+
 	pcmcia_release_configuration(link->handle);
 	pcmcia_release_io(link->handle, &link->io);
 	pcmcia_release_irq(link->handle, &link->irq);
 
-	scsi_unregister(info->host);
+	scsi_host_put(info->host);
 
 	link->state &= ~DEV_CONFIG;
 }
@@ -340,7 +413,7 @@
 static struct pcmcia_driver qlogic_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
-		.name	= "qlogic_cs",
+	.name		= "qlogic_cs",
 	},
 	.attach		= qlogic_attach,
 	.detach		= qlogic_detach,
@@ -360,5 +433,8 @@
 		qlogic_detach(dev_list);
 }
 
+MODULE_AUTHOR("Tom Zerucha, Michael Griffith");
+MODULE_DESCRIPTION("Driver for the PCMCIA Qlogic FAS SCSI controllers");
+MODULE_LICENSE("GPL");
 module_init(init_qlogic_cs);
 module_exit(exit_qlogic_cs);
diff -Nru a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c
--- a/drivers/scsi/qlogicfas.c	Wed Mar 10 21:09:43 2004
+++ b/drivers/scsi/qlogicfas.c	Wed Mar 10 21:09:43 2004
@@ -27,7 +27,6 @@
    SCSI driver cleanup and audit. This driver still needs work on the
    following
    	-	Non terminating hardware waits
-   	-	Support multiple cards at a time
    	-	Some layering violations with its pcmcia stub
 
    Redistributable under terms of the GNU General Public License
@@ -39,92 +38,6 @@
    are deemed to be part of the source code.
 
 */
-/*----------------------------------------------------------------*/
-/* Configuration */
-
-/* Set the following to 2 to use normal interrupt (active high/totempole-
-   tristate), otherwise use 0 (REQUIRED FOR PCMCIA) for active low, open
-   drain */
-
-#define QL_INT_ACTIVE_HIGH 2
-
-/* Set the following to 1 to enable the use of interrupts.  Note that 0 tends
-   to be more stable, but slower (or ties up the system more) */
-
-#define QL_USE_IRQ 1
-
-/* Set the following to max out the speed of the PIO PseudoDMA transfers,
-   again, 0 tends to be slower, but more stable.  */
-
-#define QL_TURBO_PDMA 1
-
-/* This should be 1 to enable parity detection */
-
-#define QL_ENABLE_PARITY 1
-
-/* This will reset all devices when the driver is initialized (during bootup).
-   The other linux drivers don't do this, but the DOS drivers do, and after
-   using DOS or some kind of crash or lockup this will bring things back
-   without requiring a cold boot.  It does take some time to recover from a
-   reset, so it is slower, and I have seen timeouts so that devices weren't
-   recognized when this was set. */
-
-#define QL_RESET_AT_START 0
-
-/* crystal frequency in megahertz (for offset 5 and 9)
-   Please set this for your card.  Most Qlogic cards are 40 Mhz.  The
-   Control Concepts ISA (not VLB) is 24 Mhz */
-
-#define XTALFREQ	40
-
-/**********/
-/* DANGER! modify these at your own risk */
-/* SLOWCABLE can usually be reset to zero if you have a clean setup and
-   proper termination.  The rest are for synchronous transfers and other
-   advanced features if your device can transfer faster than 5Mb/sec.
-   If you are really curious, email me for a quick howto until I have
-   something official */
-/**********/
-
-/*****/
-/* config register 1 (offset 8) options */
-/* This needs to be set to 1 if your cabling is long or noisy */
-#define SLOWCABLE 1
-
-/*****/
-/* offset 0xc */
-/* This will set fast (10Mhz) synchronous timing when set to 1
-   For this to have an effect, FASTCLK must also be 1 */
-#define FASTSCSI 0
-
-/* This when set to 1 will set a faster sync transfer rate */
-#define FASTCLK 0	/*(XTALFREQ>25?1:0)*/
-
-/*****/
-/* offset 6 */
-/* This is the sync transfer divisor, XTALFREQ/X will be the maximum
-   achievable data rate (assuming the rest of the system is capable
-   and set properly) */
-#define SYNCXFRPD 5	/*(XTALFREQ/5)*/
-
-/*****/
-/* offset 7 */
-/* This is the count of how many synchronous transfers can take place
-	i.e. how many reqs can occur before an ack is given.
-	The maximum value for this is 15, the upper bits can modify
-	REQ/ACK assertion and deassertion during synchronous transfers
-	If this is 0, the bus will only transfer asynchronously */
-#define SYNCOFFST 0
-/* for the curious, bits 7&6 control the deassertion delay in 1/2 cycles
-	of the 40Mhz clock. If FASTCLK is 1, specifying 01 (1/2) will
-	cause the deassertion to be early by 1/2 clock.  Bits 5&4 control
-	the assertion delay, also in 1/2 clocks (FASTCLK is ignored here). */
-
-/*----------------------------------------------------------------*/
-#ifdef PCMCIA
-#undef QL_INT_ACTIVE_HIGH
-#define QL_INT_ACTIVE_HIGH 0
-#endif
 
 #include <linux/module.h>
 #include <linux/blkdev.h>		/* to get disk capacity */
@@ -144,42 +57,21 @@
 
 #include "scsi.h"
 #include "hosts.h"
+#include "qlogicfas.h"
 
 /*----------------------------------------------------------------*/
-/* driver state info, local to driver */
-static int qbase;		/* Port */
-static int qinitid;		/* initiator ID */
-static int qabort;		/* Flag to cause an abort */
-static int qlirq = -1;		/* IRQ being used */
-static char qinfo[80];		/* description */
-static Scsi_Cmnd *qlcmd;	/* current command being processed */
-
-static int qlcfg5 = (XTALFREQ << 5);	/* 15625/512 */
-static int qlcfg6 = SYNCXFRPD;
-static int qlcfg7 = SYNCOFFST;
-static int qlcfg8 = (SLOWCABLE << 7) | (QL_ENABLE_PARITY << 4);
-static int qlcfg9 = ((XTALFREQ + 4) / 5);
-static int qlcfgc = (FASTCLK << 3) | (FASTSCSI << 4);
-
-int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
+int qlcfg5 = (XTALFREQ << 5);	/* 15625/512 */
+int qlcfg6 = SYNCXFRPD;
+int qlcfg7 = SYNCOFFST;
+int qlcfg8 = (SLOWCABLE << 7) | (QL_ENABLE_PARITY << 4);
+int qlcfg9 = ((XTALFREQ + 4) / 5);
+int qlcfgc = (FASTCLK << 3) | (FASTSCSI << 4);
 
-/*----------------------------------------------------------------*/
-/* The qlogic card uses two register maps - These macros select which one */
-#define REG0 ( outb( inb( qbase + 0xd ) & 0x7f , qbase + 0xd ), outb( 4 , qbase + 0xd ))
-#define REG1 ( outb( inb( qbase + 0xd ) | 0x80 , qbase + 0xd ), outb( 0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd ))
+static char qlogicfas_name[] = "qlogicfas";
 
-/* following is watchdog timeout in microseconds */
-#define WATCHDOG 5000000
+int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
 
 /*----------------------------------------------------------------*/
-/* the following will set the monitor border color (useful to find
-   where something crashed or gets stuck at and as a simple profiler) */
-
-#if 0
-#define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);}
-#else
-#define rtrc(i) {}
-#endif
 
 /*----------------------------------------------------------------*/
 /* local functions */
@@ -187,9 +79,10 @@
 
 /* error recovery - reset everything */
 
-static void ql_zap(void)
+static void ql_zap(qlogicfas_priv_t priv)
 {
 	int x;
+	int qbase = priv->qbase;
 
 	x = inb(qbase + 0xd);
 	REG0;
@@ -203,9 +96,10 @@
  *	Do a pseudo-dma tranfer
  */
  
-static int ql_pdma(int phase, char *request, int reqlen)
+static int ql_pdma(qlogicfas_priv_t priv, int phase, char *request, int reqlen)
 {
 	int j;
+	int qbase = priv->qbase;
 	j = 0;
 	if (phase & 1) {	/* in */
 #if QL_TURBO_PDMA
@@ -287,23 +181,25 @@
  *	Wait for interrupt flag (polled - not real hardware interrupt) 
  */
 
-static int ql_wai(void)
+static int ql_wai(qlogicfas_priv_t priv)
 {
 	int k;
+	int qbase = priv->qbase;
 	unsigned long i;
 
 	k = 0;
 	i = jiffies + WATCHDOG;
-	while (time_before(jiffies, i) && !qabort && !((k = inb(qbase + 4)) & 0xe0)) {
+	while (time_before(jiffies, i) && !priv->qabort &&
+					!((k = inb(qbase + 4)) & 0xe0)) {
 		barrier();
 		cpu_relax();
 	}
 	if (time_after_eq(jiffies, i))
 		return (DID_TIME_OUT);
-	if (qabort)
-		return (qabort == 1 ? DID_ABORT : DID_RESET);
+	if (priv->qabort)
+		return (priv->qabort == 1 ? DID_ABORT : DID_RESET);
 	if (k & 0x60)
-		ql_zap();
+		ql_zap(priv);
 	if (k & 0x20)
 		return (DID_PARITY);
 	if (k & 0x40)
@@ -318,9 +214,11 @@
 
 static void ql_icmd(Scsi_Cmnd * cmd)
 {
+	qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]);
+	int 	qbase = priv->qbase;
 	unsigned int i;
 
-	qabort = 0;
+	priv->qabort = 0;
 
 	REG0;
 	/* clearing of interrupts and the fifo is needed */
@@ -341,7 +239,7 @@
 	/* configurables */
 	outb(qlcfgc, qbase + 0xc);
 	/* config: no reset interrupt, (initiator) bus id */
-	outb(0x40 | qlcfg8 | qinitid, qbase + 8);
+	outb(0x40 | qlcfg8 | priv->qinitid, qbase + 8);
 	outb(qlcfg7, qbase + 7);
 	outb(qlcfg6, qbase + 6);
 	 /**/ outb(qlcfg5, qbase + 5);	/* select timer */
@@ -352,7 +250,7 @@
 	for (i = 0; i < cmd->cmd_len; i++)
 		outb(cmd->cmnd[i], qbase + 2);
 
-	qlcmd = cmd;
+	priv->qlcmd = cmd;
 	outb(0x41, qbase + 3);	/* select and send command */
 }
 
@@ -372,6 +270,8 @@
 	struct scatterlist *sglist;	/* scatter-gather list pointer */
 	unsigned int sgcount;	/* sg counter */
 	char *buf;
+	qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]);
+	int qbase = priv->qbase;
 
 	rtrc(1)
 	j = inb(qbase + 6);
@@ -382,7 +282,7 @@
 	i |= inb(qbase + 5);	/* the 0x10 bit can be set after the 0x08 */
 	if (i != 0x18) {
 		printk(KERN_ERR "Ql:Bad Interrupt status:%02x\n", i);
-		ql_zap();
+		ql_zap(priv);
 		return (DID_BAD_INTR << 16);
 	}
 	j &= 7;			/* j = inb( qbase + 7 ) >> 5; */
@@ -395,7 +295,7 @@
 	if (j != 3 && j != 4) {
 		printk(KERN_ERR "Ql:Bad sequence for command %d, int %02X, cmdleft = %d\n",
 		     j, i, inb(qbase + 7) & 0x1f);
-		ql_zap();
+		ql_zap(priv);
 		return (DID_ERROR << 16);
 	}
 	result = DID_OK;
@@ -413,18 +313,19 @@
 		/* PIO pseudo DMA to buffer or sglist */
 		REG1;
 		if (!cmd->use_sg)
-			ql_pdma(phase, cmd->request_buffer,
+			ql_pdma(priv, phase, cmd->request_buffer,
 				cmd->request_bufflen);
 		else {
 			sgcount = cmd->use_sg;
 			sglist = cmd->request_buffer;
 			while (sgcount--) {
-				if (qabort) {
+				if (priv->qabort) {
 					REG0;
-					return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16);
+					return ((priv->qabort == 1 ?
+						DID_ABORT : DID_RESET) << 16);
 				}
 				buf = page_address(sglist->page) + sglist->offset;
-				if (ql_pdma(phase, buf, sglist->length))
+				if (ql_pdma(priv, phase, buf, sglist->length))
 					break;
 				sglist++;
 			}
@@ -435,7 +336,7 @@
 		 *	Wait for irq (split into second state of irq handler
 		 *	if this can take time) 
 		 */
-		if ((k = ql_wai()))
+		if ((k = ql_wai(priv)))
 			return (k << 16);
 		k = inb(qbase + 5);	/* should be 0x10, bus service */
 	}
@@ -446,11 +347,12 @@
 	 
 	k = jiffies + WATCHDOG;
 
-	while (time_before(jiffies, k) && !qabort && !(inb(qbase + 4) & 6))
+	while (time_before(jiffies, k) && !priv->qabort &&
+						!(inb(qbase + 4) & 6))
 		cpu_relax();	/* wait for status phase */
 
 	if (time_after_eq(jiffies, k)) {
-		ql_zap();
+		ql_zap(priv);
 		return (DID_TIME_OUT << 16);
 	}
 
@@ -458,11 +360,11 @@
 	while (inb(qbase + 5))
 		cpu_relax();	/* clear pending ints */
 
-	if (qabort)
-		return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16);
+	if (priv->qabort)
+		return ((priv->qabort == 1 ? DID_ABORT : DID_RESET) << 16);
 
 	outb(0x11, qbase + 3);	/* get status and message */
-	if ((k = ql_wai()))
+	if ((k = ql_wai(priv)))
 		return (k << 16);
 	i = inb(qbase + 5);	/* get chip irq stat */
 	j = inb(qbase + 7) & 0x1f;	/* and bytes rec'd */
@@ -479,7 +381,7 @@
 	}
 	outb(0x12, qbase + 3);	/* done, disconnect */
 	rtrc(1)
-	if ((k = ql_wai()))
+	if ((k = ql_wai(priv)))
 		return (k << 16);
 
 	/*
@@ -487,21 +389,19 @@
 	 */
 	 
 	i = inb(qbase + 5);	/* should be bus service */
-	while (!qabort && ((i & 0x20) != 0x20)) {
+	while (!priv->qabort && ((i & 0x20) != 0x20)) {
 		barrier();
 		cpu_relax();
 		i |= inb(qbase + 5);
 	}
 	rtrc(0)
 
-	if (qabort)
-		return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16);
+	if (priv->qabort)
+		return ((priv->qabort == 1 ? DID_ABORT : DID_RESET) << 16);
 		
 	return (result << 16) | (message << 8) | (status & STATUS_MASK);
 }
 
-#if QL_USE_IRQ
-
 /*
  *	Interrupt handler 
  */
@@ -509,20 +409,23 @@
 static void ql_ihandl(int irq, void *dev_id, struct pt_regs *regs)
 {
 	Scsi_Cmnd *icmd;
+	struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
+	qlogicfas_priv_t priv = (qlogicfas_priv_t)&(host->hostdata[0]);
+	int qbase = priv->qbase;
 	REG0;
 
 	if (!(inb(qbase + 4) & 0x80))	/* false alarm? */
 		return;
 
-	if (qlcmd == NULL) {	/* no command to process? */
+	if (priv->qlcmd == NULL) {	/* no command to process? */
 		int i;
 		i = 16;
 		while (i-- && inb(qbase + 5));	/* maybe also ql_zap() */
 		return;
 	}
-	icmd = qlcmd;
+	icmd = priv->qlcmd;
 	icmd->result = ql_pcmd(icmd);
-	qlcmd = NULL;
+	priv->qlcmd = NULL;
 	/*
 	 *	If result is CHECK CONDITION done calls qcommand to request 
 	 *	sense 
@@ -530,7 +433,7 @@
 	(icmd->scsi_done) (icmd);
 }
 
-static irqreturn_t do_ql_ihandl(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t do_ql_ihandl(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned long flags;
 	struct Scsi_Host *host = dev_id;
@@ -541,17 +444,14 @@
 	return IRQ_HANDLED;
 }
 
-#endif
-
-#if QL_USE_IRQ
-
 /*
  *	Queued command
  */
 
 int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
-	if (cmd->device->id == qinitid) {
+	qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]);
+	if (cmd->device->id == priv->qinitid) {
 		cmd->result = DID_BAD_TARGET << 16;
 		done(cmd);
 		return 0;
@@ -559,44 +459,27 @@
 
 	cmd->scsi_done = done;
 	/* wait for the last command's interrupt to finish */
-	while (qlcmd != NULL) {
+	while (priv->qlcmd != NULL) {
 		barrier();
 		cpu_relax();
 	}
 	ql_icmd(cmd);
 	return 0;
 }
-#else
-int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
-{
-	return 1;
-}
-#endif
-
-#ifdef PCMCIA
-
-/*
- *	Allow PCMCIA code to preset the port
- *	port should be 0 and irq to -1 respectively for autoprobing 
- */
-
-void qlogicfas_preset(int port, int irq)
-{
-	qbase = port;
-	qlirq = irq;
-}
-
-#endif
 
+#ifndef PCMCIA
 /*
  *	Look for qlogic card and init if found 
  */
  
-struct Scsi_Host *__qlogicfas_detect(Scsi_Host_Template *host)
+struct Scsi_Host *__qlogicfas_detect(Scsi_Host_Template *host, int qbase,
+								int qlirq)
 {
 	int i, j;		/* these are only used by IRQ detect */
 	int qltyp;		/* type of chip */
+	int qinitid;
 	struct Scsi_Host *hreg;	/* registered host structure */
+	qlogicfas_priv_t priv;
 
 	/*	Qlogic Cards only exist at 0x230 or 0x330 (the chip itself
 	 *	decodes the address - I check 230 first since MIDI cards are
@@ -609,7 +492,7 @@
 
 	if (!qbase) {
 		for (qbase = 0x230; qbase < 0x430; qbase += 0x100) {
-			if (!request_region(qbase, 0x10, "qlogicfas"))
+			if (!request_region(qbase, 0x10, qlogicfas_name))
 				continue;
 			REG1;
 			if (((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7)
@@ -641,7 +524,6 @@
 	REG0;
 #endif
 
-#if QL_USE_IRQ
 	/*
 	 *	IRQ probe - toggle pin and check request pending 
 	 */
@@ -668,49 +550,98 @@
 	} else
 		printk(KERN_INFO "Ql: Using preset IRQ %d\n", qlirq);
 
-	if (qlirq >= 0 && !request_irq(qlirq, do_ql_ihandl, 0, "qlogicfas", NULL))
-		host->can_queue = 1;
-#endif
-	hreg = scsi_register(host, 0);	/* no host data */
+	hreg = scsi_host_alloc(host, sizeof(struct qlogicfas_priv));
 	if (!hreg)
 		goto err_release_mem;
+	priv = (qlogicfas_priv_t)&(hreg->hostdata[0]);
 	hreg->io_port = qbase;
 	hreg->n_io_port = 16;
 	hreg->dma_channel = -1;
 	if (qlirq != -1)
 		hreg->irq = qlirq;
+	priv->qbase = qbase;
+	priv->qlirq = qlirq;
+	priv->qinitid = qinitid;
+	priv->shost = hreg;
 
-	sprintf(qinfo,
+	sprintf(priv->qinfo,
 		"Qlogicfas Driver version 0.46, chip %02X at %03X, IRQ %d, TPdma:%d",
 		qltyp, qbase, qlirq, QL_TURBO_PDMA);
-	host->name = qinfo;
+	host->name = qlogicfas_name;
+
+	if (request_irq(qlirq, do_ql_ihandl, 0, qlogicfas_name, hreg))
+		goto free_scsi_host;
+
+	if (scsi_add_host(hreg, NULL))
+		goto free_interrupt;
+
+	scsi_scan_host(hreg);
 
 	return hreg;
 
+free_interrupt:
+	free_irq(qlirq, hreg);
+
+free_scsi_host:
+	scsi_host_put(hreg);
+
 err_release_mem:
 	release_region(qbase, 0x10);
-	if (host->can_queue)
-		free_irq(qlirq, do_ql_ihandl);
-	return NULL;;
-
+	return NULL;
 }
 
+#define MAX_QLOGICFAS	8
+static qlogicfas_priv_t cards;
+static int iobase[MAX_QLOGICFAS];
+static int irq[MAX_QLOGICFAS] = { [0 ... MAX_QLOGICFAS-1] = -1 };
+MODULE_PARM(iobase, "1-" __MODULE_STRING(MAX_QLOGICFAS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_QLOGICFAS) "i");
+MODULE_PARM_DESC(iobase, "I/O address");
+MODULE_PARM_DESC(irq, "IRQ");
+
 int __devinit qlogicfas_detect(Scsi_Host_Template *sht)
 {
-	return (__qlogicfas_detect(sht) != NULL);
+	struct Scsi_Host	*shost;
+	qlogicfas_priv_t	priv;
+	int	i,
+		num = 0;
+
+	for (i = 0; i < MAX_QLOGICFAS; i++) {
+		shost = __qlogicfas_detect(sht, iobase[num], irq[num]);
+		if (shost == NULL) {
+			/* no more devices */
+			break;
+		}
+		priv = (qlogicfas_priv_t)&(shost->hostdata[0]);
+		priv->next = cards;
+		cards = priv;
+		num++;
+	}
+
+	return num;
 }
 
 static int qlogicfas_release(struct Scsi_Host *shost)
 {
-	if (shost->irq)
-		free_irq(shost->irq, NULL);
+	qlogicfas_priv_t priv = (qlogicfas_priv_t)&(shost->hostdata[0]);
+	int qbase = priv->qbase;
+
+	if (shost->irq) {
+		REG1;
+		outb(0, qbase + 0xb);	/* disable ints */
+	
+		free_irq(shost->irq, shost);
+	}
 	if (shost->dma_channel != 0xff)
 		free_dma(shost->dma_channel);
 	if (shost->io_port && shost->n_io_port)
 		release_region(shost->io_port, shost->n_io_port);
-	scsi_unregister(shost);
+	scsi_remove_host(shost);
+	scsi_host_put(shost);
+
 	return 0;
 }
+#endif	/* ifndef PCMCIA */
 
 /* 
  *	Return bios parameters 
@@ -742,8 +673,9 @@
  
 static int qlogicfas_abort(Scsi_Cmnd * cmd)
 {
-	qabort = 1;
-	ql_zap();
+	qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]);
+	priv->qabort = 1;
+	ql_zap(priv);
 	return SUCCESS;
 }
 
@@ -755,8 +687,9 @@
 
 int qlogicfas_bus_reset(Scsi_Cmnd * cmd)
 {
-	qabort = 2;
-	ql_zap();
+	qlogicfas_priv_t priv = (qlogicfas_priv_t)&(cmd->device->host->hostdata[0]);
+	priv->qabort = 2;
+	ql_zap(priv);
 	return SUCCESS;
 }
 
@@ -784,22 +717,17 @@
 
 static const char *qlogicfas_info(struct Scsi_Host *host)
 {
-	return qinfo;
+	qlogicfas_priv_t priv = (qlogicfas_priv_t)&(host->hostdata[0]);
+	return priv->qinfo;
 }
 
-MODULE_AUTHOR("Tom Zerucha, Michael Griffith");
-MODULE_DESCRIPTION("Driver for the Qlogic FAS SCSI controllers");
-MODULE_LICENSE("GPL");
-
 /*
  *	The driver template is also needed for PCMCIA
  */
 Scsi_Host_Template qlogicfas_driver_template = {
 	.module			= THIS_MODULE,
-	.name			= "qlogicfas",
-	.proc_name		= "qlogicfas",
-	.detect			= qlogicfas_detect,
-	.release		= qlogicfas_release,
+	.name			= qlogicfas_name,
+	.proc_name		= qlogicfas_name,
 	.info			= qlogicfas_info,
 	.queuecommand		= qlogicfas_queuecommand,
 	.eh_abort_handler	= qlogicfas_abort,
@@ -807,7 +735,7 @@
 	.eh_device_reset_handler= qlogicfas_device_reset,
 	.eh_host_reset_handler	= qlogicfas_host_reset,
 	.bios_param		= qlogicfas_biosparam,
-	.can_queue		= 0,
+	.can_queue		= 1,
 	.this_id		= -1,
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 1,
@@ -815,6 +743,28 @@
 };
 
 #ifndef PCMCIA
-#define driver_template qlogicfas_driver_template
-#include "scsi_module.c"
-#endif
+static __init int qlogicfas_init(void)
+{
+	if (!qlogicfas_detect(&qlogicfas_driver_template)) {
+		/* no cards found */
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static __exit void qlogicfas_exit(void)
+{
+	qlogicfas_priv_t	priv;
+
+	for (priv = cards; priv != NULL; priv = priv->next)
+		qlogicfas_release(priv->shost);
+}
+
+MODULE_AUTHOR("Tom Zerucha, Michael Griffith");
+MODULE_DESCRIPTION("Driver for the Qlogic FAS SCSI controllers");
+MODULE_LICENSE("GPL");
+module_init(qlogicfas_init);
+module_exit(qlogicfas_exit);
+#endif	/* ifndef PCMCIA */
+
diff -Nru a/drivers/scsi/qlogicfas.h b/drivers/scsi/qlogicfas.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/scsi/qlogicfas.h	Wed Mar 10 21:09:43 2004
@@ -0,0 +1,124 @@
+/* to be used by qlogicfas and qlogic_cs */
+#ifndef __QLOGICFAS_H
+#define __QLOGICFAS_H
+
+/*----------------------------------------------------------------*/
+/* Configuration */
+
+/* Set the following to 2 to use normal interrupt (active high/totempole-
+   tristate), otherwise use 0 (REQUIRED FOR PCMCIA) for active low, open
+   drain */
+
+#define QL_INT_ACTIVE_HIGH 2
+
+/* Set the following to max out the speed of the PIO PseudoDMA transfers,
+   again, 0 tends to be slower, but more stable.  */
+
+#define QL_TURBO_PDMA 1
+
+/* This should be 1 to enable parity detection */
+
+#define QL_ENABLE_PARITY 1
+
+/* This will reset all devices when the driver is initialized (during bootup).
+   The other linux drivers don't do this, but the DOS drivers do, and after
+   using DOS or some kind of crash or lockup this will bring things back
+   without requiring a cold boot.  It does take some time to recover from a
+   reset, so it is slower, and I have seen timeouts so that devices weren't
+   recognized when this was set. */
+
+#define QL_RESET_AT_START 0
+
+/* crystal frequency in megahertz (for offset 5 and 9)
+   Please set this for your card.  Most Qlogic cards are 40 Mhz.  The
+   Control Concepts ISA (not VLB) is 24 Mhz */
+
+#define XTALFREQ	40
+
+/**********/
+/* DANGER! modify these at your own risk */
+/* SLOWCABLE can usually be reset to zero if you have a clean setup and
+   proper termination.  The rest are for synchronous transfers and other
+   advanced features if your device can transfer faster than 5Mb/sec.
+   If you are really curious, email me for a quick howto until I have
+   something official */
+/**********/
+
+/*****/
+/* config register 1 (offset 8) options */
+/* This needs to be set to 1 if your cabling is long or noisy */
+#define SLOWCABLE 1
+
+/*****/
+/* offset 0xc */
+/* This will set fast (10Mhz) synchronous timing when set to 1
+   For this to have an effect, FASTCLK must also be 1 */
+#define FASTSCSI 0
+
+/* This when set to 1 will set a faster sync transfer rate */
+#define FASTCLK 0	/*(XTALFREQ>25?1:0)*/
+
+/*****/
+/* offset 6 */
+/* This is the sync transfer divisor, XTALFREQ/X will be the maximum
+   achievable data rate (assuming the rest of the system is capable
+   and set properly) */
+#define SYNCXFRPD 5	/*(XTALFREQ/5)*/
+
+/*****/
+/* offset 7 */
+/* This is the count of how many synchronous transfers can take place
+	i.e. how many reqs can occur before an ack is given.
+	The maximum value for this is 15, the upper bits can modify
+	REQ/ACK assertion and deassertion during synchronous transfers
+	If this is 0, the bus will only transfer asynchronously */
+#define SYNCOFFST 0
+/* for the curious, bits 7&6 control the deassertion delay in 1/2 cycles
+	of the 40Mhz clock. If FASTCLK is 1, specifying 01 (1/2) will
+	cause the deassertion to be early by 1/2 clock.  Bits 5&4 control
+	the assertion delay, also in 1/2 clocks (FASTCLK is ignored here). */
+
+/*----------------------------------------------------------------*/
+#ifdef PCMCIA
+#undef QL_INT_ACTIVE_HIGH
+#define QL_INT_ACTIVE_HIGH 0
+#endif
+
+struct qlogicfas_priv;
+typedef struct qlogicfas_priv *qlogicfas_priv_t;
+struct qlogicfas_priv {
+	 int		qbase;		/* Port */
+	 int		qinitid;	/* initiator ID */
+	 int		qabort;		/* Flag to cause an abort */
+	 int		qlirq;		/* IRQ being used */
+	 char		qinfo[80];	/* description */
+	 Scsi_Cmnd 	*qlcmd;		/* current command being processed */
+	 struct Scsi_Host	*shost;	/* pointer back to host */
+	 qlogicfas_priv_t	next;	/* next private struct */
+};
+
+extern int qlcfg5;
+extern int qlcfg6;
+extern int qlcfg7;
+extern int qlcfg8;
+extern int qlcfg9;
+extern int qlcfgc;
+
+/* The qlogic card uses two register maps - These macros select which one */
+#define REG0 ( outb( inb( qbase + 0xd ) & 0x7f , qbase + 0xd ), outb( 4 , qbase + 0xd ))
+#define REG1 ( outb( inb( qbase + 0xd ) | 0x80 , qbase + 0xd ), outb( 0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd ))
+
+/* following is watchdog timeout in microseconds */
+#define WATCHDOG 5000000
+
+/*----------------------------------------------------------------*/
+/* the following will set the monitor border color (useful to find
+   where something crashed or gets stuck at and as a simple profiler) */
+
+#if 0
+#define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);}
+#else
+#define rtrc(i) {}
+#endif
+#endif	/* __QLOGICFAS_H */
+
diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/scsi.c	Wed Mar 10 21:09:42 2004
@@ -104,7 +104,7 @@
 	"Communications   ",
 	"Unknown          ",
 	"Unknown          ",
-	"Unknown          ",
+	"RAID             ",
 	"Enclosure        ",
 };
 
diff -Nru a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
--- a/drivers/scsi/scsi_devinfo.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/scsi_devinfo.c	Wed Mar 10 21:09:42 2004
@@ -94,95 +94,93 @@
 	 * The following causes a failed REQUEST SENSE on lun 1 for
 	 * seagate controller, which causes SCSI code to reset bus.
 	 */
-	{"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN},
+	{"HP", "C1750A", "3226", BLIST_NOLUN},		/* scanjet iic */
+	{"HP", "C1790A", "", BLIST_NOLUN},		/* scanjet iip */
+	{"HP", "C2500A", "", BLIST_NOLUN},		/* scanjet iicx */
+	{"MEDIAVIS", "CDR-H93MV", "1.31", BLIST_NOLUN},	/* locks up */
+	{"MICROTEK", "ScanMaker II", "5.61", BLIST_NOLUN},	/* responds to all lun */
+	{"MITSUMI", "CD-R CR-2201CS", "6119", BLIST_NOLUN},	/* locks up */
+	{"NEC", "D3856", "0009", BLIST_NOLUN},
 	{"QUANTUM", "LPS525S", "3110", BLIST_NOLUN},	/* locks up */
 	{"QUANTUM", "PD1225S", "3110", BLIST_NOLUN},	/* locks up */
 	{"QUANTUM", "FIREBALL ST4.3S", "0F0C", BLIST_NOLUN},	/* locks up */
-	{"MEDIAVIS", "CDR-H93MV", "1.31", BLIST_NOLUN},	/* locks up */
+	{"RELISYS", "Scorpio", NULL, BLIST_NOLUN},	/* responds to all lun */
 	{"SANKYO", "CP525", "6.64", BLIST_NOLUN},	/* causes failed REQ SENSE, extra reset */
-	{"HP", "C1750A", "3226", BLIST_NOLUN},		/* scanjet iic */
-	{"HP", "C1790A", "", BLIST_NOLUN},		/* scanjet iip */
-	{"HP", "C2500A", "", BLIST_NOLUN},		/* scanjet iicx */
+	{"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN},
 	{"YAMAHA", "CDR100", "1.00", BLIST_NOLUN},	/* locks up */
 	{"YAMAHA", "CDR102", "1.00", BLIST_NOLUN},	/* locks up */
 	{"YAMAHA", "CRW8424S", "1.0", BLIST_NOLUN},	/* locks up */
 	{"YAMAHA", "CRW6416S", "1.0c", BLIST_NOLUN},	/* locks up */
-	{"MITSUMI", "CD-R CR-2201CS", "6119", BLIST_NOLUN},	/* locks up */
-	{"RELISYS", "Scorpio", NULL, BLIST_NOLUN},	/* responds to all lun */
-	{"MICROTEK", "ScanMaker II", "5.61", BLIST_NOLUN},	/* responds to all lun */
-	{"NEC", "D3856", "0009", BLIST_NOLUN},
 
 	/*
 	 * Other types of devices that have special flags.
 	 */
-	{"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN},
-	{"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN},
-	{"IOMEGA", "Io20S         *F", NULL, BLIST_KEY},
-	{"INSITE", "Floptical   F*8I", NULL, BLIST_KEY},
-	{"INSITE", "I325VM", NULL, BLIST_KEY},
-	{"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN},
-	{"MICROP", "4110", NULL, BLIST_NOTQ},
-	{"NRC", "MBR-7", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
-	{"NRC", "MBR-7.4", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
-	{"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
-	{"NAKAMICH", "MJ-4.8S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
-	{"NAKAMICH", "MJ-5.16S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
-	{"PIONEER", "CD-ROM DRM-600", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
-	{"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
-	{"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
-	{"EMULEX", "MD21/S2     ESDI", NULL, BLIST_SINGLELUN},
+	{"ADAPTEC", "AACRAID", NULL, BLIST_FORCELUN},
+	{"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN},
 	{"CANON", "IPUBJD", NULL, BLIST_SPARSELUN},
-	{"nCipher", "Fastness Crypto", NULL, BLIST_FORCELUN},
-	{"DEC", "HSG80", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
+	{"CMD", "CRA-7280", NULL, BLIST_SPARSELUN},	/* CMD RAID Controller */
+	{"CNSI", "G7324", NULL, BLIST_SPARSELUN},	/* Chaparral G7324 RAID */
+	{"CNSi", "G8324", NULL, BLIST_SPARSELUN},	/* Chaparral G8324 RAID */
 	{"COMPAQ", "LOGICAL VOLUME", NULL, BLIST_FORCELUN},
 	{"COMPAQ", "CR3500", NULL, BLIST_FORCELUN},
-	{"NEC", "PD-1 ODX654P", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
-	{"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
-	{"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
-	{"TOSHIBA", "CDROM", NULL, BLIST_ISROM},
-	{"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM},
-	{"MegaRAID", "LD", NULL, BLIST_FORCELUN},
-	{"DGC", "RAID", NULL, BLIST_SPARSELUN},	/* Dell PV 650F, storage on LUN 0 */
-	{"DGC", "DISK", NULL, BLIST_SPARSELUN},	/* Dell PV 650F, no storage on LUN 0 */
+	{"COMPAQ", "MSA1000", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
+	{"COMPAQ", "MSA1000 VOLUME", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
+	{"COMPAQ", "HSV110", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
+	{"DDN", "SAN DataDirector", "*", BLIST_SPARSELUN},
+	{"DEC", "HSG80", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
 	{"DELL", "PV660F", NULL, BLIST_SPARSELUN},
 	{"DELL", "PV660F   PSEUDO", NULL, BLIST_SPARSELUN},
 	{"DELL", "PSEUDO DEVICE .", NULL, BLIST_SPARSELUN},	/* Dell PV 530F */
 	{"DELL", "PV530F", NULL, BLIST_SPARSELUN},
+	{"DELL", "PERCRAID", NULL, BLIST_FORCELUN},
+	{"DGC", "RAID", NULL, BLIST_SPARSELUN},	/* Dell PV 650F, storage on LUN 0 */
+	{"DGC", "DISK", NULL, BLIST_SPARSELUN},	/* Dell PV 650F, no storage on LUN 0 */
 	{"EMC", "SYMMETRIX", NULL, BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_FORCELUN},
+	{"EMULEX", "MD21/S2     ESDI", NULL, BLIST_SINGLELUN},
+	{"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"Generic", "USB Storage-SMC", "0207", BLIST_FORCELUN},
+	{"HITACHI", "DF400", "*", BLIST_SPARSELUN},
+	{"HITACHI", "DF500", "*", BLIST_SPARSELUN},
+	{"HITACHI", "DF600", "*", BLIST_SPARSELUN},
 	{"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN},	/* HP VA7400 */
 	{"HP", "OPEN-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP XP Arrays */
-	{"CMD", "CRA-7280", NULL, BLIST_SPARSELUN},	/* CMD RAID Controller */
-	{"CNSI", "G7324", NULL, BLIST_SPARSELUN},	/* Chaparral G7324 RAID */
-	{"CNSi", "G8324", NULL, BLIST_SPARSELUN},	/* Chaparral G8324 RAID */
-	{"Zzyzx", "RocketStor 500S", NULL, BLIST_SPARSELUN},
-	{"Zzyzx", "RocketStor 2000", NULL, BLIST_SPARSELUN},
-	{"SONY", "TSL", NULL, BLIST_FORCELUN},		/* DDS3 & DDS4 autoloaders */
-	{"DELL", "PERCRAID", NULL, BLIST_FORCELUN},
 	{"HP", "NetRAID-4M", NULL, BLIST_FORCELUN},
-	{"ADAPTEC", "AACRAID", NULL, BLIST_FORCELUN},
-	{"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN},
-	{"COMPAQ", "MSA1000", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
-	{"COMPAQ", "MSA1000 VOLUME", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
-	{"COMPAQ", "HSV110", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
 	{"HP", "HSV100", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
 	{"HP", "C1557A", NULL, BLIST_FORCELUN},
 	{"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN},
-	{"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"DDN", "SAN DataDirector", "*", BLIST_SPARSELUN},
-	{"HITACHI", "DF400", "*", BLIST_SPARSELUN},
-	{"HITACHI", "DF500", "*", BLIST_SPARSELUN},
-	{"HITACHI", "DF600", "*", BLIST_SPARSELUN},
 	{"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"SUN", "T300", "*", BLIST_SPARSELUN},
-	{"SUN", "T4", "*", BLIST_SPARSELUN},
+	{"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
+	{"IOMEGA", "Io20S         *F", NULL, BLIST_KEY},
+	{"INSITE", "Floptical   F*8I", NULL, BLIST_KEY},
+	{"INSITE", "I325VM", NULL, BLIST_KEY},
+	{"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN},
+	{"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+	{"MegaRAID", "LD", NULL, BLIST_FORCELUN},
+	{"MICROP", "4110", NULL, BLIST_NOTQ},
+	{"MYLEX", "DACARMRB", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"nCipher", "Fastness Crypto", NULL, BLIST_FORCELUN},
+	{"NAKAMICH", "MJ-4.8S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+	{"NAKAMICH", "MJ-5.16S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+	{"NEC", "PD-1 ODX654P", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+	{"NRC", "MBR-7", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+	{"NRC", "MBR-7.4", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+	{"PIONEER", "CD-ROM DRM-600", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+	{"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+	{"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+	{"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
 	{"SGI", "RAID3", "*", BLIST_SPARSELUN},
 	{"SGI", "RAID5", "*", BLIST_SPARSELUN},
 	{"SGI", "TP9100", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"SGI", "TP9300", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"SGI", "TP9400", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"SGI", "TP9500", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-	{"MYLEX", "DACARMRB", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN},
+	{"SONY", "TSL", NULL, BLIST_FORCELUN},		/* DDS3 & DDS4 autoloaders */
+	{"SUN", "T300", "*", BLIST_SPARSELUN},
+	{"SUN", "T4", "*", BLIST_SPARSELUN},
+	{"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN},
+	{"TOSHIBA", "CDROM", NULL, BLIST_ISROM},
+	{"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM},
 	{"XYRATEX", "RS", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"Zzyzx", "RocketStor 500S", NULL, BLIST_SPARSELUN},
+	{"Zzyzx", "RocketStor 2000", NULL, BLIST_SPARSELUN},
 	{ NULL, NULL, NULL, 0 },
 };
 
diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
--- a/drivers/scsi/scsi_error.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/scsi_error.c	Wed Mar 10 21:09:42 2004
@@ -37,6 +37,8 @@
 #define SENSE_TIMEOUT (10*HZ)
 #endif
 
+#define START_UNIT_TIMEOUT (30*HZ)
+
 /*
  * These should *probably* be handled by the host itself.
  * Since it is allowed to sleep, it probably should.
@@ -282,6 +284,15 @@
 			(scmd->sense_buffer[13] == 0x01)) {
 			return NEEDS_RETRY;
 		}
+		/*
+		 * if the device is not started, we need to wake
+		 * the error handler to start the motor
+		 */
+		if (scmd->device->allow_restart &&
+		    (scmd->sense_buffer[12] == 0x04) &&
+		    (scmd->sense_buffer[13] == 0x02)) {
+			return FAILED;
+		}
 		return SUCCESS;
 
 		/* these three are not supported */
@@ -829,6 +840,105 @@
 }
 
 /**
+ * scsi_eh_try_stu - Send START_UNIT to device.
+ * @scmd:	Scsi cmd to send START_UNIT
+ *
+ * Return value:
+ *    0 - Device is ready. 1 - Device NOT ready.
+ **/
+static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
+{
+	static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0};
+	int rtn;
+
+	if (!scmd->device->allow_restart)
+		return 1;
+
+	memcpy(scmd->cmnd, stu_command, sizeof(stu_command));
+
+	/*
+	 * zero the sense buffer.  the scsi spec mandates that any
+	 * untransferred sense data should be interpreted as being zero.
+	 */
+	memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
+
+	scmd->request_buffer = NULL;
+	scmd->request_bufflen = 0;
+	scmd->use_sg = 0;
+	scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
+	scmd->underflow = 0;
+	scmd->sc_data_direction = DMA_NONE;
+
+	rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT);
+
+	/*
+	 * when we eventually call scsi_finish, we really wish to complete
+	 * the original request, so let's restore the original data. (db)
+	 */
+	scsi_setup_cmd_retry(scmd);
+
+	/*
+	 * hey, we are done.  let's look to see what happened.
+	 */
+	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n",
+		__FUNCTION__, scmd, rtn));
+	if (rtn == SUCCESS)
+		return 0;
+	return 1;
+}
+
+ /**
+ * scsi_eh_stu - send START_UNIT if needed
+ * @shost:	scsi host being recovered.
+ * @eh_done_q:	list_head for processed commands.
+ *
+ * Notes:
+ *    If commands are failing due to not ready, initializing command required,
+ *	try revalidating the device, which will end up sending a start unit. 
+ **/
+static int scsi_eh_stu(struct Scsi_Host *shost,
+			      struct list_head *work_q,
+			      struct list_head *done_q)
+{
+	struct list_head *lh, *lh_sf;
+	struct scsi_cmnd *scmd, *stu_scmd;
+	struct scsi_device *sdev;
+
+	shost_for_each_device(sdev, shost) {
+		stu_scmd = NULL;
+		list_for_each_entry(scmd, work_q, eh_entry)
+			if (scmd->device == sdev && SCSI_SENSE_VALID(scmd) &&
+			    scsi_check_sense(scmd) == FAILED ) {
+				stu_scmd = scmd;
+				break;
+			}
+
+		if (!stu_scmd)
+			continue;
+
+		SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending START_UNIT to sdev:"
+						  " 0x%p\n", current->comm, sdev));
+
+		if (!scsi_eh_try_stu(stu_scmd)) {
+			if (!sdev->online || !scsi_eh_tur(stu_scmd)) {
+				list_for_each_safe(lh, lh_sf, work_q) {
+					scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
+					if (scmd->device == sdev)
+						scsi_eh_finish_cmd(scmd, done_q);
+				}
+			}
+		} else {
+			SCSI_LOG_ERROR_RECOVERY(3,
+						printk("%s: START_UNIT failed to sdev:"
+						       " 0x%p\n", current->comm, sdev));
+		}
+	}
+
+	return list_empty(work_q);
+}
+
+
+/**
  * scsi_eh_bus_device_reset - send bdr if needed
  * @shost:	scsi host being recovered.
  * @eh_done_q:	list_head for processed commands.
@@ -1033,7 +1143,9 @@
 		if (rtn == SUCCESS) {
 			list_for_each_safe(lh, lh_sf, work_q) {
 				scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
-				if (!scmd->device->online || !scsi_eh_tur(scmd)) 
+				if (!scmd->device->online ||
+				    (!scsi_eh_try_stu(scmd) && !scsi_eh_tur(scmd)) ||
+				    !scsi_eh_tur(scmd))
 					scsi_eh_finish_cmd(scmd, done_q);
 			}
 		} else {
@@ -1181,6 +1293,8 @@
 		 */
 	case DID_SOFT_ERROR:
 		goto maybe_retry;
+	case DID_IMM_RETRY:
+		return NEEDS_RETRY;
 
 	case DID_ERROR:
 		if (msg_byte(scmd->result) == COMMAND_COMPLETE &&
@@ -1401,10 +1515,11 @@
 			       struct list_head *work_q,
 			       struct list_head *done_q)
 {
-	if (!scsi_eh_bus_device_reset(shost, work_q, done_q))
-		if (!scsi_eh_bus_reset(shost, work_q, done_q))
-			if (!scsi_eh_host_reset(work_q, done_q))
-				scsi_eh_offline_sdevs(work_q, done_q);
+	if (!scsi_eh_stu(shost, work_q, done_q))
+		if (!scsi_eh_bus_device_reset(shost, work_q, done_q))
+			if (!scsi_eh_bus_reset(shost, work_q, done_q))
+				if (!scsi_eh_host_reset(work_q, done_q))
+					scsi_eh_offline_sdevs(work_q, done_q);
 }
 
 /**
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/scsi_lib.c	Wed Mar 10 21:09:42 2004
@@ -24,7 +24,7 @@
 #include "scsi_logging.h"
 
 
-#define SG_MEMPOOL_NR		5
+#define SG_MEMPOOL_NR		(sizeof(scsi_sg_pools)/sizeof(struct scsi_host_sg_pool))
 #define SG_MEMPOOL_SIZE		32
 
 struct scsi_host_sg_pool {
@@ -34,9 +34,27 @@
 	mempool_t	*pool;
 };
 
+#if (SCSI_MAX_PHYS_SEGMENTS < 32)
+#error SCSI_MAX_PHYS_SEGMENTS is too small
+#endif
+
 #define SP(x) { x, "sgpool-" #x } 
-struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR] = { 
-	SP(8), SP(16), SP(32), SP(64), SP(MAX_PHYS_SEGMENTS)
+struct scsi_host_sg_pool scsi_sg_pools[] = { 
+	SP(8),
+	SP(16),
+	SP(32),
+#if (SCSI_MAX_PHYS_SEGMENTS > 32)
+	SP(64),
+#if (SCSI_MAX_PHYS_SEGMENTS > 64)
+	SP(128),
+#if (SCSI_MAX_PHYS_SEGMENTS > 128)
+	SP(256),
+#if (SCSI_MAX_PHYS_SEGMENTS > 256)
+#error SCSI_MAX_PHYS_SEGMENTS is too large
+#endif
+#endif
+#endif
+#endif
 }; 	
 #undef SP
 
@@ -558,12 +576,21 @@
 	case 17 ... 32:
 		cmd->sglist_len = 2;
 		break;
+#if (SCSI_MAX_PHYS_SEGMENTS > 32)
 	case 33 ... 64:
 		cmd->sglist_len = 3;
 		break;
-	case 65 ... MAX_PHYS_SEGMENTS:
+#if (SCSI_MAX_PHYS_SEGMENTS > 64)
+	case 65 ... 128:
 		cmd->sglist_len = 4;
 		break;
+#if (SCSI_MAX_PHYS_SEGMENTS  > 128)
+	case 129 ... 256:
+		cmd->sglist_len = 5;
+		break;
+#endif
+#endif
+#endif
 	default:
 		return NULL;
 	}
@@ -917,6 +944,7 @@
 			req->current_nr_sectors);
 
 	/* release the command and kill it */
+	scsi_release_buffers(cmd);
 	scsi_put_command(cmd);
 	return BLKPREP_KILL;
 }
@@ -1285,7 +1313,7 @@
 	blk_queue_prep_rq(q, scsi_prep_fn);
 
 	blk_queue_max_hw_segments(q, shost->sg_tablesize);
-	blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS);
+	blk_queue_max_phys_segments(q, SCSI_MAX_PHYS_SEGMENTS);
 	blk_queue_max_sectors(q, shost->max_sectors);
 	blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
 	blk_queue_segment_boundary(q, shost->dma_boundary);
diff -Nru a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
--- a/drivers/scsi/scsi_priv.h	Wed Mar 10 21:09:43 2004
+++ b/drivers/scsi/scsi_priv.h	Wed Mar 10 21:09:43 2004
@@ -155,6 +155,7 @@
 extern int scsi_sysfs_add_host(struct Scsi_Host *);
 extern int scsi_sysfs_register(void);
 extern void scsi_sysfs_unregister(void);
+extern struct scsi_transport_template blank_transport_template;
 
 extern struct class sdev_class;
 extern struct bus_type scsi_bus_type;
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c	Wed Mar 10 21:09:43 2004
+++ b/drivers/scsi/scsi_scan.c	Wed Mar 10 21:09:43 2004
@@ -35,6 +35,7 @@
 #include <scsi/scsi_driver.h>
 #include <scsi/scsi_devinfo.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h>
 #include "scsi.h"
 
 #include "scsi_priv.h"
@@ -192,7 +193,7 @@
 	struct scsi_device *sdev, *device;
 	unsigned long flags;
 
-	sdev = kmalloc(sizeof(*sdev), GFP_ATOMIC);
+	sdev = kmalloc(sizeof(*sdev) + shost->transportt->size, GFP_ATOMIC);
 	if (!sdev)
 		goto out;
 
@@ -237,6 +238,11 @@
 			goto out_free_queue;
 	}
 
+	if (shost->transportt->setup) {
+		if (shost->transportt->setup(sdev))
+			goto out_cleanup_slave;
+	}
+
 	if (get_device(&sdev->host->shost_gendev)) {
 
 		device_initialize(&sdev->sdev_gendev);
@@ -253,8 +259,15 @@
 		snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE,
 			 "%d:%d:%d:%d", sdev->host->host_no,
 			 sdev->channel, sdev->id, sdev->lun);
+
+		class_device_initialize(&sdev->transport_classdev);
+		sdev->transport_classdev.dev = &sdev->sdev_gendev;
+		sdev->transport_classdev.class = sdev->host->transportt->class;
+		snprintf(sdev->transport_classdev.class_id, BUS_ID_SIZE,
+			 "%d:%d:%d:%d", sdev->host->host_no,
+			 sdev->channel, sdev->id, sdev->lun);
 	} else
-		goto out_cleanup_slave;
+		goto out_cleanup_transport;
 
 	/*
 	 * If there are any same target siblings, add this to the
@@ -283,6 +296,9 @@
 	spin_unlock_irqrestore(shost->host_lock, flags);
 	return sdev;
 
+out_cleanup_transport:
+	if (shost->transportt->cleanup)
+		shost->transportt->cleanup(sdev);
 out_cleanup_slave:
 	if (shost->hostt->slave_destroy)
 		shost->hostt->slave_destroy(sdev);
@@ -744,6 +760,8 @@
 	} else {
 		if (sdev->host->hostt->slave_destroy)
 			sdev->host->hostt->slave_destroy(sdev);
+		if (sdev->host->transportt->cleanup)
+			sdev->host->transportt->cleanup(sdev);
 		put_device(&sdev->sdev_gendev);
 	}
  out:
@@ -1300,5 +1318,7 @@
 
 	if (sdev->host->hostt->slave_destroy)
 		sdev->host->hostt->slave_destroy(sdev);
+	if (sdev->host->transportt->cleanup)
+		sdev->host->transportt->cleanup(sdev);
 	put_device(&sdev->sdev_gendev);
 }
diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- a/drivers/scsi/scsi_sysfs.c	Wed Mar 10 21:09:42 2004
+++ b/drivers/scsi/scsi_sysfs.c	Wed Mar 10 21:09:42 2004
@@ -13,6 +13,7 @@
 #include <linux/device.h>
 
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h>
 #include "scsi.h"
 
 #include "scsi_priv.h"
@@ -58,21 +59,24 @@
  * shost_show_function: macro to create an attr function that can be used to
  * show a non-bit field.
  */
-#define shost_show_function(field, format_string)			\
+#define shost_show_function(name, field, format_string)			\
 static ssize_t								\
-show_##field (struct class_device *class_dev, char *buf)		\
+show_##name (struct class_device *class_dev, char *buf)			\
 {									\
 	struct Scsi_Host *shost = class_to_shost(class_dev);		\
-	return snprintf (buf, 20, format_string, shost->field);	\
+	return snprintf (buf, 20, format_string, shost->field);		\
 }
 
 /*
  * shost_rd_attr: macro to create a function and attribute variable for a
  * read only field.
  */
-#define shost_rd_attr(field, format_string)				\
-	shost_show_function(field, format_string)			\
-static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL)
+#define shost_rd_attr2(name, field, format_string)			\
+	shost_show_function(name, field, format_string)			\
+static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+
+#define shost_rd_attr(field, format_string) \
+shost_rd_attr2(field, field, format_string)
 
 /*
  * Create the actual show/store functions and data structures.
@@ -96,6 +100,7 @@
 shost_rd_attr(cmd_per_lun, "%hd\n");
 shost_rd_attr(sg_tablesize, "%hu\n");
 shost_rd_attr(unchecked_isa_dma, "%d\n");
+shost_rd_attr2(proc_name, hostt->proc_name, "%s\n");
 
 static struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
 	&class_device_attr_unique_id,
@@ -103,6 +108,7 @@
 	&class_device_attr_cmd_per_lun,
 	&class_device_attr_sg_tablesize,
 	&class_device_attr_unchecked_isa_dma,
+	&class_device_attr_proc_name,
 	&class_device_attr_scan,
 	NULL
 };
@@ -344,6 +350,7 @@
  **/
 int scsi_sysfs_add_sdev(struct scsi_device *sdev)
 {
+	struct class_device_attribute **attrs;
 	int error = -EINVAL, i;
 
 	if (sdev->sdev_state != SDEV_CREATED)
@@ -363,6 +370,12 @@
 		goto clean_device;
 	}
 
+	if (sdev->transport_classdev.class) {
+		error = class_device_add(&sdev->transport_classdev);
+		if (error)
+			goto clean_device2;
+	}
+
 	get_device(&sdev->sdev_gendev);
 
 	if (sdev->host->hostt->sdev_attrs) {
@@ -388,10 +401,24 @@
 		}
 	}
 
+ 	if (sdev->transport_classdev.class) {
+ 		attrs = sdev->host->transportt->attrs;
+ 		for (i = 0; attrs[i]; i++) {
+ 			error = class_device_create_file(&sdev->transport_classdev,
+ 							 attrs[i]);
+ 			if (error) {
+ 				scsi_remove_device(sdev);
+				goto out;
+			}
+ 		}
+ 	}
+
  out:
 	return error;
 
-clean_device:
+ clean_device2:
+	class_device_del(&sdev->sdev_classdev);
+ clean_device:
 	sdev->sdev_state = SDEV_CANCEL;
 
 	device_del(&sdev->sdev_gendev);
@@ -409,9 +436,12 @@
 	if (sdev->sdev_state == SDEV_RUNNING || sdev->sdev_state == SDEV_CANCEL) {
 		sdev->sdev_state = SDEV_DEL;
 		class_device_unregister(&sdev->sdev_classdev);
+		class_device_unregister(&sdev->transport_classdev);
 		device_del(&sdev->sdev_gendev);
 		if (sdev->host->hostt->slave_destroy)
 			sdev->host->hostt->slave_destroy(sdev);
+		if (sdev->host->transportt->cleanup)
+			sdev->host->transportt->cleanup(sdev);
 		put_device(&sdev->sdev_gendev);
 	}
 }
@@ -498,3 +528,7 @@
 
 	return 0;
 }
+
+/* A blank transport template that is used in drivers that don't
+ * yet implement Transport Attributes */
+struct scsi_transport_template blank_transport_template = { 0, };
diff -Nru a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/scsi/scsi_transport_fc.c	Wed Mar 10 21:09:43 2004
@@ -0,0 +1,104 @@
+/* 
+ *  FiberChannel transport specific attributes exported to sysfs.
+ *
+ *  Copyright (c) 2003 Silicon Graphics, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
+
+static void transport_class_release(struct class_device *class_dev);
+
+struct class fc_transport_class = {
+	.name = "fc_transport",
+	.release = transport_class_release,
+};
+
+static __init int fc_transport_init(void)
+{
+	return class_register(&fc_transport_class);
+}
+
+static void __exit fc_transport_exit(void)
+{
+	class_unregister(&fc_transport_class);
+}
+
+static int fc_setup_transport_attrs(struct scsi_device *sdev)
+{
+	/* FIXME: Callback into the driver */
+	fc_node_name(sdev) = -1;
+	fc_port_name(sdev) = -1;
+	fc_port_id(sdev) = -1;
+
+	return 0;
+}
+
+static void transport_class_release(struct class_device *class_dev)
+{
+	struct scsi_device *sdev = transport_class_to_sdev(class_dev);
+	put_device(&sdev->sdev_gendev);
+}
+
+#define fc_transport_show_function(field, format_string, cast)			\
+static ssize_t									\
+show_fc_transport_##field (struct class_device *cdev, char *buf)		\
+{										\
+	struct scsi_device *sdev = transport_class_to_sdev(cdev);		\
+	struct fc_transport_attrs *tp;						\
+	tp = (struct fc_transport_attrs *)&sdev->transport_data;		\
+	return snprintf(buf, 20, format_string, cast tp->field);		\
+}
+
+#define fc_transport_rd_attr(field, format_string)				\
+	fc_transport_show_function(field, format_string, )			\
+static CLASS_DEVICE_ATTR( field, S_IRUGO, show_fc_transport_##field, NULL)
+
+#define fc_transport_rd_attr_cast(field, format_string, cast)			\
+	fc_transport_show_function(field, format_string, (cast))		\
+static CLASS_DEVICE_ATTR( field, S_IRUGO, show_fc_transport_##field, NULL)
+
+/* the FiberChannel Tranport Attributes: */
+fc_transport_rd_attr_cast(node_name, "0x%llx\n", unsigned long long);
+fc_transport_rd_attr_cast(port_name, "0x%llx\n", unsigned long long);
+fc_transport_rd_attr(port_id, "0x%06x\n");
+
+struct class_device_attribute *fc_transport_attrs[] = {
+	&class_device_attr_node_name,
+	&class_device_attr_port_name,
+	&class_device_attr_port_id,
+	NULL
+};
+
+struct scsi_transport_template fc_transport_template = {
+	.attrs = fc_transport_attrs,
+	.class = &fc_transport_class,
+	.setup = &fc_setup_transport_attrs,
+	.cleanup = NULL,
+	.size = sizeof(struct fc_transport_attrs) - sizeof(unsigned long),
+};
+EXPORT_SYMBOL(fc_transport_template);
+
+MODULE_AUTHOR("Martin Hicks");
+MODULE_DESCRIPTION("FC Transport Attributes");
+MODULE_LICENSE("GPL");
+
+module_init(fc_transport_init);
+module_exit(fc_transport_exit);
diff -Nru a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/scsi/scsi_transport_spi.c	Wed Mar 10 21:09:43 2004
@@ -0,0 +1,302 @@
+/* 
+ *  Parallel SCSI (SPI) transport specific attributes exported to sysfs.
+ *
+ *  Copyright (c) 2003 Silicon Graphics, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_spi.h>
+
+static void transport_class_release(struct class_device *class_dev);
+
+#define SPI_NUM_ATTRS 10	/* increase this if you add attributes */
+
+struct spi_internal {
+	struct scsi_transport_template t;
+	struct spi_function_template *f;
+	/* The actual attributes */
+	struct class_device_attribute private_attrs[SPI_NUM_ATTRS];
+	/* The array of null terminated pointers to attributes 
+	 * needed by scsi_sysfs.c */
+	struct class_device_attribute *attrs[SPI_NUM_ATTRS + 1];
+};
+
+#define to_spi_internal(tmpl)	container_of(tmpl, struct spi_internal, t)
+
+static const char *const ppr_to_ns[] = {
+	/* The PPR values 0-6 are reserved, fill them in when
+	 * the committee defines them */
+	NULL,			/* 0x00 */
+	NULL,			/* 0x01 */
+	NULL,			/* 0x02 */
+	NULL,			/* 0x03 */
+	NULL,			/* 0x04 */
+	NULL,			/* 0x05 */
+	NULL,			/* 0x06 */
+	"3.125",		/* 0x07 */
+	"6.25",			/* 0x08 */
+	"12.5",			/* 0x09 */
+	"25",			/* 0x0a */
+	"30.3",			/* 0x0b */
+	"50",			/* 0x0c */
+};
+/* The PPR values at which you calculate the period in ns by multiplying
+ * by 4 */
+#define SPI_STATIC_PPR	0x0c
+
+struct class spi_transport_class = {
+	.name = "spi_transport",
+	.release = transport_class_release,
+};
+
+static __init int spi_transport_init(void)
+{
+	return class_register(&spi_transport_class);
+}
+
+static void __exit spi_transport_exit(void)
+{
+	class_unregister(&spi_transport_class);
+}
+
+static int spi_setup_transport_attrs(struct scsi_device *sdev)
+{
+	spi_period(sdev) = -1;	/* illegal value */
+	spi_offset(sdev) = 0;	/* async */
+	spi_width(sdev) = 0;	/* narrow */
+	spi_iu(sdev) = 0;	/* no IU */
+	spi_dt(sdev) = 0;	/* ST */
+	spi_qas(sdev) = 0;
+	spi_wr_flow(sdev) = 0;
+	spi_rd_strm(sdev) = 0;
+	spi_rti(sdev) = 0;
+	spi_pcomp_en(sdev) = 0;
+
+	return 0;
+}
+
+static void transport_class_release(struct class_device *class_dev)
+{
+	struct scsi_device *sdev = transport_class_to_sdev(class_dev);
+	put_device(&sdev->sdev_gendev);
+}
+
+#define spi_transport_show_function(field, format_string)		\
+									\
+static ssize_t								\
+show_spi_transport_##field(struct class_device *cdev, char *buf)	\
+{									\
+	struct scsi_device *sdev = transport_class_to_sdev(cdev);	\
+	struct spi_transport_attrs *tp;					\
+	struct spi_internal *i = to_spi_internal(sdev->host->transportt); \
+	tp = (struct spi_transport_attrs *)&sdev->transport_data;	\
+	if(i->f->get_##field)						\
+		i->f->get_##field(sdev);				\
+	return snprintf(buf, 20, format_string, tp->field);		\
+}
+
+#define spi_transport_store_function(field, format_string)		\
+static ssize_t								\
+store_spi_transport_##field(struct class_device *cdev, const char *buf, \
+			    size_t count)				\
+{									\
+	int val;							\
+	struct scsi_device *sdev = transport_class_to_sdev(cdev);	\
+	struct spi_internal *i = to_spi_internal(sdev->host->transportt); \
+									\
+	val = simple_strtoul(buf, NULL, 0);				\
+	i->f->set_##field(sdev, val);					\
+	return count;							\
+}
+
+#define spi_transport_rd_attr(field, format_string)			\
+	spi_transport_show_function(field, format_string)		\
+	spi_transport_store_function(field, format_string)		\
+static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR,			\
+			 show_spi_transport_##field,			\
+			 store_spi_transport_##field)
+
+/* The Parallel SCSI Tranport Attributes: */
+spi_transport_rd_attr(offset, "%d\n");
+spi_transport_rd_attr(width, "%d\n");
+spi_transport_rd_attr(iu, "%d\n");
+spi_transport_rd_attr(dt, "%d\n");
+spi_transport_rd_attr(qas, "%d\n");
+spi_transport_rd_attr(wr_flow, "%d\n");
+spi_transport_rd_attr(rd_strm, "%d\n");
+spi_transport_rd_attr(rti, "%d\n");
+spi_transport_rd_attr(pcomp_en, "%d\n");
+
+/* Translate the period into ns according to the current spec
+ * for SDTR/PPR messages */
+static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf)
+
+{
+	struct scsi_device *sdev = transport_class_to_sdev(cdev);
+	struct spi_transport_attrs *tp;
+	const char *str;
+	struct spi_internal *i = to_spi_internal(sdev->host->transportt);
+
+	tp = (struct spi_transport_attrs *)&sdev->transport_data;
+
+	if(i->f->get_period)
+		i->f->get_period(sdev);
+
+	switch(tp->period) {
+
+	case 0x07 ... SPI_STATIC_PPR:
+		str = ppr_to_ns[tp->period];
+		if(!str)
+			str = "reserved";
+		break;
+
+
+	case (SPI_STATIC_PPR+1) ... 0xff:
+		return sprintf(buf, "%d\n", tp->period * 4);
+
+	default:
+		str = "unknown";
+	}
+	return sprintf(buf, "%s\n", str);
+}
+
+static ssize_t
+store_spi_transport_period(struct class_device *cdev, const char *buf,
+			    size_t count)
+{
+	struct scsi_device *sdev = transport_class_to_sdev(cdev);
+	struct spi_internal *i = to_spi_internal(sdev->host->transportt);
+	int j, period = -1;
+
+	for(j = 0; j < SPI_STATIC_PPR; j++) {
+		int len;
+
+		if(ppr_to_ns[j] == NULL)
+			continue;
+
+		len = strlen(ppr_to_ns[j]);
+
+		if(strncmp(ppr_to_ns[j], buf, len) != 0)
+			continue;
+
+		if(buf[len] != '\n')
+			continue;
+		
+		period = j;
+		break;
+	}
+
+	if(period == -1) {
+		 int val = simple_strtoul(buf, NULL, 0);
+
+		 
+		 if(val >= (SPI_STATIC_PPR + 1)*4)
+			  period = val/4;
+
+	}
+
+	if(period == -1 || period > 0xff)
+		 return -EINVAL;
+
+	i->f->set_period(sdev, period);
+
+	return count;
+}
+	
+
+	
+		 
+
+
+static CLASS_DEVICE_ATTR(period, S_IRUGO | S_IWUSR, 
+			 show_spi_transport_period,
+			 store_spi_transport_period);
+
+
+struct scsi_transport_template spi_transport_template = {
+	.class = &spi_transport_class,
+	.setup = &spi_setup_transport_attrs,
+	.cleanup = NULL,
+	.size = sizeof(struct spi_transport_attrs) - sizeof(unsigned long),
+};
+
+#define SETUP_ATTRIBUTE(field)						\
+	i->private_attrs[count] = class_device_attr_##field;		\
+	if(!i->f->set_##field) {					\
+		i->private_attrs[count].attr.mode = S_IRUGO;		\
+		i->private_attrs[count].store = NULL;			\
+	}								\
+	i->attrs[count] = &i->private_attrs[count];			\
+	count++
+
+struct scsi_transport_template *
+spi_attach_transport(struct spi_function_template *ft)
+{
+	struct spi_internal *i = kmalloc(sizeof(struct spi_internal),
+					 GFP_KERNEL);
+	int count = 0;
+	if(!i)
+		return NULL;
+
+	memset(i, 0, sizeof(struct spi_internal));
+
+
+	i->t.attrs = &i->attrs[0];
+	i->t.class = &spi_transport_class;
+	i->t.setup = &spi_setup_transport_attrs;
+	i->t.size = sizeof(struct spi_transport_attrs) - sizeof(unsigned long);
+	i->f = ft;
+
+	SETUP_ATTRIBUTE(period);
+	SETUP_ATTRIBUTE(offset);
+	SETUP_ATTRIBUTE(width);
+	SETUP_ATTRIBUTE(iu);
+	SETUP_ATTRIBUTE(dt);
+	SETUP_ATTRIBUTE(qas);
+	SETUP_ATTRIBUTE(wr_flow);
+	SETUP_ATTRIBUTE(rd_strm);
+	SETUP_ATTRIBUTE(rti);
+	SETUP_ATTRIBUTE(pcomp_en);
+
+	/* if you add an attribute but forget to increase SPI_NUM_ATTRS
+	 * this bug will trigger */
+	BUG_ON(count != SPI_NUM_ATTRS);
+
+	i->attrs[count] = NULL;
+
+	return &i->t;
+}
+EXPORT_SYMBOL(spi_attach_transport);
+
+void spi_release_transport(struct scsi_transport_template *t)
+{
+	struct spi_internal *i = to_spi_internal(t);
+
+	kfree(i);
+}
+EXPORT_SYMBOL(spi_release_transport);
+
+
+MODULE_AUTHOR("Martin Hicks");
+MODULE_DESCRIPTION("SPI Transport Attributes");
+MODULE_LICENSE("GPL");
+
+module_init(spi_transport_init);
+module_exit(spi_transport_exit);
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	Wed Mar 10 21:09:43 2004
+++ b/drivers/scsi/sd.c	Wed Mar 10 21:09:43 2004
@@ -19,6 +19,9 @@
  *	   not being read in sd_open. Fix problem where removable media 
  *	   could be ejected after sd_open.
  *	 - Douglas Gilbert <dgilbert@interlog.com> cleanup for lk 2.5.x
+ *	 - Badari Pulavarty <pbadari@us.ibm.com>, Matthew Wilcox 
+ *	   <willy@debian.org>, Kurt Garloff <garloff@suse.de>: 
+ *	   Support 32k/1M disks.
  *
  *	Logging policy (needs CONFIG_SCSI_LOGGING defined):
  *	 - setting up transfer: SCSI_LOG_HLQUEUE levels 1 and 2
@@ -61,7 +64,7 @@
  * Remaining dev_t-handling stuff
  */
 #define SD_MAJORS	16
-#define SD_DISKS	(SD_MAJORS << 4)
+#define SD_DISKS	32768	/* anything between 256 and 262144 */
 
 /*
  * Time out in seconds for disks and Magneto-opticals (which are slower).
@@ -121,6 +124,20 @@
 	.init_command		= sd_init_command,
 };
 
+/* Device no to disk mapping:
+ * 
+ *       major         disc2     disc  p1
+ *   |............|.............|....|....| <- dev_t
+ *    31        20 19          8 7  4 3  0
+ * 
+ * Inside a major, we have 16k disks, however mapped non-
+ * contiguously. The first 16 disks are for major0, the next
+ * ones with major1, ... Disk 256 is for major0 again, disk 272 
+ * for major1, ... 
+ * As we stay compatible with our numbering scheme, we can reuse 
+ * the well-know SCSI majors 8, 65--71, 136--143.
+ */
+
 static int sd_major(int major_idx)
 {
 	switch (major_idx) {
@@ -136,6 +153,14 @@
 	}
 }
 
+static unsigned int make_sd_dev(unsigned int sd_nr, unsigned int part)
+{
+	return  (part & 0xf) | ((sd_nr & 0xf) << 4) |
+		(sd_major((sd_nr & 0xf0) >> 4) << 20) | (sd_nr & 0xfff00);
+}
+
+/* reverse mapping dev -> (sd_nr, part) not currently needed */
+
 #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,kobj);
 
 static inline struct scsi_disk *scsi_disk(struct gendisk *disk)
@@ -1301,7 +1326,7 @@
 	struct scsi_disk *sdkp;
 	struct gendisk *gd;
 	u32 index;
-	int error;
+	int error, devno;
 
 	error = -ENODEV;
 	if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD))
@@ -1319,6 +1344,12 @@
 	kobject_init(&sdkp->kobj);
 	sdkp->kobj.ktype = &scsi_disk_kobj_type;
 
+	/* Note: We can accomodate 64 partitions, but the genhd code
+	 * assumes partitions allocate consecutive minors, which they don't.
+	 * So for now stay with max 16 partitions and leave two spare bits. 
+	 * Later, we may change the genhd code and the alloc_disk() call
+	 * and the ->minors assignment here. 	KG, 2004-02-10
+	 */ 
 	gd = alloc_disk(16);
 	if (!gd)
 		goto out_free;
@@ -1339,16 +1370,23 @@
 	sdkp->index = index;
 	sdkp->openers = 0;
 
-	gd->major = sd_major(index >> 4);
-	gd->first_minor = (index & 15) << 4;
+	devno = make_sd_dev(index, 0);
+	gd->major = MAJOR(devno);
+	gd->first_minor = MINOR(devno);
 	gd->minors = 16;
 	gd->fops = &sd_fops;
 
-	if (index >= 26) {
+	if (index < 26) {
+		sprintf(gd->disk_name, "sd%c", 'a' + index % 26);
+	} else if (index < (26*27)) {
 		sprintf(gd->disk_name, "sd%c%c",
-			'a' + index/26-1,'a' + index % 26);
+			'a' + index / 26 - 1,'a' + index % 26);
 	} else {
-		sprintf(gd->disk_name, "sd%c", 'a' + index % 26);
+		const unsigned int m1 = (index / 26 - 1) / 26 - 1;
+		const unsigned int m2 = (index / 26 - 1) % 26;
+		const unsigned int m3 =  index % 26;
+		sprintf(gd->disk_name, "sd%c%c%c",
+			'a' + m1, 'a' + m2, 'a' + m3);
 	}
 
 	strcpy(gd->devfs_name, sdp->devfs_name);
diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c	Wed Mar 10 21:09:43 2004
+++ b/drivers/scsi/st.c	Wed Mar 10 21:09:43 2004
@@ -17,7 +17,7 @@
    Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
  */
 
-static char *verstr = "20040213";
+static char *verstr = "20040226";
 
 #include <linux/module.h>
 
@@ -121,7 +121,15 @@
 };
 #endif
 
-static char *st_formats[ST_NBR_MODES] ={"", "l", "m", "a"};
+/* Restrict the number of modes so that names for all are assigned */
+#if ST_NBR_MODES > 16
+#error "Maximum number of modes is 16"
+#endif
+/* Bit reversed order to get same names for same minors with all
+   mode counts */
+static char *st_formats[] = {
+	"",  "r", "k", "s", "l", "t", "o", "u",
+	"m", "v", "p", "x", "a", "y", "q", "z"}; 
 
 /* The default definitions have been moved to st_options.h */
 
@@ -3888,8 +3896,11 @@
 				       dev_num);
 				goto out_free_tape;
 			}
-			snprintf(cdev->kobj.name, KOBJ_NAME_LEN, "%sm%d%s", disk->disk_name,
-				 mode, j ? "n" : "");
+			/* Make sure that the minor numbers corresponding to the four
+			   first modes always get the same names */
+			i = mode << (4 - ST_NBR_MODE_BITS);
+			snprintf(cdev->kobj.name, KOBJ_NAME_LEN, "%s%s%s", j ? "n" : "",
+				 disk->disk_name, st_formats[i]);
 			cdev->owner = THIS_MODULE;
 			cdev->ops = &st_fops;
 
@@ -3909,22 +3920,26 @@
 	}
 
 	for (mode = 0; mode < ST_NBR_MODES; ++mode) {
+		/* Make sure that the minor numbers corresponding to the four
+		   first modes always get the same names */
+		i = mode << (4 - ST_NBR_MODE_BITS);
 		/*  Rewind entry  */
-		devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, dev_num + (mode << 5)),
+		devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, 0)),
 			      S_IFCHR | S_IRUGO | S_IWUGO,
-			      "%s/mt%s", SDp->devfs_name, st_formats[mode]);
+			      "%s/mt%s", SDp->devfs_name, st_formats[i]);
 		/*  No-rewind entry  */
-		devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, dev_num + (mode << 5) + 128),
+		devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, 1)),
 			      S_IFCHR | S_IRUGO | S_IWUGO,
-			      "%s/mt%sn", SDp->devfs_name, st_formats[mode]);
+			      "%s/mt%sn", SDp->devfs_name, st_formats[i]);
 	}
 	disk->number = devfs_register_tape(SDp->devfs_name);
 
 	printk(KERN_WARNING
 	"Attached scsi tape %s at scsi%d, channel %d, id %d, lun %d\n",
 	       tape_name(tpnt), SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
-	printk(KERN_WARNING "%s: try direct i/o: %s, max page reachable by HBA %lu\n",
-	       tape_name(tpnt), tpnt->try_dio ? "yes" : "no", tpnt->max_pfn);
+	printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B), max page reachable by HBA %lu\n",
+	       tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
+	       queue_dma_alignment(SDp->request_queue) + 1, tpnt->max_pfn);
 
 	return 0;
 
@@ -3977,8 +3992,9 @@
 			sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
 					  "tape");
 			for (mode = 0; mode < ST_NBR_MODES; ++mode) {
-				devfs_remove("%s/mt%s", SDp->devfs_name, st_formats[mode]);
-				devfs_remove("%s/mt%sn", SDp->devfs_name, st_formats[mode]);
+				j = mode << (4 - ST_NBR_MODE_BITS);
+				devfs_remove("%s/mt%s", SDp->devfs_name, st_formats[j]);
+				devfs_remove("%s/mt%sn", SDp->devfs_name, st_formats[j]);
 				for (j=0; j < 2; j++) {
 					class_simple_device_remove(MKDEV(SCSI_TAPE_MAJOR,
 									 TAPE_MINOR(i, mode, j)));
diff -Nru a/drivers/scsi/st.h b/drivers/scsi/st.h
--- a/drivers/scsi/st.h	Wed Mar 10 21:09:43 2004
+++ b/drivers/scsi/st.h	Wed Mar 10 21:09:43 2004
@@ -50,6 +50,8 @@
 	struct cdev *cdevs[2];  /* Auto-rewind and non-rewind devices */
 } ST_mode;
 
+/* Number of modes can be changed by changing ST_NBR_MODE_BITS. The maximum
+   number of modes is 16 (ST_NBR_MODE_BITS 4) */
 #define ST_NBR_MODE_BITS 2
 #define ST_NBR_MODES (1 << ST_NBR_MODE_BITS)
 #define ST_MODE_SHIFT (7 - ST_NBR_MODE_BITS)
diff -Nru a/include/scsi/scsi.h b/include/scsi/scsi.h
--- a/include/scsi/scsi.h	Wed Mar 10 21:09:43 2004
+++ b/include/scsi/scsi.h	Wed Mar 10 21:09:43 2004
@@ -10,6 +10,12 @@
 
 #include <linux/types.h>
 
+/*
+ *	The maximum sg list length SCSI can cope with
+ *	(currently must be a power of 2 between 32 and 256)
+ */
+#define SCSI_MAX_PHYS_SEGMENTS	MAX_PHYS_SEGMENTS
+
 
 /*
  *	SCSI command lengths
@@ -200,6 +206,7 @@
 #define TYPE_MEDIUM_CHANGER 0x08
 #define TYPE_COMM           0x09    /* Communications device */
 #define TYPE_ENCLOSURE      0x0d    /* Enclosure Services Device */
+#define TYPE_RAID           0x0c
 #define TYPE_NO_LUN         0x7f
 
 /*
@@ -273,6 +280,7 @@
 #define DID_BAD_INTR    0x09	/* Got an interrupt we weren't expecting.  */
 #define DID_PASSTHROUGH 0x0a	/* Force command past mid-layer            */
 #define DID_SOFT_ERROR  0x0b	/* The low level driver just wish a retry  */
+#define DID_IMM_RETRY   0x0c	/* Retry without decrementing retry count  */
 #define DRIVER_OK       0x00	/* Driver status                           */
 
 /*
diff -Nru a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
--- a/include/scsi/scsi_device.h	Wed Mar 10 21:09:42 2004
+++ b/include/scsi/scsi_device.h	Wed Mar 10 21:09:42 2004
@@ -94,6 +94,7 @@
 	unsigned skip_ms_page_8:1;	/* do not use MODE SENSE page 0x08 */
 	unsigned skip_ms_page_3f:1;	/* do not use MODE SENSE page 0x3f */
 	unsigned no_start_on_add:1;	/* do not issue start on add */
+	unsigned allow_restart:1; /* issue START_UNIT in error handler */
 
 	unsigned int device_blocked;	/* Device returned QUEUE_FULL. */
 
@@ -103,12 +104,17 @@
 	struct device		sdev_gendev;
 	struct class_device	sdev_classdev;
 
+	struct class_device	transport_classdev;
+
 	enum scsi_device_state sdev_state;
-};
+	unsigned long		transport_data[0];
+} __attribute__((aligned(sizeof(unsigned long))));
 #define	to_scsi_device(d)	\
 	container_of(d, struct scsi_device, sdev_gendev)
 #define	class_to_sdev(d)	\
 	container_of(d, struct scsi_device, sdev_classdev)
+#define transport_class_to_sdev(class_dev) \
+	container_of(class_dev, struct scsi_device, transport_classdev)
 
 extern struct scsi_device *scsi_add_device(struct Scsi_Host *,
 		uint, uint, uint);
diff -Nru a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
--- a/include/scsi/scsi_host.h	Wed Mar 10 21:09:42 2004
+++ b/include/scsi/scsi_host.h	Wed Mar 10 21:09:42 2004
@@ -11,6 +11,7 @@
 struct scsi_device;
 struct Scsi_Host;
 struct scsi_host_cmd_pool;
+struct scsi_transport_template;
 
 
 /*
@@ -395,6 +396,7 @@
 	unsigned int            eh_kill:1; /* set when killing the eh thread */
 	wait_queue_head_t       host_wait;
 	struct scsi_host_template *hostt;
+	struct scsi_transport_template *transportt;
 	volatile unsigned short host_busy;   /* commands actually active on low-level */
 	volatile unsigned short host_failed; /* commands that failed. */
     
diff -Nru a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_transport.h	Wed Mar 10 21:09:43 2004
@@ -0,0 +1,41 @@
+/* 
+ *  Transport specific attributes.
+ *
+ *  Copyright (c) 2003 Silicon Graphics, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef SCSI_TRANSPORT_H
+#define SCSI_TRANSPORT_H
+
+struct scsi_transport_template {
+	/* The NULL terminated list of transport attributes
+	 * that should be exported.
+	 */
+	struct class_device_attribute **attrs;
+
+	/* The transport class that the device is in */
+	struct class *class;
+
+	/* Constructor/Destructor functions */
+	int (* setup)(struct scsi_device *);
+	void (* cleanup)(struct scsi_device *);
+	/* The size of the specific transport attribute structure (a
+	 * space of this size will be left at the end of the
+	 * scsi_device structure */
+	int	size;
+};
+
+#endif /* SCSI_TRANSPORT_H */
diff -Nru a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_transport_fc.h	Wed Mar 10 21:09:43 2004
@@ -0,0 +1,38 @@
+/* 
+ *  FiberChannel transport specific attributes exported to sysfs.
+ *
+ *  Copyright (c) 2003 Silicon Graphics, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef SCSI_TRANSPORT_FC_H
+#define SCSI_TRANSPORT_FC_H
+
+struct scsi_transport_template;
+
+struct fc_transport_attrs {
+	int port_id;
+	uint64_t node_name;
+	uint64_t port_name;
+};
+
+/* accessor functions */
+#define fc_port_id(x)	(((struct fc_transport_attrs *)&(x)->transport_data)->port_id)
+#define fc_node_name(x)	(((struct fc_transport_attrs *)&(x)->transport_data)->node_name)
+#define fc_port_name(x)	(((struct fc_transport_attrs *)&(x)->transport_data)->port_name)
+
+extern struct scsi_transport_template fc_transport_template;
+
+#endif /* SCSI_TRANSPORT_FC_H */
diff -Nru a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_transport_spi.h	Wed Mar 10 21:09:43 2004
@@ -0,0 +1,79 @@
+/* 
+ *  Parallel SCSI (SPI) transport specific attributes exported to sysfs.
+ *
+ *  Copyright (c) 2003 Silicon Graphics, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef SCSI_TRANSPORT_SPI_H
+#define SCSI_TRANSPORT_SPI_H
+
+#include <linux/config.h>
+
+struct scsi_transport_template;
+
+struct spi_transport_attrs {
+	int period;		/* value in the PPR/SDTR command */
+	int offset;
+	int width:1;		/* 0 - narrow, 1 - wide */
+	int iu:1;		/* Information Units enabled */
+	int dt:1;		/* DT clocking enabled */
+	int qas:1;		/* Quick Arbitration and Selection enabled */
+	int wr_flow:1;		/* Write Flow control enabled */
+	int rd_strm:1;		/* Read streaming enabled */
+	int rti:1;		/* Retain Training Information */
+	int pcomp_en:1;		/* Precompensation enabled */
+};
+
+/* accessor functions */
+#define spi_period(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->period)
+#define spi_offset(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->offset)
+#define spi_width(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->width)
+#define spi_iu(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->iu)
+#define spi_dt(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->dt)
+#define spi_qas(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->qas)
+#define spi_wr_flow(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->wr_flow)
+#define spi_rd_strm(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->rd_strm)
+#define spi_rti(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->rti)
+#define spi_pcomp_en(x)	(((struct spi_transport_attrs *)&(x)->transport_data)->pcomp_en)
+
+/* The functions by which the transport class and the driver communicate */
+struct spi_function_template {
+	void	(*get_period)(struct scsi_device *);
+	void	(*set_period)(struct scsi_device *, int);
+	void	(*get_offset)(struct scsi_device *);
+	void	(*set_offset)(struct scsi_device *, int);
+	void	(*get_width)(struct scsi_device *);
+	void	(*set_width)(struct scsi_device *, int);
+	void	(*get_iu)(struct scsi_device *);
+	void	(*set_iu)(struct scsi_device *, int);
+	void	(*get_dt)(struct scsi_device *);
+	void	(*set_dt)(struct scsi_device *, int);
+	void	(*get_qas)(struct scsi_device *);
+	void	(*set_qas)(struct scsi_device *, int);
+	void	(*get_wr_flow)(struct scsi_device *);
+	void	(*set_wr_flow)(struct scsi_device *, int);
+	void	(*get_rd_strm)(struct scsi_device *);
+	void	(*set_rd_strm)(struct scsi_device *, int);
+	void	(*get_rti)(struct scsi_device *);
+	void	(*set_rti)(struct scsi_device *, int);
+	void	(*get_pcomp_en)(struct scsi_device *);
+	void	(*set_pcomp_en)(struct scsi_device *, int);
+};
+
+struct scsi_transport_template *spi_attach_transport(struct spi_function_template *);
+void spi_release_transport(struct scsi_transport_template *);
+
+#endif /* SCSI_TRANSPORT_SPI_H */