fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / message / fusion / mptbase.h
index 8a84b72..e316708 100644 (file)
@@ -5,15 +5,9 @@
  *          LSIFC9xx/LSI409xx Fibre Channel
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
- *  Credits:
- *     (see mptbase.c)
- *
- *  Copyright (c) 1999-2004 LSI Logic Corporation
- *  Originally By: Steven J. Ralston
- *  (mailto:sjralston1@netscape.net)
+ *  Copyright (c) 1999-2007 LSI Logic Corporation
  *  (mailto:mpt_linux_developer@lsil.com)
  *
- *  $Id: mptbase.h,v 1.144 2003/01/28 21:31:56 pdelaney Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
 #define MPTBASE_H_INCLUDED
 /*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#include <linux/version.h>
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 
-#include "scsi3.h"             /* SCSI defines */
-
 #include "lsi/mpi_type.h"
 #include "lsi/mpi.h"           /* Fusion MPI(nterface) basic defs */
 #include "lsi/mpi_ioc.h"       /* Fusion MPT IOC(ontroller) defs */
@@ -73,7 +63,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"
+#include "lsi/mpi_sas.h"       /* SAS support */
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
 #endif
 
 #ifndef COPYRIGHT
-#define COPYRIGHT      "Copyright (c) 1999-2004 " MODULEAUTHOR
+#define COPYRIGHT      "Copyright (c) 1999-2007 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON       "3.01.09"
-#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.01.09"
+#define MPT_LINUX_VERSION_COMMON       "3.04.03"
+#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.04.03"
 #define WHAT_MAGIC_STRING              "@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
 #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_REPLY_FRAME_SIZE          0x50  /* Must be a multiple of 8 */
 
 #define  MPT_SG_REQ_128_SCALE          1
 #define  MPT_SG_REQ_96_SCALE           2
 typedef enum {
        MPTBASE_DRIVER,         /* MPT base class */
        MPTCTL_DRIVER,          /* MPT ioctl class */
-       MPTSCSIH_DRIVER,        /* MPT SCSI host (initiator) class */
+       MPTSPI_DRIVER,          /* MPT SPI host class */
+       MPTFC_DRIVER,           /* MPT FC host class */
+       MPTSAS_DRIVER,          /* MPT SAS host class */
        MPTLAN_DRIVER,          /* MPT LAN class */
        MPTSTM_DRIVER,          /* MPT SCSI target mode class */
-       MPTDMP_DRIVER,          /* MPT Dynamic Multi-pathing class */
        MPTUNKNOWN_DRIVER
 } MPT_DRIVER_CLASS;
 
 struct mpt_pci_driver{
        int  (*probe) (struct pci_dev *dev, const struct pci_device_id *id);
        void (*remove) (struct pci_dev *dev);
-       void (*shutdown) (struct device * dev);
-#ifdef CONFIG_PM
-       int  (*resume) (struct pci_dev *dev);
-       int  (*suspend) (struct pci_dev *dev, u32 state);
-#endif
 };
 
 /*
@@ -228,8 +214,7 @@ struct mpt_pci_driver{
 
 typedef union _MPT_FRAME_TRACKER {
        struct {
-               struct _MPT_FRAME_HDR   *forw;
-               struct _MPT_FRAME_HDR   *back;
+               struct list_head        list;
                u32                      arg1;
                u32                      pad;
                void                    *argp1;
@@ -292,15 +277,6 @@ typedef struct _MPT_FRAME_HDR {
 
 #define MPT_REQ_MSGFLAGS_DROPME                0x80
 
-/* Used for tracking the free request frames
- * and free reply frames.
- */
-typedef struct _MPT_Q_TRACKER {
-       MPT_FRAME_HDR   *head;
-       MPT_FRAME_HDR   *tail;
-} MPT_Q_TRACKER;
-
-
 typedef struct _MPT_SGL_HDR {
        SGESimple32_t    sge[1];
 } MPT_SGL_HDR;
@@ -309,44 +285,6 @@ typedef struct _MPT_SGL64_HDR {
        SGESimple64_t    sge[1];
 } MPT_SGL64_HDR;
 
-
-typedef struct _Q_ITEM {
-       struct _Q_ITEM  *forw;
-       struct _Q_ITEM  *back;
-} Q_ITEM;
-
-typedef struct _Q_TRACKER {
-       struct _Q_ITEM  *head;
-       struct _Q_ITEM  *tail;
-} Q_TRACKER;
-
-typedef struct _MPT_DONE_Q {
-       struct _MPT_DONE_Q      *forw;
-       struct _MPT_DONE_Q      *back;
-       void                    *argp;
-} MPT_DONE_Q;
-
-typedef struct _DONE_Q_TRACKER {
-       MPT_DONE_Q      *head;
-       MPT_DONE_Q      *tail;
-} DONE_Q_TRACKER;
-
-/*
- *  Chip-specific stuff... FC929 delineates break between
- *  FC and Parallel SCSI parts. Do NOT re-order.
- */
-
-typedef enum {
-       FC919X = 0x0819,
-       FC929X = 0x0829,
-       FC909 = 0x0909,
-       FC919 = 0x0919,
-       FC929 = 0x0929,
-       C1030 = 0x1030,
-       C1035 = 0x1035,
-       FCUNK = 0xFBAD
-} CHIP_TYPE;
-
 /*
  *  System interface register set
  */
@@ -369,7 +307,8 @@ typedef struct _SYSIF_REGS
        u32     HostIndex;      /* 50     Host Index register        */
        u32     Reserved4[15];  /* 54-8F                             */
        u32     Fubar;          /* 90     For Fubar usage            */
-       u32     Reserved5[27];  /* 94-FF                             */
+       u32     Reserved5[1050];/* 94-10F8                           */
+       u32     Reset_1078;     /* 10FC   Reset 1078                 */
 } SYSIF_REGS;
 
 /*
@@ -381,73 +320,37 @@ typedef struct _SYSIF_REGS
 /*
  *     Dynamic Multi-Pathing specific stuff...
  */
-#define DMP_MAX_PATHS  8
-
-typedef struct _PathInfo {
-       u8               ioc;
-       u8               target;
-       u8               pad;
-       u8               pflags;
-} PathInfo;
-
-#define PATHINFO_FLAGS_OWNED           0x01
-#define PATHINFO_FLAGS_EXISTS          0x02
-#define PATHINFO_FLAGS_AVAILABLE       0x04
-#define PATHINFO_FLAGS_SECONDARY       0x08
-
-#define PFLAGS_EXISTS_AND_AVAIL                (PATHINFO_FLAGS_EXISTS|PATHINFO_FLAGS_AVAILABLE)
-#define PFLAGS_AVAIL_AND_OWNED         (PATHINFO_FLAGS_AVAILABLE|PATHINFO_FLAGS_OWNED)
-
-typedef struct _ScsiCmndTracker {
-       void                    *head;
-       void                    *tail;
-} ScsiCmndTracker;
 
+/* VirtTarget negoFlags field */
+#define MPT_TARGET_NO_NEGO_WIDE                0x01
+#define MPT_TARGET_NO_NEGO_SYNC                0x02
+#define MPT_TARGET_NO_NEGO_QAS         0x04
+#define MPT_TAPE_NEGO_IDP              0x08
 
 /*
  *     VirtDevice - FC LUN device or SCSI target device
- *     (used to be FCSCSI_TARGET)
  */
-typedef struct _VirtDevice {
-       struct _VirtDevice      *forw;
-       struct _VirtDevice      *back;
-       struct scsi_device      *device;
-       rwlock_t                 VdevLock;
-       int                      ref_cnt;
+typedef struct _VirtTarget {
+       struct scsi_target      *starget;
        u8                       tflags;
        u8                       ioc_id;
        u8                       target_id;
        u8                       bus_id;
        u8                       minSyncFactor; /* 0xFF is async */
        u8                       maxOffset;     /* 0 if async */
-       u8                       maxWidth;      /* 0 if narrow, 1 if wide*/
-       u8                       negoFlags;     /* bit field, 0 if WDTR/SDTR/QAS allowed */
+       u8                       maxWidth;      /* 0 if narrow, 1 if wide */
+       u8                       negoFlags;     /* bit field, see above */
        u8                       raidVolume;    /* set, if RAID Volume */
        u8                       type;          /* byte 0 of Inquiry data */
-       u8                       cflags;        /* controller flags */
-       u8                       rsvd1raid;
-       int                      npaths;
-       u16                      fc_phys_lun;
-       u16                      fc_xlat_lun;
-       int                      stall_detected;
-       PathInfo                 path[DMP_MAX_PATHS];
-       struct timer_list        stall_timer;
-       struct timer_list        retry_timer;
-       struct timer_list        gone_timer;
-       ScsiCmndTracker          WaitQ;
-       ScsiCmndTracker          SentQ;
-       ScsiCmndTracker          DoneQ;
+       u8                       deleted;       /* target in process of being removed */
        u32                      num_luns;
        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
-                  as they are treateed as a single entity in the code */
-       u8                       uniq_prepad[8];
-       u8                       uniq_data[20];
-       u8                       pad2[4];
+} VirtTarget;
+
+typedef struct _VirtDevice {
+       VirtTarget              *vtarget;
+       u8                       configured_lun;
+       u32                      lun;
 } VirtDevice;
 
 /*
@@ -459,18 +362,8 @@ typedef struct _VirtDevice {
 #define MPT_TARGET_FLAGS_Q_YES         0x08
 #define MPT_TARGET_FLAGS_VALID_56      0x10
 #define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20
-
-#define MPT_TARGET_NO_NEGO_WIDE                0x01
-#define MPT_TARGET_NO_NEGO_SYNC                0x02
-#define MPT_TARGET_NO_NEGO_QAS         0x04
-
-typedef struct _VirtDevTracker {
-       struct _VirtDevice      *head;
-       struct _VirtDevice      *tail;
-       rwlock_t                 VlistLock;
-       int                      pad;
-} VirtDevTracker;
-
+#define MPT_TARGET_FLAGS_RAID_COMPONENT        0x40
+#define MPT_TARGET_FLAGS_LED_ON                0x80
 
 /*
  *     /proc/mpt interface
@@ -513,7 +406,6 @@ do { \
 
 typedef struct _MPT_IOCTL {
        struct _MPT_ADAPTER     *ioc;
-       struct timer_list        timer;         /* timer function for this adapter */
        u8                       ReplyFrame[MPT_DEFAULT_FRAME_SIZE];    /* reply frame data */
        u8                       sense[MPT_SENSE_BUFFER_ALLOC];
        int                      wait_done;     /* wake-up value for this ioc */
@@ -521,14 +413,24 @@ typedef struct _MPT_IOCTL {
        u8                       status;        /* current command status */
        u8                       reset;         /* 1 if bus reset allowed */
        u8                       target;        /* target for reset */
-       void                    *tmPtr;
-       struct timer_list        TMtimer;       /* timer function for this adapter */
+       struct mutex             ioctl_mutex;
 } MPT_IOCTL;
 
+#define MPT_SAS_MGMT_STATUS_RF_VALID   0x02    /* The Reply Frame is VALID */
+#define MPT_SAS_MGMT_STATUS_COMMAND_GOOD       0x10    /* Command Status GOOD */
+#define MPT_SAS_MGMT_STATUS_TM_FAILED  0x40    /* User TM request failed */
+
+typedef struct _MPT_SAS_MGMT {
+       struct mutex             mutex;
+       struct completion        done;
+       u8                       reply[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */
+       u8                       status;        /* current command status */
+}MPT_SAS_MGMT;
+
 /*
  *  Event Structure and define
  */
-#define MPTCTL_EVENT_LOG_SIZE          (0x0000000A)
+#define MPTCTL_EVENT_LOG_SIZE          (0x000000032)
 typedef struct _mpt_ioctl_events {
        u32     event;          /* Specified by define above */
        u32     eventContext;   /* Index or counter */
@@ -545,27 +447,16 @@ typedef struct _mpt_ioctl_events {
  *     Substructure to store SCSI specific configuration page data
  */
                                                /* dvStatus defines: */
-#define MPT_SCSICFG_NEGOTIATE          0x01    /* Negotiate on next IO */
-#define MPT_SCSICFG_NEED_DV            0x02    /* Schedule DV */
-#define MPT_SCSICFG_DV_PENDING         0x04    /* DV on this physical id pending */
-#define MPT_SCSICFG_DV_NOT_DONE                0x08    /* DV has not been performed */
-#define MPT_SCSICFG_BLK_NEGO           0x10    /* WriteSDP1 with WDTR and SDTR disabled */
-#define MPT_SCSICFG_RELOAD_IOC_PG3     0x20    /* IOC Pg 3 data is obsolete */
-                                               /* Args passed to writeSDP1: */
 #define MPT_SCSICFG_USE_NVRAM          0x01    /* WriteSDP1 using NVRAM */
 #define MPT_SCSICFG_ALL_IDS            0x02    /* WriteSDP1 to all IDS */
 /* #define MPT_SCSICFG_BLK_NEGO                0x10       WriteSDP1 with WDTR and SDTR disabled */
 
-typedef        struct _ScsiCfgData {
+typedef        struct _SpiCfgData {
        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 */
        u8               maxSyncOffset;         /* 0 if async */
        u8               maxBusWidth;           /* 0 if narrow, 1 if wide */
@@ -575,55 +466,99 @@ typedef   struct _ScsiCfgData {
        u8               sdp0version;           /* SDP0 version */
        u8               sdp0length;            /* SDP0 length  */
        u8               dvScheduled;           /* 1 if scheduled */
-       u8               forceDv;               /* 1 to force DV scheduling */
        u8               noQas;                 /* Disable QAS for this adapter */
-       u8               Saf_Te;                /* 1 to force all Processors as SAF-TE if Inquiry data length is too short to check for SAF-TE */
+       u8               Saf_Te;                /* 1 to force all Processors as
+                                                * SAF-TE if Inquiry data length
+                                                * is too short to check for SAF-TE
+                                                */
+       u8               bus_reset;             /* 1 to allow bus reset */
        u8               rsvd[1];
-} ScsiCfgData;
+}SpiCfgData;
+
+typedef        struct _SasCfgData {
+       u8               ptClear;               /* 1 to automatically clear the
+                                                * persistent table.
+                                                * 0 to disable
+                                                * automatic clearing.
+                                                */
+}SasCfgData;
+
+typedef        struct _RaidCfgData {
+       IOCPage2_t      *pIocPg2;               /* table of Raid Volumes */
+       IOCPage3_t      *pIocPg3;               /* table of physical disks */
+       int              isRaid;                /* bit field, 1 if RAID */
+}RaidCfgData;
+
+typedef struct _FcCfgData {
+       /* will ultimately hold fc_port_page0 also */
+       struct {
+               FCPortPage1_t   *data;
+               dma_addr_t       dma;
+               int              pg_sz;
+       }                        fc_port_page1[2];
+} FcCfgData;
+
+#define MPT_RPORT_INFO_FLAGS_REGISTERED        0x01    /* rport registered */
+#define MPT_RPORT_INFO_FLAGS_MISSING   0x02    /* missing from DevPage0 scan */
+
+/*
+ * data allocated for each fc rport device
+ */
+struct mptfc_rport_info
+{
+       struct list_head list;
+       struct fc_rport *rport;
+       struct scsi_target *starget;
+       FCDevicePage0_t pg0;
+       u8              flags;
+};
 
 /*
  *  Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
  */
 typedef struct _MPT_ADAPTER
 {
-       struct _MPT_ADAPTER     *forw;
-       struct _MPT_ADAPTER     *back;
        int                      id;            /* Unique adapter id N {0,1,2,...} */
        int                      pci_irq;       /* This irq           */
        char                     name[MPT_NAME_LENGTH]; /* "iocN"             */
        char                    *prod_name;     /* "LSIFC9x9"         */
-       volatile SYSIF_REGS     *chip;          /* == c8817000 (mmap) */
-       volatile SYSIF_REGS     *pio_chip;      /* Programmed IO (downloadboot) */
+       SYSIF_REGS __iomem      *chip;          /* == c8817000 (mmap) */
+       SYSIF_REGS __iomem      *pio_chip;      /* Programmed IO (downloadboot) */
+       u8                       bus_type;
        u32                      mem_phys;      /* == f4020000 (mmap) */
        u32                      pio_mem_phys;  /* Programmed IO (downloadboot) */
        int                      mem_size;      /* mmap memory size */
        int                      alloc_total;
        u32                      last_state;
        int                      active;
-       u8                      *fifo_pool;     /* dma pool for fifo's */
-       dma_addr_t               fifo_pool_dma;
-       int                      fifo_pool_sz;  /* allocated size */
-       u8                      *chain_alloc;   /* chain buffer alloc ptr */
-       dma_addr_t              chain_alloc_dma;
-       int                     chain_alloc_sz;
-       u8                      *reply_alloc;   /* Reply frames alloc ptr */
-       dma_addr_t               reply_alloc_dma;
+       u8                      *alloc;         /* frames alloc ptr */
+       dma_addr_t               alloc_dma;
+       u32                      alloc_sz;
        MPT_FRAME_HDR           *reply_frames;  /* Reply msg frames - rounded up! */
-       dma_addr_t               reply_frames_dma;
        u32                      reply_frames_low_dma;
        int                      reply_depth;   /* Num Allocated reply frames */
        int                      reply_sz;      /* Reply frame size */
-       CHIP_TYPE                chip_type;
+       int                      num_chain;     /* Number of chain buffers */
+               /* Pool of buffers for chaining. ReqToChain
+                * and ChainToChain track index of chain buffers.
+                * ChainBuffer (DMA) virt/phys addresses.
+                * FreeChainQ (lock) locking mechanisms.
+                */
+       int                     *ReqToChain;
+       int                     *RequestNB;
+       int                     *ChainToChain;
+       u8                      *ChainBuffer;
+       dma_addr_t               ChainBufferDMA;
+       struct list_head         FreeChainQ;
+       spinlock_t               FreeChainQlock;
                /* We (host driver) get to manage our own RequestQueue! */
-       u8                      *req_alloc;     /* Request frames alloc ptr */
-       dma_addr_t               req_alloc_dma;
-       MPT_FRAME_HDR           *req_frames;    /* Request msg frames - rounded up! */
        dma_addr_t               req_frames_dma;
+       MPT_FRAME_HDR           *req_frames;    /* Request msg frames - rounded up! */
        u32                      req_frames_low_dma;
        int                      req_depth;     /* Number of request frames */
        int                      req_sz;        /* Request frame size (bytes) */
        spinlock_t               FreeQlock;
-       MPT_Q_TRACKER            FreeQ;
+       struct list_head         FreeQ;
                /* Pool of SCSI sense buffers for commands coming from
                 * the SCSI mid-layer.  We have one 256 byte sense buffer
                 * for each REQ entry.
@@ -631,11 +566,17 @@ typedef struct _MPT_ADAPTER
        u8                      *sense_buf_pool;
        dma_addr_t               sense_buf_pool_dma;
        u32                      sense_buf_low_dma;
+       u8                      *HostPageBuffer; /* SAS - host page buffer support */
+       u32                     HostPageBuffer_sz;
+       dma_addr_t              HostPageBuffer_dma;
        int                      mtrr_reg;
        struct pci_dev          *pcidev;        /* struct pci_dev pointer */
-       u8                      *memmap;        /* mmap address */
+       u8                      __iomem *memmap;        /* mmap address */
        struct Scsi_Host        *sh;            /* Scsi Host pointer */
-       ScsiCfgData             spi_data;       /* Scsi config. data */
+       SpiCfgData              spi_data;       /* Scsi config. data */
+       RaidCfgData             raid_data;      /* Raid config. data */
+       SasCfgData              sas_data;       /* Sas config. data */
+       FcCfgData               fc_data;        /* Fc config. data */
        MPT_IOCTL               *ioctl;         /* ioctl data pointer */
        struct proc_dir_entry   *ioc_dentry;
        struct _MPT_ADAPTER     *alt_ioc;       /* ptr to 929 bound adapter port */
@@ -645,45 +586,65 @@ typedef struct _MPT_ADAPTER
        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 */
        u8                      *cached_fw;     /* Pointer to FW */
        dma_addr_t              cached_fw_dma;
-       Q_TRACKER                configQ;       /* linked list of config. requests */
+       struct list_head         configQ;       /* linked list of config. requests */
        int                      hs_reply_idx;
 #ifndef MFCNT
        u32                      pad0;
 #else
        u32                      mfcnt;
 #endif
+       u32                      NB_for_64_byte_frame;
        u32                      hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
        u16                      hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
        IOCFactsReply_t          facts;
        PortFactsReply_t         pfacts[2];
        FCPortPage0_t            fc_port_page0[2];
+       struct timer_list        persist_timer; /* persist table timer */
+       int                      persist_wait_done; /* persist completion flag */
+       u8                       persist_reply_frame[MPT_DEFAULT_FRAME_SIZE]; /* persist reply */
        LANPage0_t               lan_cnfg_page0;
        LANPage1_t               lan_cnfg_page1;
-#ifdef CONFIG_PM
-       u32                      PciState[64];     /* save PCI state to this area */
-#endif
+       /*
+        * Description: errata_flag_1064
+        * If a PCIX read occurs within 1 or 2 cycles after the chip receives
+        * a split completion for a read data, an internal address pointer incorrectly
+        * increments by 32 bytes
+        */
+       int                      errata_flag_1064;
+       int                      aen_event_read_flag; /* flag to indicate event log was read*/
        u8                       FirstWhoInit;
        u8                       upload_fw;     /* If set, do a fw upload */
        u8                       reload_fw;     /* Force a FW Reload on next reset */
-       u8                       pad1[5];
-       struct list_head         list; 
+       u8                       NBShiftFactor;  /* NB Shift Factor based on Block Size (Facts)  */
+       u8                       pad1[4];
+       int                      DoneCtx;
+       int                      TaskCtx;
+       int                      InternalCtx;
+       spinlock_t               initializing_hba_lock;
+       int                      initializing_hba_lock_flag;
+       struct list_head         list;
+       struct net_device       *netdev;
+       struct list_head         sas_topology;
+       struct mutex             sas_topology_mutex;
+       struct mutex             sas_discovery_mutex;
+       u8                       sas_discovery_runtime;
+       u8                       sas_discovery_ignore_events;
+       u16                      handle;
+       int                      sas_index; /* index refrencing */
+       MPT_SAS_MGMT             sas_mgmt;
+       struct work_struct       sas_persist_task;
+
+       struct work_struct       fc_setup_reset_work;
+       struct list_head         fc_rports;
+       spinlock_t               fc_rescan_work_lock;
+       struct work_struct       fc_rescan_work;
+       char                     fc_rescan_work_q_name[KOBJ_NAME_LEN];
+       struct workqueue_struct *fc_rescan_work_q;
 } MPT_ADAPTER;
 
-
-typedef struct _MPT_ADAPTER_TRACKER {
-       MPT_ADAPTER     *head;
-       MPT_ADAPTER     *tail;
-} MPT_ADAPTER_TRACKER;
-
 /*
  *  New return value convention:
  *    1 = Ok to free associated request frame
@@ -757,10 +718,10 @@ typedef struct _mpt_sge {
 #define dexitprintk(x)
 #endif
 
-#ifdef MPT_DEBUG_RESET
-#define drsprintk(x)  printk x
+#if defined MPT_DEBUG_FAIL || defined (MPT_DEBUG_SG)
+#define dfailprintk(x) printk x
 #else
-#define drsprintk(x)
+#define dfailprintk(x)
 #endif
 
 #ifdef MPT_DEBUG_HANDSHAKE
@@ -769,11 +730,40 @@ typedef struct _mpt_sge {
 #define dhsprintk(x)
 #endif
 
+#if defined(MPT_DEBUG_EVENTS) || defined(MPT_DEBUG_VERBOSE_EVENTS)
+#define devtprintk(x)  printk x
+#else
+#define devtprintk(x)
+#endif
+
+#ifdef MPT_DEBUG_VERBOSE_EVENTS
+#define devtverboseprintk(x)  printk x
+#else
+#define devtverboseprintk(x)
+#endif
+
+#ifdef MPT_DEBUG_RESET
+#define drsprintk(x)  printk x
+#else
+#define drsprintk(x)
+#endif
+
 //#if defined(MPT_DEBUG) || defined(MPT_DEBUG_MSG_FRAME)
 #if defined(MPT_DEBUG_MSG_FRAME)
 #define dmfprintk(x)  printk x
+#define DBG_DUMP_REQUEST_FRAME(mfp) \
+       {       int  i, n = 24;                                         \
+               u32 *m = (u32 *)(mfp);                                  \
+               for (i=0; i<n; i++) {                                   \
+                       if (i && ((i%8)==0))                            \
+                               printk("\n");                           \
+                       printk("%08x ", le32_to_cpu(m[i]));             \
+               }                                                       \
+               printk("\n");                                           \
+       }
 #else
 #define dmfprintk(x)
+#define DBG_DUMP_REQUEST_FRAME(mfp)
 #endif
 
 #ifdef MPT_DEBUG_IRQ
@@ -794,13 +784,18 @@ typedef struct _mpt_sge {
 #define ddlprintk(x)
 #endif
 
-
 #ifdef MPT_DEBUG_DV
 #define ddvprintk(x)  printk x
 #else
 #define ddvprintk(x)
 #endif
 
+#ifdef MPT_DEBUG_NEGO
+#define dnegoprintk(x)  printk x
+#else
+#define dnegoprintk(x)
+#endif
+
 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
 #define ddvtprintk(x)  printk x
 #else
@@ -813,16 +808,46 @@ typedef struct _mpt_sge {
 #define dctlprintk(x)
 #endif
 
-#ifdef MPT_DEBUG_RESET
-#define dtmprintk(x) printk x
+#ifdef MPT_DEBUG_REPLY
+#define dreplyprintk(x) printk x
 #else
-#define dtmprintk(x)
+#define dreplyprintk(x)
+#endif
+
+#ifdef DMPT_DEBUG_FC
+#define dfcprintk(x) printk x
+#else
+#define dfcprintk(x)
 #endif
 
-#ifdef MPT_DEBUG_NEH
-#define nehprintk(x) printk x
+#ifdef MPT_DEBUG_TM
+#define dtmprintk(x) printk x
+#define DBG_DUMP_TM_REQUEST_FRAME(mfp) \
+       {       u32 *m = (u32 *)(mfp);                                  \
+               int  i, n = 13;                                         \
+               printk("TM_REQUEST:\n");                                \
+               for (i=0; i<n; i++) {                                   \
+                       if (i && ((i%8)==0))                            \
+                               printk("\n");                           \
+                       printk("%08x ", le32_to_cpu(m[i]));             \
+               }                                                       \
+               printk("\n");                                           \
+       }
+#define DBG_DUMP_TM_REPLY_FRAME(mfp) \
+       {       u32 *m = (u32 *)(mfp);                                  \
+               int  i, n = (le32_to_cpu(m[0]) & 0x00FF0000) >> 16;     \
+               printk("TM_REPLY MessageLength=%d:\n", n);              \
+               for (i=0; i<n; i++) {                                   \
+                       if (i && ((i%8)==0))                            \
+                               printk("\n");                           \
+                       printk(" %08x", le32_to_cpu(m[i]));             \
+               }                                                       \
+               printk("\n");                                           \
+       }
 #else
-#define nehprintk(x)
+#define dtmprintk(x)
+#define DBG_DUMP_TM_REQUEST_FRAME(mfp)
+#define DBG_DUMP_TM_REPLY_FRAME(mfp)
 #endif
 
 #if defined(MPT_DEBUG_CONFIG) || defined(MPT_DEBUG)
@@ -847,41 +872,6 @@ typedef struct _mpt_sge {
 #define MPT_INDEX_2_RFPTR(ioc,idx) \
        (MPT_FRAME_HDR*)( (u8*)(ioc)->reply_frames + (ioc)->req_sz * (idx) )
 
-#define Q_INIT(q,type)  (q)->head = (q)->tail = (type*)(q)
-#define Q_IS_EMPTY(q)   ((Q_ITEM*)(q)->head == (Q_ITEM*)(q))
-
-#define Q_ADD_TAIL(qt,i,type) { \
-       Q_TRACKER       *_qt = (Q_TRACKER*)(qt); \
-       Q_ITEM          *oldTail = _qt->tail; \
-       (i)->forw = (type*)_qt; \
-       (i)->back = (type*)oldTail; \
-       oldTail->forw = (Q_ITEM*)(i); \
-       _qt->tail = (Q_ITEM*)(i); \
-}
-
-#define Q_ADD_HEAD(qt,i,type) { \
-       Q_TRACKER       *_qt = (Q_TRACKER*)(qt); \
-       Q_ITEM          *oldHead = _qt->head; \
-       (i)->forw = (type*)oldHead; \
-       (i)->back = (type*)_qt; \
-       oldHead->back = (Q_ITEM*)(i); \
-       _qt->head = (Q_ITEM*)(i); \
-}
-
-#define Q_DEL_ITEM(i) { \
-       Q_ITEM  *_forw = (Q_ITEM*)(i)->forw; \
-       Q_ITEM  *_back = (Q_ITEM*)(i)->back; \
-       _back->forw = _forw; \
-       _forw->back = _back; \
-}
-
-#define SWAB4(value) \
-       (u32)(   (((value) & 0x000000ff) << 24) \
-              | (((value) & 0x0000ff00) << 8)  \
-              | (((value) & 0x00ff0000) >> 8)  \
-              | (((value) & 0xff000000) >> 24) )
-
-
 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_MSG_FRAME)
 #define DBG_DUMP_REPLY_FRAME(mfp) \
        {       u32 *m = (u32 *)(mfp);                                  \
@@ -904,9 +894,20 @@ typedef struct _mpt_sge {
 #define DBG_DUMP_REQUEST_FRAME_HDR(mfp)
 #endif
 
+// debug sas wide ports
+#ifdef MPT_DEBUG_SAS_WIDE
+#define dsaswideprintk(x) printk x
+#else
+#define dsaswideprintk(x)
+#endif
+
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
+#define SCSI_STD_SENSE_BYTES    18
+#define SCSI_STD_INQUIRY_BYTES  36
+#define SCSI_MAX_INQUIRY_BYTES  96
+
 /*
  * MPT_SCSI_HOST defines - Used by the IOCTL and the SCSI drivers
  * Private to the driver.
@@ -945,48 +946,29 @@ typedef struct _MPT_LOCAL_REPLY {
 #define        TM_STATE_IN_PROGRESS   (1)
 #define        TM_STATE_ERROR         (2)
 
+typedef enum {
+       FC,
+       SPI,
+       SAS
+} BUS_TYPE;
+
 typedef struct _MPT_SCSI_HOST {
        MPT_ADAPTER              *ioc;
        int                       port;
        u32                       pad0;
        struct scsi_cmnd        **ScsiLookup;
-               /* Pool of buffers for chaining. ReqToChain
-                * and ChainToChain track index of chain buffers.
-                * ChainBuffer (DMA) virt/phys addresses.
-                * FreeChainQ (lock) locking mechanisms.
-                */
-       int                      *ReqToChain;
-       int                      *ChainToChain;
-       u8                       *ChainBuffer;
-       dma_addr_t                ChainBufferDMA;
-       MPT_Q_TRACKER             FreeChainQ;
-       spinlock_t                FreeChainQlock;
-       u32                       qtag_tick;
-       VirtDevice              **Targets;
+       VirtTarget              **Targets;
        MPT_LOCAL_REPLY          *pLocal;               /* used for internal commands */
        struct timer_list         timer;
-       struct timer_list         TMtimer;              /* Timer for TM commands ONLY */
                /* Pool of memory for holding SCpnts before doing
                 * OS callbacks. freeQ is the free pool.
                 */
-       u8                       *memQ;
-       DONE_Q_TRACKER            freeQ;
-       DONE_Q_TRACKER            doneQ;                /* Holds Linux formmatted requests */
-       DONE_Q_TRACKER            pendingQ;             /* Holds MPI formmatted requests */
-       MPT_Q_TRACKER             taskQ;                /* TM request Q */
-       spinlock_t                freedoneQlock;
-       int                       taskQcnt;
-       int                       num_chain;            /* Number of chain buffers */
-       int                       max_sge;              /* Max No of SGE*/
-       u8                        numTMrequests;
        u8                        tmPending;
        u8                        resetPending;
-       u8                        is_spi;               /* Parallel SCSI i/f */
        u8                        negoNvram;            /* DV disabled, nego NVRAM */
-       u8                        is_multipath;         /* Multi-path compatible */
+       u8                        pad1;
        u8                        tmState;
-       u8                        rsvd[1];
-       MPT_FRAME_HDR            *tmPtr;                /* Ptr to TM request*/
+       u8                        rsvd[2];
        MPT_FRAME_HDR            *cmdPtr;               /* Ptr to nonOS request */
        struct scsi_cmnd         *abortSCpnt;
        MPT_LOCAL_REPLY           localReply;           /* internal cmd reply struct */
@@ -994,6 +976,11 @@ typedef struct _MPT_SCSI_HOST {
        unsigned long             soft_resets;          /* fw/external bus resets count */
        unsigned long             timeouts;             /* cmd timeouts */
        ushort                    sel_timeout[MPT_MAX_FC_DEVICES];
+       char                      *info_kbuf;
+       wait_queue_head_t         scandv_waitq;
+       int                       scandv_wait_done;
+       long                      last_queue_full;
+       u16                       tm_iocstatus;
 } MPT_SCSI_HOST;
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1004,34 +991,17 @@ typedef struct _MPT_SCSI_HOST {
 /* Forward decl, a strange C thing, to prevent gcc compiler warnings */
 struct scsi_cmnd;
 
-/*
- *     DMP service layer structure / API interface
- */
-typedef struct _DmpServices {
-       VirtDevTracker    VdevList;
-       struct semaphore *Daemon;
-       int             (*ScsiPathSelect)
-                               (struct scsi_cmnd *, MPT_SCSI_HOST **hd, int *target, int *lun);
-       int             (*DmpIoDoneChk)
-                               (MPT_SCSI_HOST *, struct scsi_cmnd *,
-                                SCSIIORequest_t *,
-                                SCSIIOReply_t *);
-       void            (*mptscsih_scanVlist)
-                               (MPT_SCSI_HOST *, int portnum);
-       int             (*ScsiAbort)
-                               (struct scsi_cmnd *);
-       int             (*ScsiBusReset)
-                               (struct scsi_cmnd *);
-} DmpServices_t;
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  * Generic structure passed to the base mpt_config function.
  */
 typedef struct _x_config_parms {
-       Q_ITEM                   linkage;       /* linked list */
+       struct list_head         linkage;       /* linked list */
        struct timer_list        timer;         /* timer function for this request  */
-       ConfigPageHeader_t      *hdr;
+       union {
+               ConfigExtendedPageHeader_t      *ehdr;
+               ConfigPageHeader_t      *hdr;
+       } cfghdr;
        dma_addr_t               physAddr;
        int                      wait_done;     /* wait for this request */
        u32                      pageAddr;      /* properly formatted */
@@ -1047,6 +1017,12 @@ typedef struct _x_config_parms {
 /*
  *  Public entry points...
  */
+extern int      mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id);
+extern void     mpt_detach(struct pci_dev *pdev);
+#ifdef CONFIG_PM
+extern int      mpt_suspend(struct pci_dev *pdev, pm_message_t state);
+extern int      mpt_resume(struct pci_dev *pdev);
+#endif
 extern int      mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass);
 extern void     mpt_deregister(int cb_idx);
 extern int      mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc);
@@ -1055,52 +1031,35 @@ extern int       mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func);
 extern void     mpt_reset_deregister(int cb_idx);
 extern int      mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx);
 extern void     mpt_device_driver_deregister(int cb_idx);
-extern int      mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable);
-extern void     mpt_deregister_ascqops_strings(void);
 extern MPT_FRAME_HDR   *mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc);
-extern void     mpt_free_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
+extern void     mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
 extern void     mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
 extern void     mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr);
-extern void     mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr);
 
 extern int      mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag);
-extern int      mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait, int sleepFlag);
 extern int      mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp);
 extern u32      mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
 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);
 extern void     mpt_free_fw_memory(MPT_ADAPTER *ioc);
 extern int      mpt_findImVolumes(MPT_ADAPTER *ioc);
-extern int      mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
+extern int      mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
 
 /*
  *  Public data decl's...
  */
 extern struct list_head          ioc_list;
 extern struct proc_dir_entry   *mpt_proc_root_dir;
-extern DmpServices_t           *DmpService;
 
 extern int               mpt_lan_index;        /* needed by mptlan.c */
 extern int               mpt_stm_index;        /* needed by mptstm.c */
 
-extern void             *mpt_v_ASCQ_TablePtr;
-extern const char      **mpt_ScsiOpcodesPtr;
-extern int               mpt_ASCQ_TableSz;
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #endif         /* } __KERNEL__ */
 
-/*
- *  More (public) macros...
- */
-#ifndef offsetof
-#define offsetof(t, m) ((size_t) (&((t *)0)->m))
-#endif
-
-#if defined(__alpha__) || defined(__sparc_v9__) || defined(__ia64__) || defined(__x86_64__)
+#if defined(__alpha__) || defined(__sparc_v9__) || defined(__ia64__) || defined(__x86_64__) || defined(__powerpc__)
 #define CAST_U32_TO_PTR(x)     ((void *)(u64)x)
 #define CAST_PTR_TO_U32(x)     ((u32)(u64)x)
 #else