aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 15:36:37 +0100
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 15:36:37 +0100
commit2fc2991175bf77395e6b15fe6b2304d3bf72da40 (patch)
treeb0ff38c09240e7c00e1577d447ebe89143d752dc /drivers/message/fusion
parent[MTD] mtdchar: Return EINVAL for bad seeks instead of fixing up to valid byte (diff)
parent[PATCH] nvidiafb: Geforce 7800 series support added (diff)
downloadlinux-dev-2fc2991175bf77395e6b15fe6b2304d3bf72da40.tar.xz
linux-dev-2fc2991175bf77395e6b15fe6b2304d3bf72da40.zip
Merge branch 'master' of /home/tglx/work/mtd/git/linux-2.6.git/
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r--drivers/message/fusion/Kconfig17
-rw-r--r--drivers/message/fusion/Makefile1
-rw-r--r--drivers/message/fusion/lsi/mpi.h19
-rw-r--r--drivers/message/fusion/lsi/mpi_cnfg.h85
-rw-r--r--drivers/message/fusion/lsi/mpi_history.txt67
-rw-r--r--drivers/message/fusion/lsi/mpi_init.h203
-rw-r--r--drivers/message/fusion/lsi/mpi_ioc.h11
-rw-r--r--drivers/message/fusion/lsi/mpi_targ.h74
-rw-r--r--drivers/message/fusion/mptbase.c1276
-rw-r--r--drivers/message/fusion/mptbase.h61
-rw-r--r--drivers/message/fusion/mptctl.c18
-rw-r--r--drivers/message/fusion/mptfc.c2
-rw-r--r--drivers/message/fusion/mptlan.c7
-rw-r--r--drivers/message/fusion/mptsas.c1239
-rw-r--r--drivers/message/fusion/mptscsih.c593
-rw-r--r--drivers/message/fusion/mptscsih.h7
-rw-r--r--drivers/message/fusion/mptspi.c8
17 files changed, 2953 insertions, 735 deletions
diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig
index 33f209a39cb6..1883d22cffeb 100644
--- a/drivers/message/fusion/Kconfig
+++ b/drivers/message/fusion/Kconfig
@@ -35,6 +35,23 @@ config FUSION_FC
LSIFC929X
LSIFC929XL
+config FUSION_SAS
+ tristate "Fusion MPT ScsiHost drivers for SAS"
+ depends on PCI && SCSI
+ select FUSION
+ select SCSI_SAS_ATTRS
+ ---help---
+ SCSI HOST support for a SAS host adapters.
+
+ List of supported controllers:
+
+ LSISAS1064
+ LSISAS1066
+ LSISAS1068
+ LSISAS1064E
+ LSISAS1066E
+ LSISAS1068E
+
config FUSION_MAX_SGE
int "Maximum number of scatter gather entries (16 - 128)"
depends on FUSION
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile
index 1d2f9db813c1..8a2e2657f4c2 100644
--- a/drivers/message/fusion/Makefile
+++ b/drivers/message/fusion/Makefile
@@ -34,5 +34,6 @@
obj-$(CONFIG_FUSION_SPI) += mptbase.o mptscsih.o mptspi.o
obj-$(CONFIG_FUSION_FC) += mptbase.o mptscsih.o mptfc.o
+obj-$(CONFIG_FUSION_SAS) += mptbase.o mptscsih.o mptsas.o
obj-$(CONFIG_FUSION_CTL) += mptctl.o
obj-$(CONFIG_FUSION_LAN) += mptlan.o
diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h
index 9f98334e5076..b61e3d175070 100644
--- a/drivers/message/fusion/lsi/mpi.h
+++ b/drivers/message/fusion/lsi/mpi.h
@@ -6,7 +6,7 @@
* Title: MPI Message independent structures and definitions
* Creation Date: July 27, 2000
*
- * mpi.h Version: 01.05.07
+ * mpi.h Version: 01.05.08
*
* Version History
* ---------------
@@ -71,6 +71,9 @@
* 03-11-05 01.05.07 Removed function codes for SCSI IO 32 and
* TargetAssistExtended requests.
* Removed EEDP IOCStatus codes.
+ * 06-24-05 01.05.08 Added function codes for SCSI IO 32 and
+ * TargetAssistExtended requests.
+ * Added EEDP IOCStatus codes.
* --------------------------------------------------------------------------
*/
@@ -101,7 +104,7 @@
/* 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 (0x0A)
#define MPI_HEADER_VERSION_DEV (0x00)
#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI_HEADER_VERSION_UNIT_SHIFT (8)
@@ -292,10 +295,13 @@
#define MPI_FUNCTION_DIAG_BUFFER_POST (0x1D)
#define MPI_FUNCTION_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_TARGET_ASSIST_EXTENDED (0x23)
#define MPI_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24)
#define MPI_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25)
@@ -681,6 +687,15 @@ typedef struct _MSG_DEFAULT_REPLY
#define MPI_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C)
/****************************************************************************/
+/* For use by SCSI Initiator and SCSI Target end-to-end data protection */
+/****************************************************************************/
+
+#define MPI_IOCSTATUS_EEDP_GUARD_ERROR (0x004D)
+#define MPI_IOCSTATUS_EEDP_REF_TAG_ERROR (0x004E)
+#define MPI_IOCSTATUS_EEDP_APP_TAG_ERROR (0x004F)
+
+
+/****************************************************************************/
/* SCSI Target values */
/****************************************************************************/
diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h
index 15b12b06799d..d8339896f734 100644
--- a/drivers/message/fusion/lsi/mpi_cnfg.h
+++ b/drivers/message/fusion/lsi/mpi_cnfg.h
@@ -6,7 +6,7 @@
* Title: MPI Config message, structures, and Pages
* Creation Date: July 27, 2000
*
- * mpi_cnfg.h Version: 01.05.08
+ * mpi_cnfg.h Version: 01.05.09
*
* Version History
* ---------------
@@ -232,6 +232,23 @@
* New physical mapping mode in SAS IO Unit Page 2.
* Added CONFIG_PAGE_SAS_ENCLOSURE_0.
* Added Slot and Enclosure fields to SAS Device Page 0.
+ * 06-24-05 01.05.09 Added EEDP defines to IOC Page 1.
+ * Added more RAID type defines to IOC Page 2.
+ * Added Port Enable Delay settings to BIOS Page 1.
+ * Added Bad Block Table Full define to RAID Volume Page 0.
+ * Added Previous State defines to RAID Physical Disk
+ * Page 0.
+ * Added Max Sata Targets define for DiscoveryStatus field
+ * of SAS IO Unit Page 0.
+ * Added Device Self Test to Control Flags of SAS IO Unit
+ * Page 1.
+ * Added Direct Attach Starting Slot Number define for SAS
+ * IO Unit Page 2.
+ * Added new fields in SAS Device Page 2 for enclosure
+ * mapping.
+ * Added OwnerDevHandle and Flags field to SAS PHY Page 0.
+ * Added IOC GPIO Flags define to SAS Enclosure Page 0.
+ * Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT.
* --------------------------------------------------------------------------
*/
@@ -477,6 +494,7 @@ typedef struct _MSG_CONFIG_REPLY
#define MPI_MANUFACTPAGE_DEVICEID_FC929X (0x0626)
#define MPI_MANUFACTPAGE_DEVICEID_FC939X (0x0642)
#define MPI_MANUFACTPAGE_DEVICEID_FC949X (0x0640)
+#define MPI_MANUFACTPAGE_DEVICEID_FC949ES (0x0646)
/* SCSI */
#define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030)
#define MPI_MANUFACTPAGE_DEVID_53C1030ZC (0x0031)
@@ -769,9 +787,13 @@ typedef struct _CONFIG_PAGE_IOC_1
} CONFIG_PAGE_IOC_1, MPI_POINTER PTR_CONFIG_PAGE_IOC_1,
IOCPage1_t, MPI_POINTER pIOCPage1_t;
-#define MPI_IOCPAGE1_PAGEVERSION (0x02)
+#define MPI_IOCPAGE1_PAGEVERSION (0x03)
/* defines for the Flags field */
+#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_INITIATOR_CONTEXT_REPLY_DISABLE (0x00000010)
#define MPI_IOCPAGE1_REPLY_COALESCING (0x00000001)
@@ -795,6 +817,11 @@ typedef struct _CONFIG_PAGE_IOC_2_RAID_VOL
#define MPI_RAID_VOL_TYPE_IS (0x00)
#define MPI_RAID_VOL_TYPE_IME (0x01)
#define MPI_RAID_VOL_TYPE_IM (0x02)
+#define MPI_RAID_VOL_TYPE_RAID_5 (0x03)
+#define MPI_RAID_VOL_TYPE_RAID_6 (0x04)
+#define MPI_RAID_VOL_TYPE_RAID_10 (0x05)
+#define MPI_RAID_VOL_TYPE_RAID_50 (0x06)
+#define MPI_RAID_VOL_TYPE_UNKNOWN (0xFF)
/* IOC Page 2 Volume Flags values */
@@ -820,13 +847,17 @@ typedef struct _CONFIG_PAGE_IOC_2
} CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
IOCPage2_t, MPI_POINTER pIOCPage2_t;
-#define MPI_IOCPAGE2_PAGEVERSION (0x02)
+#define MPI_IOCPAGE2_PAGEVERSION (0x03)
/* IOC Page 2 Capabilities flags */
#define MPI_IOCPAGE2_CAP_FLAGS_IS_SUPPORT (0x00000001)
#define MPI_IOCPAGE2_CAP_FLAGS_IME_SUPPORT (0x00000002)
#define MPI_IOCPAGE2_CAP_FLAGS_IM_SUPPORT (0x00000004)
+#define MPI_IOCPAGE2_CAP_FLAGS_RAID_5_SUPPORT (0x00000008)
+#define MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT (0x00000010)
+#define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT (0x00000020)
+#define MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT (0x00000040)
#define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT (0x20000000)
#define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT (0x40000000)
#define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT (0x80000000)
@@ -945,7 +976,7 @@ typedef struct _CONFIG_PAGE_BIOS_1
} CONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1,
BIOSPage1_t, MPI_POINTER pBIOSPage1_t;
-#define MPI_BIOSPAGE1_PAGEVERSION (0x01)
+#define MPI_BIOSPAGE1_PAGEVERSION (0x02)
/* values for the BiosOptions field */
#define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE (0x00000400)
@@ -954,6 +985,8 @@ typedef struct _CONFIG_PAGE_BIOS_1
#define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001)
/* values for the IOCSettings field */
+#define MPI_BIOSPAGE1_IOCSET_MASK_PORT_ENABLE_DELAY (0x00F00000)
+#define MPI_BIOSPAGE1_IOCSET_SHIFT_PORT_ENABLE_DELAY (20)
#define MPI_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000)
#define MPI_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT (0x00000000)
#define MPI_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT (0x00010000)
@@ -1167,6 +1200,7 @@ typedef struct _CONFIG_PAGE_BIOS_2
#define MPI_BIOSPAGE2_FORM_PCI_SLOT_NUMBER (0x03)
#define MPI_BIOSPAGE2_FORM_FC_WWN (0x04)
#define MPI_BIOSPAGE2_FORM_SAS_WWN (0x05)
+#define MPI_BIOSPAGE2_FORM_ENCLOSURE_SLOT (0x06)
/****************************************************************************
@@ -1957,11 +1991,11 @@ typedef struct _RAID_VOL0_STATUS
RaidVol0Status_t, MPI_POINTER pRaidVol0Status_t;
/* RAID Volume Page 0 VolumeStatus defines */
-
#define MPI_RAIDVOL0_STATUS_FLAG_ENABLED (0x01)
#define MPI_RAIDVOL0_STATUS_FLAG_QUIESCED (0x02)
#define MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x04)
#define MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE (0x08)
+#define MPI_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL (0x10)
#define MPI_RAIDVOL0_STATUS_STATE_OPTIMAL (0x00)
#define MPI_RAIDVOL0_STATUS_STATE_DEGRADED (0x01)
@@ -2025,7 +2059,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0
} CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,
RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t;
-#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x04)
+#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x05)
/* values for RAID Volume Page 0 InactiveStatus field */
#define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00)
@@ -2104,6 +2138,8 @@ typedef struct _RAID_PHYS_DISK0_STATUS
#define MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC (0x01)
#define MPI_PHYSDISK0_STATUS_FLAG_QUIESCED (0x02)
#define MPI_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME (0x04)
+#define MPI_PHYSDISK0_STATUS_FLAG_OPTIMAL_PREVIOUS (0x00)
+#define MPI_PHYSDISK0_STATUS_FLAG_NOT_OPTIMAL_PREVIOUS (0x08)
#define MPI_PHYSDISK0_STATUS_ONLINE (0x00)
#define MPI_PHYSDISK0_STATUS_MISSING (0x01)
@@ -2132,7 +2168,7 @@ typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_0
} CONFIG_PAGE_RAID_PHYS_DISK_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_0,
RaidPhysDiskPage0_t, MPI_POINTER pRaidPhysDiskPage0_t;
-#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION (0x01)
+#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION (0x02)
typedef struct _RAID_PHYS_DISK1_PATH
@@ -2263,7 +2299,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
} CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0,
SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t;
-#define MPI_SASIOUNITPAGE0_PAGEVERSION (0x02)
+#define MPI_SASIOUNITPAGE0_PAGEVERSION (0x03)
/* values for SAS IO Unit Page 0 PortFlags */
#define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS (0x08)
@@ -2299,6 +2335,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
#define MPI_SAS_IOUNIT0_DS_SUBTRACTIVE_LINK (0x00000200)
#define MPI_SAS_IOUNIT0_DS_TABLE_LINK (0x00000400)
#define MPI_SAS_IOUNIT0_DS_UNSUPPORTED_DEVICE (0x00000800)
+#define MPI_SAS_IOUNIT0_DS_MAX_SATA_TARGETS (0x00001000)
typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA
@@ -2336,6 +2373,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x04)
/* values for SAS IO Unit Page 1 ControlFlags */
+#define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_3_0_MAX (0x4000)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_1_5_MAX (0x2000)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000)
@@ -2345,9 +2383,8 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
#define MPI_SAS_IOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9)
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x00)
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x01)
-#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x10)
+#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x02)
-#define MPI_SAS_IOUNIT1_CONTROL_AUTO_PORT_SAME_SAS_ADDR (0x0100)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020)
@@ -2390,7 +2427,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
} CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2,
SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t;
-#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x03)
+#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x04)
/* values for SAS IO Unit Page 2 Status field */
#define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02)
@@ -2406,6 +2443,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
#define MPI_SAS_IOUNIT2_FLAGS_ENCLOSURE_SLOT_PHYS_MAP (0x02)
#define MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT (0x10)
+#define MPI_SAS_IOUNIT2_FLAGS_DA_STARTING_SLOT (0x20)
typedef struct _CONFIG_PAGE_SAS_IO_UNIT_3
@@ -2584,11 +2622,19 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_2
{
CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U64 PhysicalIdentifier; /* 08h */
- U32 Reserved1; /* 10h */
+ U32 EnclosureMapping; /* 10h */
} CONFIG_PAGE_SAS_DEVICE_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_2,
SasDevicePage2_t, MPI_POINTER pSasDevicePage2_t;
-#define MPI_SASDEVICE2_PAGEVERSION (0x00)
+#define MPI_SASDEVICE2_PAGEVERSION (0x01)
+
+/* defines for SAS Device Page 2 EnclosureMapping field */
+#define MPI_SASDEVICE2_ENC_MAP_MASK_MISSING_COUNT (0x0000000F)
+#define MPI_SASDEVICE2_ENC_MAP_SHIFT_MISSING_COUNT (0)
+#define MPI_SASDEVICE2_ENC_MAP_MASK_NUM_SLOTS (0x000007F0)
+#define MPI_SASDEVICE2_ENC_MAP_SHIFT_NUM_SLOTS (4)
+#define MPI_SASDEVICE2_ENC_MAP_MASK_START_INDEX (0x001FF800)
+#define MPI_SASDEVICE2_ENC_MAP_SHIFT_START_INDEX (11)
/****************************************************************************
@@ -2598,7 +2644,8 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_2
typedef struct _CONFIG_PAGE_SAS_PHY_0
{
CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
- U32 Reserved1; /* 08h */
+ U16 OwnerDevHandle; /* 08h */
+ U16 Reserved1; /* 0Ah */
U64 SASAddress; /* 0Ch */
U16 AttachedDevHandle; /* 14h */
U8 AttachedPhyIdentifier; /* 16h */
@@ -2607,12 +2654,12 @@ typedef struct _CONFIG_PAGE_SAS_PHY_0
U8 ProgrammedLinkRate; /* 20h */
U8 HwLinkRate; /* 21h */
U8 ChangeCount; /* 22h */
- U8 Reserved3; /* 23h */
+ U8 Flags; /* 23h */
U32 PhyInfo; /* 24h */
} CONFIG_PAGE_SAS_PHY_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_0,
SasPhyPage0_t, MPI_POINTER pSasPhyPage0_t;
-#define MPI_SASPHY0_PAGEVERSION (0x00)
+#define MPI_SASPHY0_PAGEVERSION (0x01)
/* values for SAS PHY Page 0 ProgrammedLinkRate field */
#define MPI_SAS_PHY0_PRATE_MAX_RATE_MASK (0xF0)
@@ -2632,6 +2679,9 @@ typedef struct _CONFIG_PAGE_SAS_PHY_0
#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 Flags field */
+#define MPI_SAS_PHY0_FLAGS_SGPIO_DIRECT_ATTACH_ENC (0x01)
+
/* 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)
@@ -2690,7 +2740,7 @@ typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0
} CONFIG_PAGE_SAS_ENCLOSURE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_ENCLOSURE_0,
SasEnclosurePage0_t, MPI_POINTER pSasEnclosurePage0_t;
-#define MPI_SASENCLOSURE0_PAGEVERSION (0x00)
+#define MPI_SASENCLOSURE0_PAGEVERSION (0x01)
/* values for SAS Enclosure Page 0 Flags field */
#define MPI_SAS_ENCLS0_FLAGS_SEP_BUS_ID_VALID (0x0020)
@@ -2702,6 +2752,7 @@ typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0
#define MPI_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO (0x0002)
#define MPI_SAS_ENCLS0_FLAGS_MNG_EXP_SGPIO (0x0003)
#define MPI_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE (0x0004)
+#define MPI_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO (0x0005)
/****************************************************************************
diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt
index c9edbee41edf..1a30ef16adb4 100644
--- a/drivers/message/fusion/lsi/mpi_history.txt
+++ b/drivers/message/fusion/lsi/mpi_history.txt
@@ -6,17 +6,17 @@
Copyright (c) 2000-2005 LSI Logic Corporation.
---------------------------------------
- Header Set Release Version: 01.05.09
+ Header Set Release Version: 01.05.10
Header Set Release Date: 03-11-05
---------------------------------------
Filename Current version Prior version
---------- --------------- -------------
- mpi.h 01.05.07 01.05.06
- mpi_ioc.h 01.05.08 01.05.07
- mpi_cnfg.h 01.05.08 01.05.07
- mpi_init.h 01.05.04 01.05.03
- mpi_targ.h 01.05.04 01.05.03
+ mpi.h 01.05.08 01.05.07
+ mpi_ioc.h 01.05.09 01.05.08
+ mpi_cnfg.h 01.05.09 01.05.08
+ mpi_init.h 01.05.05 01.05.04
+ mpi_targ.h 01.05.05 01.05.04
mpi_fc.h 01.05.01 01.05.01
mpi_lan.h 01.05.01 01.05.01
mpi_raid.h 01.05.02 01.05.02
@@ -24,7 +24,7 @@
mpi_inb.h 01.05.01 01.05.01
mpi_sas.h 01.05.01 01.05.01
mpi_type.h 01.05.01 01.05.01
- mpi_history.txt 01.05.09 01.05.08
+ mpi_history.txt 01.05.09 01.05.09
* Date Version Description
@@ -88,6 +88,9 @@ mpi.h
* 03-11-05 01.05.07 Removed function codes for SCSI IO 32 and
* TargetAssistExtended requests.
* Removed EEDP IOCStatus codes.
+ * 06-24-05 01.05.08 Added function codes for SCSI IO 32 and
+ * TargetAssistExtended requests.
+ * Added EEDP IOCStatus codes.
* --------------------------------------------------------------------------
mpi_ioc.h
@@ -159,6 +162,8 @@ mpi_ioc.h
* Reply and IOC Init Request.
* 03-11-05 01.05.08 Added family code for 1068E family.
* Removed IOCFacts Reply EEDP Capability bit.
+ * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.
+ * Added Max SATA Targets to SAS Discovery Error event.
* --------------------------------------------------------------------------
mpi_cnfg.h
@@ -380,6 +385,23 @@ mpi_cnfg.h
* New physical mapping mode in SAS IO Unit Page 2.
* Added CONFIG_PAGE_SAS_ENCLOSURE_0.
* Added Slot and Enclosure fields to SAS Device Page 0.
+ * 06-24-05 01.05.09 Added EEDP defines to IOC Page 1.
+ * Added more RAID type defines to IOC Page 2.
+ * Added Port Enable Delay settings to BIOS Page 1.
+ * Added Bad Block Table Full define to RAID Volume Page 0.
+ * Added Previous State defines to RAID Physical Disk
+ * Page 0.
+ * Added Max Sata Targets define for DiscoveryStatus field
+ * of SAS IO Unit Page 0.
+ * Added Device Self Test to Control Flags of SAS IO Unit
+ * Page 1.
+ * Added Direct Attach Starting Slot Number define for SAS
+ * IO Unit Page 2.
+ * Added new fields in SAS Device Page 2 for enclosure
+ * mapping.
+ * Added OwnerDevHandle and Flags field to SAS PHY Page 0.
+ * Added IOC GPIO Flags define to SAS Enclosure Page 0.
+ * Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT.
* --------------------------------------------------------------------------
mpi_init.h
@@ -418,6 +440,8 @@ mpi_init.h
* Modified SCSI Enclosure Processor Request and Reply to
* support Enclosure/Slot addressing rather than WWID
* addressing.
+ * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.
+ * Added four new defines for SEP SlotStatus.
* --------------------------------------------------------------------------
mpi_targ.h
@@ -461,6 +485,7 @@ mpi_targ.h
* 10-05-04 01.05.02 MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added.
* 02-22-05 01.05.03 Changed a comment.
* 03-11-05 01.05.04 Removed TargetAssistExtended Request.
+ * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines.
* --------------------------------------------------------------------------
mpi_fc.h
@@ -571,20 +596,20 @@ mpi_type.h
mpi_history.txt Parts list history
-Filename 01.05.09
----------- --------
-mpi.h 01.05.07
-mpi_ioc.h 01.05.08
-mpi_cnfg.h 01.05.08
-mpi_init.h 01.05.04
-mpi_targ.h 01.05.04
-mpi_fc.h 01.05.01
-mpi_lan.h 01.05.01
-mpi_raid.h 01.05.02
-mpi_tool.h 01.05.03
-mpi_inb.h 01.05.01
-mpi_sas.h 01.05.01
-mpi_type.h 01.05.01
+Filename 01.05.10 01.05.09
+---------- -------- --------
+mpi.h 01.05.08 01.05.07
+mpi_ioc.h 01.05.09 01.05.08
+mpi_cnfg.h 01.05.09 01.05.08
+mpi_init.h 01.05.05 01.05.04
+mpi_targ.h 01.05.05 01.05.04
+mpi_fc.h 01.05.01 01.05.01
+mpi_lan.h 01.05.01 01.05.01
+mpi_raid.h 01.05.02 01.05.02
+mpi_tool.h 01.05.03 01.05.03
+mpi_inb.h 01.05.01 01.05.01
+mpi_sas.h 01.05.01 01.05.01
+mpi_type.h 01.05.01 01.05.01
Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03
---------- -------- -------- -------- -------- -------- --------
diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h
index aca035801a86..d5af75afbd94 100644
--- a/drivers/message/fusion/lsi/mpi_init.h
+++ b/drivers/message/fusion/lsi/mpi_init.h
@@ -6,7 +6,7 @@
* Title: MPI initiator mode messages and structures
* Creation Date: June 8, 2000
*
- * mpi_init.h Version: 01.05.04
+ * mpi_init.h Version: 01.05.05
*
* Version History
* ---------------
@@ -48,6 +48,8 @@
* Modified SCSI Enclosure Processor Request and Reply to
* support Enclosure/Slot addressing rather than WWID
* addressing.
+ * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.
+ * Added four new defines for SEP SlotStatus.
* --------------------------------------------------------------------------
*/
@@ -203,6 +205,197 @@ typedef struct _MSG_SCSI_IO_REPLY
/****************************************************************************/
+/* SCSI IO 32 messages and associated structures */
+/****************************************************************************/
+
+typedef struct
+{
+ U8 CDB[20]; /* 00h */
+ U32 PrimaryReferenceTag; /* 14h */
+ U16 PrimaryApplicationTag; /* 18h */
+ U16 PrimaryApplicationTagMask; /* 1Ah */
+ U32 TransferLength; /* 1Ch */
+} MPI_SCSI_IO32_CDB_EEDP32, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_EEDP32,
+ MpiScsiIo32CdbEedp32_t, MPI_POINTER pMpiScsiIo32CdbEedp32_t;
+
+typedef struct
+{
+ U8 CDB[16]; /* 00h */
+ U32 DataLength; /* 10h */
+ U32 PrimaryReferenceTag; /* 14h */
+ U16 PrimaryApplicationTag; /* 18h */
+ U16 PrimaryApplicationTagMask; /* 1Ah */
+ U32 TransferLength; /* 1Ch */
+} MPI_SCSI_IO32_CDB_EEDP16, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_EEDP16,
+ MpiScsiIo32CdbEedp16_t, MPI_POINTER pMpiScsiIo32CdbEedp16_t;
+
+typedef union
+{
+ U8 CDB32[32];
+ MPI_SCSI_IO32_CDB_EEDP32 EEDP32;
+ MPI_SCSI_IO32_CDB_EEDP16 EEDP16;
+ SGE_SIMPLE_UNION SGE;
+} MPI_SCSI_IO32_CDB_UNION, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_UNION,
+ MpiScsiIo32Cdb_t, MPI_POINTER pMpiScsiIo32Cdb_t;
+
+typedef struct
+{
+ U8 TargetID; /* 00h */
+ U8 Bus; /* 01h */
+ U16 Reserved1; /* 02h */
+ U32 Reserved2; /* 04h */
+} MPI_SCSI_IO32_BUS_TARGET_ID_FORM, MPI_POINTER PTR_MPI_SCSI_IO32_BUS_TARGET_ID_FORM,
+ MpiScsiIo32BusTargetIdForm_t, MPI_POINTER pMpiScsiIo32BusTargetIdForm_t;
+
+typedef union
+{
+ MPI_SCSI_IO32_BUS_TARGET_ID_FORM SCSIID;
+ U64 WWID;
+} MPI_SCSI_IO32_ADDRESS, MPI_POINTER PTR_MPI_SCSI_IO32_ADDRESS,
+ MpiScsiIo32Address_t, MPI_POINTER pMpiScsiIo32Address_t;
+
+typedef struct _MSG_SCSI_IO32_REQUEST
+{
+ U8 Port; /* 00h */
+ U8 Reserved1; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U8 CDBLength; /* 04h */
+ U8 SenseBufferLength; /* 05h */
+ U8 Flags; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U8 LUN[8]; /* 0Ch */
+ U32 Control; /* 14h */
+ MPI_SCSI_IO32_CDB_UNION CDB; /* 18h */
+ U32 DataLength; /* 38h */
+ U32 BidirectionalDataLength; /* 3Ch */
+ U32 SecondaryReferenceTag; /* 40h */
+ U16 SecondaryApplicationTag; /* 44h */
+ U16 Reserved2; /* 46h */
+ U16 EEDPFlags; /* 48h */
+ U16 ApplicationTagTranslationMask; /* 4Ah */
+ U32 EEDPBlockSize; /* 4Ch */
+ MPI_SCSI_IO32_ADDRESS DeviceAddress; /* 50h */
+ U8 SGLOffset0; /* 58h */
+ U8 SGLOffset1; /* 59h */
+ U8 SGLOffset2; /* 5Ah */
+ U8 SGLOffset3; /* 5Bh */
+ U32 Reserved3; /* 5Ch */
+ U32 Reserved4; /* 60h */
+ U32 SenseBufferLowAddr; /* 64h */
+ SGE_IO_UNION SGL; /* 68h */
+} MSG_SCSI_IO32_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO32_REQUEST,
+ SCSIIO32Request_t, MPI_POINTER pSCSIIO32Request_t;
+
+/* SCSI IO 32 MsgFlags bits */
+#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH (0x01)
+#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_32 (0x00)
+#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_64 (0x01)
+
+#define MPI_SCSIIO32_MSGFLGS_SENSE_LOCATION (0x02)
+#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_HOST (0x00)
+#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_IOC (0x02)
+
+#define MPI_SCSIIO32_MSGFLGS_CMD_DETERMINES_DATA_DIR (0x04)
+#define MPI_SCSIIO32_MSGFLGS_SGL_OFFSETS_CHAINS (0x08)
+#define MPI_SCSIIO32_MSGFLGS_MULTICAST (0x10)
+#define MPI_SCSIIO32_MSGFLGS_BIDIRECTIONAL (0x20)
+#define MPI_SCSIIO32_MSGFLGS_LARGE_CDB (0x40)
+
+/* SCSI IO 32 Flags bits */
+#define MPI_SCSIIO32_FLAGS_FORM_MASK (0x03)
+#define MPI_SCSIIO32_FLAGS_FORM_SCSIID (0x00)
+#define MPI_SCSIIO32_FLAGS_FORM_WWID (0x01)
+
+/* SCSI IO 32 LUN fields */
+#define MPI_SCSIIO32_LUN_FIRST_LEVEL_ADDRESSING (0x0000FFFF)
+#define MPI_SCSIIO32_LUN_SECOND_LEVEL_ADDRESSING (0xFFFF0000)
+#define MPI_SCSIIO32_LUN_THIRD_LEVEL_ADDRESSING (0x0000FFFF)
+#define MPI_SCSIIO32_LUN_FOURTH_LEVEL_ADDRESSING (0xFFFF0000)
+#define MPI_SCSIIO32_LUN_LEVEL_1_WORD (0xFF00)
+#define MPI_SCSIIO32_LUN_LEVEL_1_DWORD (0x0000FF00)
+
+/* SCSI IO 32 Control bits */
+#define MPI_SCSIIO32_CONTROL_DATADIRECTION_MASK (0x03000000)
+#define MPI_SCSIIO32_CONTROL_NODATATRANSFER (0x00000000)
+#define MPI_SCSIIO32_CONTROL_WRITE (0x01000000)
+#define MPI_SCSIIO32_CONTROL_READ (0x02000000)
+#define MPI_SCSIIO32_CONTROL_BIDIRECTIONAL (0x03000000)
+
+#define MPI_SCSIIO32_CONTROL_ADDCDBLEN_MASK (0xFC000000)
+#define MPI_SCSIIO32_CONTROL_ADDCDBLEN_SHIFT (26)
+
+#define MPI_SCSIIO32_CONTROL_TASKATTRIBUTE_MASK (0x00000700)
+#define MPI_SCSIIO32_CONTROL_SIMPLEQ (0x00000000)
+#define MPI_SCSIIO32_CONTROL_HEADOFQ (0x00000100)
+#define MPI_SCSIIO32_CONTROL_ORDEREDQ (0x00000200)
+#define MPI_SCSIIO32_CONTROL_ACAQ (0x00000400)
+#define MPI_SCSIIO32_CONTROL_UNTAGGED (0x00000500)
+#define MPI_SCSIIO32_CONTROL_NO_DISCONNECT (0x00000700)
+
+#define MPI_SCSIIO32_CONTROL_TASKMANAGE_MASK (0x00FF0000)
+#define MPI_SCSIIO32_CONTROL_OBSOLETE (0x00800000)
+#define MPI_SCSIIO32_CONTROL_CLEAR_ACA_RSV (0x00400000)
+#define MPI_SCSIIO32_CONTROL_TARGET_RESET (0x00200000)
+#define MPI_SCSIIO32_CONTROL_LUN_RESET_RSV (0x00100000)
+#define MPI_SCSIIO32_CONTROL_RESERVED (0x00080000)
+#define MPI_SCSIIO32_CONTROL_CLR_TASK_SET_RSV (0x00040000)
+#define MPI_SCSIIO32_CONTROL_ABORT_TASK_SET (0x00020000)
+#define MPI_SCSIIO32_CONTROL_RESERVED2 (0x00010000)
+
+/* SCSI IO 32 EEDPFlags */
+#define MPI_SCSIIO32_EEDPFLAGS_MASK_OP (0x0007)
+#define MPI_SCSIIO32_EEDPFLAGS_NOOP_OP (0x0000)
+#define MPI_SCSIIO32_EEDPFLAGS_CHK_OP (0x0001)
+#define MPI_SCSIIO32_EEDPFLAGS_STRIP_OP (0x0002)
+#define MPI_SCSIIO32_EEDPFLAGS_CHKRM_OP (0x0003)
+#define MPI_SCSIIO32_EEDPFLAGS_INSERT_OP (0x0004)
+#define MPI_SCSIIO32_EEDPFLAGS_REPLACE_OP (0x0006)
+#define MPI_SCSIIO32_EEDPFLAGS_CHKREGEN_OP (0x0007)
+
+#define MPI_SCSIIO32_EEDPFLAGS_PASS_REF_TAG (0x0008)
+#define MPI_SCSIIO32_EEDPFLAGS_8_9THS_MODE (0x0010)
+
+#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_MASK (0x0700)
+#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_GUARD (0x0100)
+#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_REFTAG (0x0200)
+#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_LBATAG (0x0400)
+#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_SHIFT (8)
+
+#define MPI_SCSIIO32_EEDPFLAGS_INC_SEC_APPTAG (0x1000)
+#define MPI_SCSIIO32_EEDPFLAGS_INC_PRI_APPTAG (0x2000)
+#define MPI_SCSIIO32_EEDPFLAGS_INC_SEC_REFTAG (0x4000)
+#define MPI_SCSIIO32_EEDPFLAGS_INC_PRI_REFTAG (0x8000)
+
+
+/* SCSIIO32 IO reply structure */
+typedef struct _MSG_SCSIIO32_IO_REPLY
+{
+ U8 Port; /* 00h */
+ U8 Reserved1; /* 01h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U8 CDBLength; /* 04h */
+ U8 SenseBufferLength; /* 05h */
+ U8 Flags; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U8 SCSIStatus; /* 0Ch */
+ U8 SCSIState; /* 0Dh */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ U32 TransferCount; /* 14h */
+ U32 SenseCount; /* 18h */
+ U32 ResponseInfo; /* 1Ch */
+ U16 TaskTag; /* 20h */
+ U16 Reserved2; /* 22h */
+ U32 BidirectionalTransferCount; /* 24h */
+} MSG_SCSIIO32_IO_REPLY, MPI_POINTER PTR_MSG_SCSIIO32_IO_REPLY,
+ SCSIIO32Reply_t, MPI_POINTER pSCSIIO32Reply_t;
+
+
+/****************************************************************************/
/* SCSI Task Management messages */
/****************************************************************************/
@@ -310,10 +503,14 @@ typedef struct _MSG_SEP_REQUEST
#define MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080)
#define MPI_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100)
#define MPI_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
+#define MPI_SEP_REQ_SLOTSTATUS_REQ_CONSISTENCY_CHECK (0x00001000)
+#define MPI_SEP_REQ_SLOTSTATUS_DISABLE (0x00002000)
+#define MPI_SEP_REQ_SLOTSTATUS_REQ_RESERVED_DEVICE (0x00004000)
#define MPI_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
#define MPI_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE (0x00040000)
#define MPI_SEP_REQ_SLOTSTATUS_REQUEST_INSERT (0x00080000)
#define MPI_SEP_REQ_SLOTSTATUS_DO_NOT_MOVE (0x00400000)
+#define MPI_SEP_REQ_SLOTSTATUS_ACTIVE (0x00800000)
#define MPI_SEP_REQ_SLOTSTATUS_B_ENABLE_BYPASS (0x04000000)
#define MPI_SEP_REQ_SLOTSTATUS_A_ENABLE_BYPASS (0x08000000)
#define MPI_SEP_REQ_SLOTSTATUS_DEV_OFF (0x10000000)
@@ -352,11 +549,15 @@ typedef struct _MSG_SEP_REPLY
#define MPI_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080)
#define MPI_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100)
#define MPI_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
+#define MPI_SEP_REPLY_SLOTSTATUS_CONSISTENCY_CHECK (0x00001000)
+#define MPI_SEP_REPLY_SLOTSTATUS_DISABLE (0x00002000)
+#define MPI_SEP_REPLY_SLOTSTATUS_RESERVED_DEVICE (0x00004000)
#define MPI_SEP_REPLY_SLOTSTATUS_REPORT (0x00010000)
#define MPI_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
#define MPI_SEP_REPLY_SLOTSTATUS_REMOVE_READY (0x00040000)
#define MPI_SEP_REPLY_SLOTSTATUS_INSERT_READY (0x00080000)
#define MPI_SEP_REPLY_SLOTSTATUS_DO_NOT_REMOVE (0x00400000)
+#define MPI_SEP_REPLY_SLOTSTATUS_ACTIVE (0x00800000)
#define MPI_SEP_REPLY_SLOTSTATUS_B_BYPASS_ENABLED (0x01000000)
#define MPI_SEP_REPLY_SLOTSTATUS_A_BYPASS_ENABLED (0x02000000)
#define MPI_SEP_REPLY_SLOTSTATUS_B_ENABLE_BYPASS (0x04000000)
diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h
index f91eb4efe8cc..93b70e2b4266 100644
--- a/drivers/message/fusion/lsi/mpi_ioc.h
+++ b/drivers/message/fusion/lsi/mpi_ioc.h
@@ -6,7 +6,7 @@
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: August 11, 2000
*
- * mpi_ioc.h Version: 01.05.08
+ * mpi_ioc.h Version: 01.05.09
*
* Version History
* ---------------
@@ -81,6 +81,8 @@
* Reply and IOC Init Request.
* 03-11-05 01.05.08 Added family code for 1068E family.
* Removed IOCFacts Reply EEDP Capability bit.
+ * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.
+ * Added Max SATA Targets to SAS Discovery Error event.
* --------------------------------------------------------------------------
*/
@@ -261,7 +263,11 @@ typedef struct _MSG_IOC_FACTS_REPLY
#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)
+#define MPI_IOCFACTS_CAPABILITY_BIDIRECTIONAL (0x00000080)
+#define MPI_IOCFACTS_CAPABILITY_MULTICAST (0x00000100)
+#define MPI_IOCFACTS_CAPABILITY_SCSIIO32 (0x00000200)
+#define MPI_IOCFACTS_CAPABILITY_NO_SCSIIO16 (0x00000400)
/*****************************************************************************
@@ -677,6 +683,7 @@ typedef struct _EVENT_DATA_DISCOVERY_ERROR
#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_SUBTRACTIVE (0x00000200)
#define MPI_EVENT_DSCVRY_ERR_DS_TABLE_TO_TABLE (0x00000400)
#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS (0x00000800)
+#define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS (0x00001000)
/*****************************************************************************
diff --git a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h
index 623901fd82be..3f462859ceea 100644
--- a/drivers/message/fusion/lsi/mpi_targ.h
+++ b/drivers/message/fusion/lsi/mpi_targ.h
@@ -6,7 +6,7 @@
* Title: MPI Target mode messages and structures
* Creation Date: June 22, 2000
*
- * mpi_targ.h Version: 01.05.04
+ * mpi_targ.h Version: 01.05.05
*
* Version History
* ---------------
@@ -53,6 +53,7 @@
* 10-05-04 01.05.02 MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added.
* 02-22-05 01.05.03 Changed a comment.
* 03-11-05 01.05.04 Removed TargetAssistExtended Request.
+ * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines.
* --------------------------------------------------------------------------
*/
@@ -371,6 +372,77 @@ typedef struct _MSG_TARGET_ERROR_REPLY
/****************************************************************************/
+/* Target Assist Extended Request */
+/****************************************************************************/
+
+typedef struct _MSG_TARGET_ASSIST_EXT_REQUEST
+{
+ U8 StatusCode; /* 00h */
+ U8 TargetAssistFlags; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U16 QueueTag; /* 04h */
+ U8 Reserved1; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U32 ReplyWord; /* 0Ch */
+ U8 LUN[8]; /* 10h */
+ U32 RelativeOffset; /* 18h */
+ U32 Reserved2; /* 1Ch */
+ U32 Reserved3; /* 20h */
+ U32 PrimaryReferenceTag; /* 24h */
+ U16 PrimaryApplicationTag; /* 28h */
+ U16 PrimaryApplicationTagMask; /* 2Ah */
+ U32 Reserved4; /* 2Ch */
+ U32 DataLength; /* 30h */
+ U32 BidirectionalDataLength; /* 34h */
+ U32 SecondaryReferenceTag; /* 38h */
+ U16 SecondaryApplicationTag; /* 3Ch */
+ U16 Reserved5; /* 3Eh */
+ U16 EEDPFlags; /* 40h */
+ U16 ApplicationTagTranslationMask; /* 42h */
+ U32 EEDPBlockSize; /* 44h */
+ U8 SGLOffset0; /* 48h */
+ U8 SGLOffset1; /* 49h */
+ U8 SGLOffset2; /* 4Ah */
+ U8 SGLOffset3; /* 4Bh */
+ U32 Reserved6; /* 4Ch */
+ SGE_IO_UNION SGL[1]; /* 50h */
+} MSG_TARGET_ASSIST_EXT_REQUEST, MPI_POINTER PTR_MSG_TARGET_ASSIST_EXT_REQUEST,
+ TargetAssistExtRequest_t, MPI_POINTER pTargetAssistExtRequest_t;
+
+/* see the defines after MSG_TARGET_ASSIST_REQUEST for TargetAssistFlags */
+
+/* defines for the MsgFlags field */
+#define TARGET_ASSIST_EXT_MSGFLAGS_BIDIRECTIONAL (0x20)
+#define TARGET_ASSIST_EXT_MSGFLAGS_MULTICAST (0x10)
+#define TARGET_ASSIST_EXT_MSGFLAGS_SGL_OFFSET_CHAINS (0x08)
+
+/* defines for the EEDPFlags field */
+#define TARGET_ASSIST_EXT_EEDP_MASK_OP (0x0007)
+#define TARGET_ASSIST_EXT_EEDP_NOOP_OP (0x0000)
+#define TARGET_ASSIST_EXT_EEDP_CHK_OP (0x0001)
+#define TARGET_ASSIST_EXT_EEDP_STRIP_OP (0x0002)
+#define TARGET_ASSIST_EXT_EEDP_CHKRM_OP (0x0003)
+#define TARGET_ASSIST_EXT_EEDP_INSERT_OP (0x0004)
+#define TARGET_ASSIST_EXT_EEDP_REPLACE_OP (0x0006)
+#define TARGET_ASSIST_EXT_EEDP_CHKREGEN_OP (0x0007)
+
+#define TARGET_ASSIST_EXT_EEDP_PASS_REF_TAG (0x0008)
+
+#define TARGET_ASSIST_EXT_EEDP_T10_CHK_MASK (0x0700)
+#define TARGET_ASSIST_EXT_EEDP_T10_CHK_GUARD (0x0100)
+#define TARGET_ASSIST_EXT_EEDP_T10_CHK_APPTAG (0x0200)
+#define TARGET_ASSIST_EXT_EEDP_T10_CHK_REFTAG (0x0400)
+#define TARGET_ASSIST_EXT_EEDP_T10_CHK_SHIFT (8)
+
+#define TARGET_ASSIST_EXT_EEDP_INC_SEC_APPTAG (0x1000)
+#define TARGET_ASSIST_EXT_EEDP_INC_PRI_APPTAG (0x2000)
+#define TARGET_ASSIST_EXT_EEDP_INC_SEC_REFTAG (0x4000)
+#define TARGET_ASSIST_EXT_EEDP_INC_PRI_REFTAG (0x8000)
+
+
+/****************************************************************************/
/* Target Status Send Request */
/****************************************************************************/
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index ffbe6f4720e1..790a2932ded9 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -135,13 +135,12 @@ static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
-//static u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
-static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag);
+static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
@@ -152,6 +151,7 @@ static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
static int GetLanConfigPages(MPT_ADAPTER *ioc);
static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
static int GetIoUnitPage2(MPT_ADAPTER *ioc);
+int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
@@ -159,6 +159,8 @@ 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);
+static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
+static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
#ifdef CONFIG_PROC_FS
static int procmpt_summary_read(char *buf, char **start, off_t offset,
@@ -175,6 +177,7 @@ static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *
static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
+static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
/* module entry point */
static int __init fusion_init (void);
@@ -206,6 +209,144 @@ pci_enable_io_access(struct pci_dev *pdev)
pci_write_config_word(pdev, PCI_COMMAND, command_reg);
}
+/*
+ * Process turbo (context) reply...
+ */
+static void
+mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
+{
+ MPT_FRAME_HDR *mf = NULL;
+ MPT_FRAME_HDR *mr = NULL;
+ int req_idx = 0;
+ int cb_idx;
+
+ dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
+ ioc->name, pa));
+
+ switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
+ case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
+ req_idx = pa & 0x0000FFFF;
+ cb_idx = (pa & 0x00FF0000) >> 16;
+ mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
+ break;
+ case MPI_CONTEXT_REPLY_TYPE_LAN:
+ cb_idx = mpt_lan_index;
+ /*
+ * Blind set of mf to NULL here was fatal
+ * after lan_reply says "freeme"
+ * Fix sort of combined with an optimization here;
+ * added explicit check for case where lan_reply
+ * was just returning 1 and doing nothing else.
+ * For this case skip the callback, but set up
+ * proper mf value first here:-)
+ */
+ if ((pa & 0x58000000) == 0x58000000) {
+ req_idx = pa & 0x0000FFFF;
+ mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
+ mpt_free_msg_frame(ioc, mf);
+ mb();
+ return;
+ break;
+ }
+ mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
+ break;
+ case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
+ cb_idx = mpt_stm_index;
+ mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
+ break;
+ default:
+ cb_idx = 0;
+ BUG();
+ }
+
+ /* Check for (valid) IO callback! */
+ if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
+ MptCallbacks[cb_idx] == NULL) {
+ printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
+ __FUNCTION__, ioc->name, cb_idx);
+ goto out;
+ }
+
+ if (MptCallbacks[cb_idx](ioc, mf, mr))
+ mpt_free_msg_frame(ioc, mf);
+ out:
+ mb();
+}
+
+static void
+mpt_reply(MPT_ADAPTER *ioc, u32 pa)
+{
+ MPT_FRAME_HDR *mf;
+ MPT_FRAME_HDR *mr;
+ int req_idx;
+ int cb_idx;
+ int freeme;
+
+ u32 reply_dma_low;
+ u16 ioc_stat;
+
+ /* non-TURBO reply! Hmmm, something may be up...
+ * Newest turbo reply mechanism; get address
+ * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
+ */
+
+ /* Map DMA address of reply header to cpu address.
+ * pa is 32 bits - but the dma address may be 32 or 64 bits
+ * get offset based only only the low addresses
+ */
+
+ reply_dma_low = (pa <<= 1);
+ mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
+ (reply_dma_low - ioc->reply_frames_low_dma));
+
+ req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
+ cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
+ mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
+
+ dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
+ ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
+ DBG_DUMP_REPLY_FRAME(mr)
+
+ /* Check/log IOC log info
+ */
+ ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
+ if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
+ u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
+ if (ioc->bus_type == FC)
+ mpt_fc_log_info(ioc, log_info);
+ else if (ioc->bus_type == SCSI)
+ mpt_sp_log_info(ioc, log_info);
+ else if (ioc->bus_type == SAS)
+ mpt_sas_log_info(ioc, log_info);
+ }
+ if (ioc_stat & MPI_IOCSTATUS_MASK) {
+ if (ioc->bus_type == SCSI &&
+ cb_idx != mpt_stm_index &&
+ cb_idx != mpt_lan_index)
+ mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
+ }
+
+
+ /* Check for (valid) IO callback! */
+ if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
+ MptCallbacks[cb_idx] == NULL) {
+ printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
+ __FUNCTION__, ioc->name, cb_idx);
+ freeme = 0;
+ goto out;
+ }
+
+ freeme = MptCallbacks[cb_idx](ioc, mf, mr);
+
+ out:
+ /* Flush (non-TURBO) reply with a WRITE! */
+ CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
+
+ if (freeme)
+ mpt_free_msg_frame(ioc, mf);
+ mb();
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
@@ -218,8 +359,7 @@ pci_enable_io_access(struct pci_dev *pdev)
* (also referred to as a IO Controller or IOC).
* This routine must clear the interrupt from the adapter and does
* so by reading the reply FIFO. Multiple replies may be processed
- * per single call to this routine; up to MPT_MAX_REPLIES_PER_ISR
- * which is currently set to 32 in mptbase.h.
+ * per single call to this routine.
*
* This routine handles register-level access of the adapter but
* dispatches (calls) a protocol-specific callback routine to handle
@@ -228,164 +368,21 @@ pci_enable_io_access(struct pci_dev *pdev)
static irqreturn_t
mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
{
- MPT_ADAPTER *ioc;
- MPT_FRAME_HDR *mf;
- MPT_FRAME_HDR *mr;
- u32 pa;
- int req_idx;
- int cb_idx;
- int type;
- int freeme;
-
- ioc = (MPT_ADAPTER *)bus_id;
+ MPT_ADAPTER *ioc = bus_id;
+ u32 pa;
/*
* Drain the reply FIFO!
- *
- * NOTES: I've seen up to 10 replies processed in this loop, so far...
- * Update: I've seen up to 9182 replies processed in this loop! ??
- * Update: Limit ourselves to processing max of N replies
- * (bottom of loop).
*/
while (1) {
-
- if ((pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
+ pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
+ if (pa == 0xFFFFFFFF)
return IRQ_HANDLED;
-
- cb_idx = 0;
- freeme = 0;
-
- /*
- * Check for non-TURBO reply!
- */
- if (pa & MPI_ADDRESS_REPLY_A_BIT) {
- u32 reply_dma_low;
- u16 ioc_stat;
-
- /* non-TURBO reply! Hmmm, something may be up...
- * Newest turbo reply mechanism; get address
- * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
- */
-
- /* Map DMA address of reply header to cpu address.
- * pa is 32 bits - but the dma address may be 32 or 64 bits
- * get offset based only only the low addresses
- */
- reply_dma_low = (pa = (pa << 1));
- mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
- (reply_dma_low - ioc->reply_frames_low_dma));
-
- req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
- cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
- mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
-
- dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x\n",
- ioc->name, mr, req_idx));
- DBG_DUMP_REPLY_FRAME(mr)
-
- /* Check/log IOC log info
- */
- ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
- if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
- u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
- if (ioc->bus_type == FC)
- mpt_fc_log_info(ioc, log_info);
- else if (ioc->bus_type == SCSI)
- mpt_sp_log_info(ioc, log_info);
- }
- if (ioc_stat & MPI_IOCSTATUS_MASK) {
- if (ioc->bus_type == SCSI)
- mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
- }
- } else {
- /*
- * Process turbo (context) reply...
- */
- dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n", ioc->name, pa));
- type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
- if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
- cb_idx = mpt_stm_index;
- mf = NULL;
- mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
- } else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
- cb_idx = mpt_lan_index;
- /* Blind set of mf to NULL here was fatal
- * after lan_reply says "freeme"
- * Fix sort of combined with an optimization here;
- * added explicit check for case where lan_reply
- * was just returning 1 and doing nothing else.
- * For this case skip the callback, but set up
- * proper mf value first here:-)
- */
- if ((pa & 0x58000000) == 0x58000000) {
- req_idx = pa & 0x0000FFFF;
- mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
- freeme = 1;
- /*
- * IMPORTANT! Invalidate the callback!
- */
- cb_idx = 0;
- } else {
- mf = NULL;
- }
- mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
- } else {
- req_idx = pa & 0x0000FFFF;
- cb_idx = (pa & 0x00FF0000) >> 16;
- mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
- mr = NULL;
- }
- pa = 0; /* No reply flush! */
- }
-
-#ifdef MPT_DEBUG_IRQ
- if (ioc->bus_type == SCSI) {
- /* Verify mf, mr are reasonable.
- */
- if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
- || (mf < ioc->req_frames)) ) {
- printk(MYIOC_s_WARN_FMT
- "mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc->name, (void *)mf, req_idx);
- cb_idx = 0;
- pa = 0;
- freeme = 0;
- }
- if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth))
- || (mr < ioc->reply_frames)) ) {
- printk(MYIOC_s_WARN_FMT
- "mpt_interrupt: Invalid rf (%p)!\n", ioc->name, (void *)mr);
- cb_idx = 0;
- pa = 0;
- freeme = 0;
- }
- if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) {
- printk(MYIOC_s_WARN_FMT
- "mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx);
- cb_idx = 0;
- pa = 0;
- freeme = 0;
- }
- }
-#endif
-
- /* Check for (valid) IO callback! */
- if (cb_idx) {
- /* Do the callback! */
- freeme = (*(MptCallbacks[cb_idx]))(ioc, mf, mr);
- }
-
- if (pa) {
- /* Flush (non-TURBO) reply with a WRITE! */
- CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
- }
-
- if (freeme) {
- /* Put Request back on FreeQ! */
- mpt_free_msg_frame(ioc, mf);
- }
-
- mb();
- } /* drain reply FIFO */
+ else if (pa & MPI_ADDRESS_REPLY_A_BIT)
+ mpt_reply(ioc, pa);
+ else
+ mpt_turbo_reply(ioc, pa);
+ }
return IRQ_HANDLED;
}
@@ -399,7 +396,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
* @mf: Pointer to original MPT request frame
* @reply: Pointer to MPT reply frame (NULL if TurboReply)
*
- * Returns 1 indicating original alloc'd request frame ptr
+ * Returns 1 indicating original alloc'd request frame ptr
* should be freed, or 0 if it shouldn't.
*/
static int
@@ -408,28 +405,17 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
int freereq = 1;
u8 func;
- dprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
-
- if ((mf == NULL) ||
- (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
- printk(MYIOC_s_ERR_FMT "NULL or BAD request frame ptr! (=%p)\n",
- ioc->name, (void *)mf);
- return 1;
- }
-
- if (reply == NULL) {
- dprintk((MYIOC_s_ERR_FMT "Unexpected NULL Event (turbo?) reply!\n",
- ioc->name));
- return 1;
- }
+ dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
+#if defined(MPT_DEBUG_MSG_FRAME)
if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
DBG_DUMP_REQUEST_FRAME_HDR(mf)
}
+#endif
func = reply->u.hdr.Function;
- dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
+ dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
ioc->name, func));
if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
@@ -448,8 +434,14 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
* Hmmm... It seems that EventNotificationReply is an exception
* to the rule of one reply per request.
*/
- if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
+ if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
freereq = 0;
+ devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
+ ioc->name, pEvReply));
+ } else {
+ devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
+ ioc->name, pEvReply));
+ }
#ifdef CONFIG_PROC_FS
// LogEvent(ioc, pEvReply);
@@ -491,10 +483,21 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
pCfg->status = status;
if (status == MPI_IOCSTATUS_SUCCESS) {
- pCfg->hdr->PageVersion = pReply->Header.PageVersion;
- pCfg->hdr->PageLength = pReply->Header.PageLength;
- pCfg->hdr->PageNumber = pReply->Header.PageNumber;
- pCfg->hdr->PageType = pReply->Header.PageType;
+ if ((pReply->Header.PageType &
+ MPI_CONFIG_PAGETYPE_MASK) ==
+ MPI_CONFIG_PAGETYPE_EXTENDED) {
+ pCfg->cfghdr.ehdr->ExtPageLength =
+ le16_to_cpu(pReply->ExtPageLength);
+ pCfg->cfghdr.ehdr->ExtPageType =
+ pReply->ExtPageType;
+ }
+ pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
+
+ /* If this is a regular header, save PageLength. */
+ /* LMP Do this better so not using a reserved field! */
+ pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
+ pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
+ pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
}
}
@@ -504,6 +507,14 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
pCfg->wait_done = 1;
wake_up(&mpt_waitq);
}
+ } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
+ /* we should be always getting a reply frame */
+ memcpy(ioc->persist_reply_frame, reply,
+ min(MPT_DEFAULT_FRAME_SIZE,
+ 4*reply->u.reply.MsgLength));
+ del_timer(&ioc->persist_timer);
+ ioc->persist_wait_done = 1;
+ wake_up(&mpt_waitq);
} else {
printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
ioc->name, func);
@@ -705,7 +716,7 @@ mpt_device_driver_deregister(int cb_idx)
if (dd_cbfunc->remove)
dd_cbfunc->remove(ioc->pcidev);
}
-
+
MptDeviceDriverHandlers[cb_idx] = NULL;
}
@@ -745,6 +756,7 @@ mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
u.frame.linkage.list);
list_del(&mf->u.frame.linkage.list);
+ mf->u.frame.linkage.arg1 = 0;
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
/* u16! */
@@ -818,7 +830,7 @@ mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
}
#endif
- mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
+ mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
dsgprintk((MYIOC_s_INFO_FMT "mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, ioc->RequestNB[req_idx]));
CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
}
@@ -840,6 +852,7 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
/* Put Request back on FreeQ! */
spin_lock_irqsave(&ioc->FreeQlock, flags);
+ mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
#ifdef MFCNT
ioc->mfcnt--;
@@ -920,7 +933,7 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req,
/* Make sure there are no doorbells */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-
+
CHIPREG_WRITE32(&ioc->chip->Doorbell,
((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
@@ -935,14 +948,14 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req,
return -5;
dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
- ioc->name, ii));
+ ioc->name, ii));
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
return -2;
}
-
+
/* Send request via doorbell handshake */
req_as_bytes = (u8 *) req;
for (ii = 0; ii < reqBytes/4; ii++) {
@@ -966,12 +979,123 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req,
/* Make sure there are no doorbells */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-
+
return r;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
+ * mpt_host_page_access_control - provides mechanism for the host
+ * driver to control the IOC's Host Page Buffer access.
+ * @ioc: Pointer to MPT adapter structure
+ * @access_control_value: define bits below
+ *
+ * Access Control Value - bits[15:12]
+ * 0h Reserved
+ * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
+ * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
+ * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+
+static int
+mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
+{
+ int r = 0;
+
+ /* return if in use */
+ if (CHIPREG_READ32(&ioc->chip->Doorbell)
+ & MPI_DOORBELL_ACTIVE)
+ return -1;
+
+ CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+
+ CHIPREG_WRITE32(&ioc->chip->Doorbell,
+ ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
+ <<MPI_DOORBELL_FUNCTION_SHIFT) |
+ (access_control_value<<12)));
+
+ /* Wait for IOC to clear Doorbell Status bit */
+ if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
+ return -2;
+ }else
+ return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ * mpt_host_page_alloc - allocate system memory for the fw
+ * If we already allocated memory in past, then resend the same pointer.
+ * ioc@: Pointer to pointer to IOC adapter
+ * ioc_init@: Pointer to ioc init config page
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+static int
+mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
+{
+ char *psge;
+ int flags_length;
+ u32 host_page_buffer_sz=0;
+
+ if(!ioc->HostPageBuffer) {
+
+ host_page_buffer_sz =
+ le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
+
+ if(!host_page_buffer_sz)
+ return 0; /* fw doesn't need any host buffers */
+
+ /* spin till we get enough memory */
+ while(host_page_buffer_sz > 0) {
+
+ if((ioc->HostPageBuffer = pci_alloc_consistent(
+ ioc->pcidev,
+ host_page_buffer_sz,
+ &ioc->HostPageBuffer_dma)) != NULL) {
+
+ dinitprintk((MYIOC_s_INFO_FMT
+ "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
+ ioc->name,
+ ioc->HostPageBuffer,
+ ioc->HostPageBuffer_dma,
+ host_page_buffer_sz));
+ ioc->alloc_total += host_page_buffer_sz;
+ ioc->HostPageBuffer_sz = host_page_buffer_sz;
+ break;
+ }
+
+ host_page_buffer_sz -= (4*1024);
+ }
+ }
+
+ if(!ioc->HostPageBuffer) {
+ printk(MYIOC_s_ERR_FMT
+ "Failed to alloc memory for host_page_buffer!\n",
+ ioc->name);
+ return -999;
+ }
+
+ psge = (char *)&ioc_init->HostPageBufferSGE;
+ flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
+ MPI_SGE_FLAGS_SYSTEM_ADDRESS |
+ MPI_SGE_FLAGS_32_BIT_ADDRESSING |
+ MPI_SGE_FLAGS_HOST_TO_IOC |
+ MPI_SGE_FLAGS_END_OF_BUFFER;
+ if (sizeof(dma_addr_t) == sizeof(u64)) {
+ flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
+ }
+ flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
+ flags_length |= ioc->HostPageBuffer_sz;
+ mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
+ ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
+
+return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
* mpt_verify_adapter - Given a unique IOC identifier, set pointer to
* the associated MPT adapter structure.
* @iocid: IOC unique identifier (integer)
@@ -988,9 +1112,9 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
if (ioc->id == iocid) {
*iocpp =ioc;
return iocid;
- }
+ }
}
-
+
*iocpp = NULL;
return -1;
}
@@ -1032,9 +1156,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
if (pci_enable_device(pdev))
return r;
-
+
dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
-
+
if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
dprintk((KERN_INFO MYNAM
": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
@@ -1059,7 +1183,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->alloc_total = sizeof(MPT_ADAPTER);
ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
-
+
ioc->pcidev = pdev;
ioc->diagPending = 0;
spin_lock_init(&ioc->diagLock);
@@ -1079,7 +1203,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
/* Initilize SCSI Config Data structure
*/
- memset(&ioc->spi_data, 0, sizeof(ScsiCfgData));
+ memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
/* Initialize the running configQ head.
*/
@@ -1088,7 +1212,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
/* Find lookup slot. */
INIT_LIST_HEAD(&ioc->list);
ioc->id = mpt_ids++;
-
+
mem_phys = msize = 0;
port = psize = 0;
for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
@@ -1143,7 +1267,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->prod_name = "LSIFC909";
ioc->bus_type = FC;
}
- if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
ioc->prod_name = "LSIFC929";
ioc->bus_type = FC;
}
@@ -1208,6 +1332,33 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->prod_name = "LSI53C1035";
ioc->bus_type = SCSI;
}
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
+ ioc->prod_name = "LSISAS1064";
+ ioc->bus_type = SAS;
+ ioc->errata_flag_1064 = 1;
+ }
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) {
+ ioc->prod_name = "LSISAS1066";
+ ioc->bus_type = SAS;
+ ioc->errata_flag_1064 = 1;
+ }
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
+ ioc->prod_name = "LSISAS1068";
+ ioc->bus_type = SAS;
+ ioc->errata_flag_1064 = 1;
+ }
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
+ ioc->prod_name = "LSISAS1064E";
+ ioc->bus_type = SAS;
+ }
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) {
+ ioc->prod_name = "LSISAS1066E";
+ ioc->bus_type = SAS;
+ }
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
+ ioc->prod_name = "LSISAS1068E";
+ ioc->bus_type = SAS;
+ }
if (ioc->errata_flag_1064)
pci_disable_io_access(pdev);
@@ -1322,7 +1473,7 @@ mpt_detach(struct pci_dev *pdev)
remove_proc_entry(pname, NULL);
sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
remove_proc_entry(pname, NULL);
-
+
/* call per device driver remove entry point */
for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
if(MptDeviceDriverHandlers[ii] &&
@@ -1330,7 +1481,7 @@ mpt_detach(struct pci_dev *pdev)
MptDeviceDriverHandlers[ii]->remove(pdev);
}
}
-
+
/* Disable interrupts! */
CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
@@ -1403,7 +1554,7 @@ mpt_resume(struct pci_dev *pdev)
u32 device_state = pdev->current_state;
int recovery_state;
int ii;
-
+
printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
ioc->name, pdev, pci_name(pdev), device_state);
@@ -1534,7 +1685,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
break;
}
-
+
if (ii == 5) {
dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
@@ -1542,7 +1693,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
MptDisplayIocCapabilities(ioc);
}
-
+
if (alt_ioc_ready) {
if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
@@ -1599,8 +1750,23 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
*/
if (ret == 0) {
rc = mpt_do_upload(ioc, sleepFlag);
- if (rc != 0)
+ if (rc == 0) {
+ if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
+ /*
+ * Maintain only one pointer to FW memory
+ * so there will not be two attempt to
+ * downloadboot onboard dual function
+ * chips (mpt_adapter_disable,
+ * mpt_diag_reset)
+ */
+ ioc->cached_fw = NULL;
+ ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
+ ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
+ }
+ } else {
printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
+ ret = -5;
+ }
}
}
}
@@ -1613,7 +1779,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
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",
+ dinitprintk((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;
@@ -1635,7 +1801,22 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
* and we try GetLanConfigPages again...
*/
if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
- if (ioc->bus_type == FC) {
+ if (ioc->bus_type == SAS) {
+
+ /* clear persistency table */
+ if(ioc->facts.IOCExceptions &
+ MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
+ ret = mptbase_sas_persist_operation(ioc,
+ MPI_SAS_OP_CLEAR_NOT_PRESENT);
+ if(ret != 0)
+ return -1;
+ }
+
+ /* Find IM volumes
+ */
+ mpt_findImVolumes(ioc);
+
+ } else if (ioc->bus_type == FC) {
/*
* Pre-fetch FC port WWN and stuff...
* (FCPortPage0_t stuff)
@@ -1670,7 +1851,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
/* Find IM volumes
*/
- if (ioc->facts.MsgVersion >= 0x0102)
+ if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
mpt_findImVolumes(ioc);
/* Check, and possibly reset, the coalescing value
@@ -1700,7 +1881,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
}
if (alt_ioc_ready && MptResetHandlers[ii]) {
- dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
+ drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
ioc->name, ioc->alt_ioc->name, ii));
rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
handlers++;
@@ -1733,8 +1914,8 @@ mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
" searching for devfn match on %x or %x\n",
- ioc->name, pci_name(pdev), pdev->devfn,
- func-1, func+1));
+ ioc->name, pci_name(pdev), pdev->bus->number,
+ pdev->devfn, func-1, func+1));
peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
if (!peer) {
@@ -1778,7 +1959,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
if (ioc->cached_fw != NULL) {
ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
- if ((ret = mpt_downloadboot(ioc, NO_SLEEP)) < 0) {
+ if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
printk(KERN_WARNING MYNAM
": firmware downloadboot failure (%d)!\n", ret);
}
@@ -1826,9 +2007,9 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
}
kfree(ioc->spi_data.nvram);
- kfree(ioc->spi_data.pIocPg3);
+ kfree(ioc->raid_data.pIocPg3);
ioc->spi_data.nvram = NULL;
- ioc->spi_data.pIocPg3 = NULL;
+ ioc->raid_data.pIocPg3 = NULL;
if (ioc->spi_data.pIocPg4 != NULL) {
sz = ioc->spi_data.IocPg4Sz;
@@ -1847,6 +2028,23 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
kfree(ioc->ChainToChain);
ioc->ChainToChain = NULL;
+
+ if (ioc->HostPageBuffer != NULL) {
+ if((ret = mpt_host_page_access_control(ioc,
+ MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
+ printk(KERN_ERR MYNAM
+ ": %s: host page buffers free failed (%d)!\n",
+ __FUNCTION__, ret);
+ }
+ dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
+ ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
+ pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
+ ioc->HostPageBuffer,
+ ioc->HostPageBuffer_dma);
+ ioc->HostPageBuffer = NULL;
+ ioc->HostPageBuffer_sz = 0;
+ ioc->alloc_total -= ioc->HostPageBuffer_sz;
+ }
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1861,36 +2059,39 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
static void
mpt_adapter_dispose(MPT_ADAPTER *ioc)
{
- if (ioc != NULL) {
- int sz_first, sz_last;
+ int sz_first, sz_last;
- sz_first = ioc->alloc_total;
+ if (ioc == NULL)
+ return;
- mpt_adapter_disable(ioc);
+ sz_first = ioc->alloc_total;
- if (ioc->pci_irq != -1) {
- free_irq(ioc->pci_irq, ioc);
- ioc->pci_irq = -1;
- }
+ mpt_adapter_disable(ioc);
- if (ioc->memmap != NULL)
- iounmap(ioc->memmap);
+ if (ioc->pci_irq != -1) {
+ free_irq(ioc->pci_irq, ioc);
+ ioc->pci_irq = -1;
+ }
+
+ if (ioc->memmap != NULL) {
+ iounmap(ioc->memmap);
+ ioc->memmap = NULL;
+ }
#if defined(CONFIG_MTRR) && 0
- if (ioc->mtrr_reg > 0) {
- mtrr_del(ioc->mtrr_reg, 0, 0);
- dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
- }
+ if (ioc->mtrr_reg > 0) {
+ mtrr_del(ioc->mtrr_reg, 0, 0);
+ dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
+ }
#endif
- /* Zap the adapter lookup ptr! */
- list_del(&ioc->list);
+ /* Zap the adapter lookup ptr! */
+ list_del(&ioc->list);
- sz_last = ioc->alloc_total;
- dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
- ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
- kfree(ioc);
- }
+ sz_last = ioc->alloc_total;
+ dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
+ ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
+ kfree(ioc);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1977,7 +2178,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
}
/* Is it already READY? */
- if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
+ if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
return 0;
/*
@@ -1995,7 +2196,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
* Hmmm... Did it get left operational?
*/
if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
- dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
+ dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
ioc->name));
/* Check WhoInit.
@@ -2004,8 +2205,8 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
* Else, fall through to KickStart case
*/
whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
- dprintk((KERN_WARNING MYNAM
- ": whoinit 0x%x\n statefault %d force %d\n",
+ dinitprintk((KERN_INFO MYNAM
+ ": whoinit 0x%x statefault %d force %d\n",
whoinit, statefault, force));
if (whoinit == MPI_WHOINIT_PCI_PEER)
return -4;
@@ -2026,7 +2227,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
* Loop here waiting for IOC to come READY.
*/
ii = 0;
- cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
+ cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
@@ -2140,8 +2341,8 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
get_facts.Function = MPI_FUNCTION_IOC_FACTS;
/* Assert: All other get_facts fields are zero! */
- dinitprintk((MYIOC_s_INFO_FMT
- "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
+ dinitprintk((MYIOC_s_INFO_FMT
+ "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
ioc->name, req_sz, reply_sz));
/* No non-zero fields in the get_facts request are greater than
@@ -2174,7 +2375,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
- status = facts->IOCStatus & MPI_IOCSTATUS_MASK;
+ status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
/* CHECKME! IOCStatus, IOCLogInfo */
facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
@@ -2204,6 +2405,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
le32_to_cpu(facts->CurrentSenseBufferHighAddr);
facts->CurReplyFrameSize =
le16_to_cpu(facts->CurReplyFrameSize);
+ facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
/*
* Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
@@ -2221,7 +2423,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
if ( sz & 0x02 )
sz += 2;
facts->FWImageSize = sz;
-
+
if (!facts->RequestFrameSize) {
/* Something is wrong! */
printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
@@ -2240,7 +2442,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
ioc->NBShiftFactor = shiftFactor;
dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
ioc->name, vv, shiftFactor, r));
-
+
if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
/*
* Set values for this IOC's request & reply frame sizes,
@@ -2261,7 +2463,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
return r;
}
} else {
- printk(MYIOC_s_ERR_FMT
+ printk(MYIOC_s_ERR_FMT
"Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
RequestFrameSize)/sizeof(u32)));
@@ -2375,13 +2577,25 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
ioc->name, ioc->upload_fw, ioc->facts.Flags));
- if (ioc->bus_type == FC)
+ if(ioc->bus_type == SAS)
+ ioc_init.MaxDevices = ioc->facts.MaxDevices;
+ else if(ioc->bus_type == FC)
ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
else
ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
-
ioc_init.MaxBuses = MPT_MAX_BUS;
-
+ dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
+ ioc->name, ioc->facts.MsgVersion));
+ if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
+ // set MsgVersion and HeaderVersion host driver was built with
+ ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
+ ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
+
+ if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
+ ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
+ } else if(mpt_host_page_alloc(ioc, &ioc_init))
+ return -99;
+ }
ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
if (sizeof(dma_addr_t) == sizeof(u64)) {
@@ -2395,17 +2609,21 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
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;
+ ioc->facts.MaxDevices = ioc_init.MaxDevices;
+ ioc->facts.MaxBuses = ioc_init.MaxBuses;
dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
ioc->name, &ioc_init));
r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
- if (r != 0)
+ if (r != 0) {
+ printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
return r;
+ }
/* No need to byte swap the multibyte fields in the reply
* since we don't even look at it's contents.
@@ -2413,9 +2631,11 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
ioc->name, &ioc_init));
-
- if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
+
+ if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
+ printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
return r;
+ }
/* YIKES! SUPER IMPORTANT!!!
* Poll IocState until _OPERATIONAL while IOC is doing
@@ -2440,7 +2660,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
state = mpt_GetIocState(ioc, 1);
count++;
}
- dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
+ dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
ioc->name, count));
return r;
@@ -2462,7 +2682,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
{
PortEnable_t port_enable;
MPIDefaultReply_t reply_buf;
- int ii;
+ int rc;
int req_sz;
int reply_sz;
@@ -2484,22 +2704,15 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
/* RAID FW may take a long time to enable
*/
- if (ioc->bus_type == FC) {
- ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
- reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
- } else {
- ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
+ if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
+ > MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) {
+ rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
+ } else {
+ rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
+ reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag);
}
-
- if (ii != 0)
- return ii;
-
- /* We do not even look at the reply, so we need not
- * swap the multi-byte fields.
- */
-
- return 0;
+ return rc;
}
/*
@@ -2529,7 +2742,7 @@ mpt_free_fw_memory(MPT_ADAPTER *ioc)
int sz;
sz = ioc->facts.FWImageSize;
- dinitprintk((KERN_WARNING MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
+ dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
pci_free_consistent(ioc->pcidev, sz,
ioc->cached_fw, ioc->cached_fw_dma);
@@ -2573,9 +2786,9 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
mpt_alloc_fw_memory(ioc, sz);
- dinitprintk((KERN_WARNING MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
+ dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
-
+
if (ioc->cached_fw == NULL) {
/* Major Failure.
*/
@@ -2605,14 +2818,14 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
- dinitprintk((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n",
+ dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
prequest, sgeoffset));
DBG_DUMP_FW_REQUEST_FRAME(prequest)
ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
- dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii));
+ dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
cmdStatus = -EFAULT;
if (ii == 0) {
@@ -2627,10 +2840,10 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
cmdStatus = 0;
}
}
- dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
+ dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
ioc->name, cmdStatus));
-
+
if (cmdStatus) {
ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
@@ -2656,9 +2869,8 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
* <0 for fw upload failure.
*/
static int
-mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
+mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
{
- MpiFwHeader_t *pFwHeader;
MpiExtImageHeader_t *pExtImage;
u32 fwSize;
u32 diag0val;
@@ -2669,18 +2881,8 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
u32 load_addr;
u32 ioc_state=0;
- ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
- ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
-
- if ( ioc->facts.FWImageSize == 0 )
- return -1;
-
- if (ioc->cached_fw == NULL)
- return -2;
-
- /* prevent a second downloadboot and memory free with alt_ioc */
- if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
- ioc->alt_ioc->cached_fw = NULL;
+ ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
+ ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
@@ -2708,16 +2910,17 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
ioc->name, count));
break;
}
- /* wait 1 sec */
+ /* wait .1 sec */
if (sleepFlag == CAN_SLEEP) {
- msleep_interruptible (1000);
+ msleep_interruptible (100);
} else {
- mdelay (1000);
+ mdelay (100);
}
}
if ( count == 30 ) {
- ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
+ ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
+ "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
ioc->name, diag0val));
return -3;
}
@@ -2732,7 +2935,6 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
/* Set the DiagRwEn and Disable ARM bits */
CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
- pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
fwSize = (pFwHeader->ImageSize + 3)/4;
ptrFw = (u32 *) pFwHeader;
@@ -2761,8 +2963,8 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
fwSize = (pExtImage->ImageSize + 3) >> 2;
ptrFw = (u32 *)pExtImage;
- ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n",
- ioc->name, fwSize*4, ptrFw, load_addr));
+ ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
+ ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
while (fwSize--) {
@@ -2782,19 +2984,38 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
/* Clear the internal flash bad bit - autoincrementing register,
* so must do two writes.
*/
- CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
- diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
- diagRwData |= 0x4000000;
- CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
- CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
+ if (ioc->bus_type == SCSI) {
+ /*
+ * 1030 and 1035 H/W errata, workaround to access
+ * the ClearFlashBadSignatureBit
+ */
+ CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
+ diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
+ diagRwData |= 0x40000000;
+ CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
+ CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
+
+ } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
+ diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
+ MPI_DIAG_CLEAR_FLASH_BAD_SIG);
+
+ /* wait 1 msec */
+ if (sleepFlag == CAN_SLEEP) {
+ msleep_interruptible (1);
+ } else {
+ mdelay (1);
+ }
+ }
if (ioc->errata_flag_1064)
pci_disable_io_access(ioc->pcidev);
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
- ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
+ ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
+ "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
ioc->name, diag0val));
- diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
+ diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
ioc->name, diag0val));
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
@@ -2802,10 +3023,23 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
/* Write 0xFF to reset the sequencer */
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
+ if (ioc->bus_type == SAS) {
+ ioc_state = mpt_GetIocState(ioc, 0);
+ if ( (GetIocFacts(ioc, sleepFlag,
+ MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
+ ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
+ ioc->name, ioc_state));
+ return -EFAULT;
+ }
+ }
+
for (count=0; count<HZ*20; count++) {
if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
ioc->name, count, ioc_state));
+ if (ioc->bus_type == SAS) {
+ return 0;
+ }
if ((SendIocInit(ioc, sleepFlag)) != 0) {
ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
ioc->name));
@@ -2845,9 +3079,9 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
* 0 else
*
* Returns:
- * 1 - hard reset, READY
- * 0 - no reset due to History bit, READY
- * -1 - no reset due to History bit but not READY
+ * 1 - hard reset, READY
+ * 0 - no reset due to History bit, READY
+ * -1 - no reset due to History bit but not READY
* OR reset but failed to come READY
* -2 - no reset, could not enter DIAG mode
* -3 - reset but bad FW bit
@@ -2990,7 +3224,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
*
*/
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
- mdelay (1);
+ mdelay(1);
/*
* Now hit the reset bit in the Diagnostic register
@@ -3039,12 +3273,13 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
/* wait 1 sec */
if (sleepFlag == CAN_SLEEP) {
- ssleep(1);
+ msleep_interruptible (1000);
} else {
mdelay (1000);
}
}
- if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
+ if ((count = mpt_downloadboot(ioc,
+ (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
printk(KERN_WARNING MYNAM
": firmware downloadboot failure (%d)!\n", count);
}
@@ -3170,7 +3405,7 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
u32 state;
int cntdn, count;
- drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
+ drsprintk((KERN_INFO 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, 5, sleepFlag)) < 0)
@@ -3374,6 +3609,9 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
ioc->reply_frames = (MPT_FRAME_HDR *) mem;
ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
+ dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
+ ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
+
alloc_dma += reply_sz;
mem += reply_sz;
@@ -3382,7 +3620,7 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
ioc->req_frames = (MPT_FRAME_HDR *) mem;
ioc->req_frames_dma = alloc_dma;
- dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffers @ %p[%p]\n",
+ dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
ioc->name, mem, (void *)(ulong)alloc_dma));
ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
@@ -3408,7 +3646,7 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
ioc->ChainBuffer = mem;
ioc->ChainBufferDMA = alloc_dma;
- dinitprintk((KERN_INFO MYNAM " :%s.ChainBuffers @ %p(%p)\n",
+ dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
/* Initialize the free chain Q.
@@ -3513,7 +3751,7 @@ out_fail:
*/
static int
mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
- int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
+ int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
{
MPIDefaultReply_t *mptReply;
int failcnt = 0;
@@ -3588,7 +3826,7 @@ mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
*/
if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
failcnt++;
-
+
dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
@@ -3624,7 +3862,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
int count = 0;
u32 intstat=0;
- cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
+ cntdn = 1000 * howlong;
if (sleepFlag == CAN_SLEEP) {
while (--cntdn) {
@@ -3674,7 +3912,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
int count = 0;
u32 intstat=0;
- cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
+ cntdn = 1000 * howlong;
if (sleepFlag == CAN_SLEEP) {
while (--cntdn) {
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
@@ -3747,7 +3985,7 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
}
dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
- ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
+ ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
/*
@@ -3819,7 +4057,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
hdr.PageLength = 0;
hdr.PageNumber = 0;
hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
- cfg.hdr = &hdr;
+ cfg.cfghdr.hdr = &hdr;
cfg.physAddr = -1;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
cfg.dir = 0;
@@ -3863,7 +4101,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
hdr.PageLength = 0;
hdr.PageNumber = 1;
hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
- cfg.hdr = &hdr;
+ cfg.cfghdr.hdr = &hdr;
cfg.physAddr = -1;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
cfg.dir = 0;
@@ -3930,7 +4168,7 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
hdr.PageLength = 0;
hdr.PageNumber = 0;
hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
- cfg.hdr = &hdr;
+ cfg.cfghdr.hdr = &hdr;
cfg.physAddr = -1;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
cfg.dir = 0;
@@ -3988,6 +4226,85 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
+ * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @sas_address: 64bit SAS Address for operation.
+ * @target_id: specified target for operation
+ * @bus: specified bus for operation
+ * @persist_opcode: see below
+ *
+ * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
+ * devices not currently present.
+ * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
+ *
+ * NOTE: Don't use not this function during interrupt time.
+ *
+ * Returns: 0 for success, non-zero error
+ */
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+int
+mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
+{
+ SasIoUnitControlRequest_t *sasIoUnitCntrReq;
+ SasIoUnitControlReply_t *sasIoUnitCntrReply;
+ MPT_FRAME_HDR *mf = NULL;
+ MPIHeader_t *mpi_hdr;
+
+
+ /* insure garbage is not sent to fw */
+ switch(persist_opcode) {
+
+ case MPI_SAS_OP_CLEAR_NOT_PRESENT:
+ case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
+ break;
+
+ default:
+ return -1;
+ break;
+ }
+
+ printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
+
+ /* Get a MF for this command.
+ */
+ if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
+ printk("%s: no msg frames!\n",__FUNCTION__);
+ return -1;
+ }
+
+ mpi_hdr = (MPIHeader_t *) mf;
+ sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
+ memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
+ sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
+ sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
+ sasIoUnitCntrReq->Operation = persist_opcode;
+
+ init_timer(&ioc->persist_timer);
+ ioc->persist_timer.data = (unsigned long) ioc;
+ ioc->persist_timer.function = mpt_timer_expired;
+ ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
+ ioc->persist_wait_done=0;
+ add_timer(&ioc->persist_timer);
+ mpt_put_msg_frame(mpt_base_index, ioc, mf);
+ wait_event(mpt_waitq, ioc->persist_wait_done);
+
+ sasIoUnitCntrReply =
+ (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
+ if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
+ printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
+ __FUNCTION__,
+ sasIoUnitCntrReply->IOCStatus,
+ sasIoUnitCntrReply->IOCLogInfo);
+ return -1;
+ }
+
+ printk("%s: success\n",__FUNCTION__);
+ return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
* GetIoUnitPage2 - Retrieve BIOS version and boot order information.
* @ioc: Pointer to MPT_ADAPTER structure
*
@@ -4012,7 +4329,7 @@ GetIoUnitPage2(MPT_ADAPTER *ioc)
hdr.PageLength = 0;
hdr.PageNumber = 2;
hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
- cfg.hdr = &hdr;
+ cfg.cfghdr.hdr = &hdr;
cfg.physAddr = -1;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
cfg.dir = 0;
@@ -4102,7 +4419,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
header.PageLength = 0;
header.PageNumber = 0;
header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
- cfg.hdr = &header;
+ cfg.cfghdr.hdr = &header;
cfg.physAddr = -1;
cfg.pageAddr = portnum;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4122,6 +4439,8 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
ioc->spi_data.minSyncFactor = MPT_ASYNC;
ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
rc = 1;
+ ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
+ ioc->name, ioc->spi_data.minSyncFactor));
} else {
/* Save the Port Page 0 data
*/
@@ -4131,7 +4450,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
- dinitprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
+ ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
ioc->name, pPP0->Capabilities));
}
ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
@@ -4140,6 +4459,8 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
ioc->spi_data.minSyncFactor = (u8) (data >> 8);
+ ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
+ ioc->name, ioc->spi_data.minSyncFactor));
} else {
ioc->spi_data.maxSyncOffset = 0;
ioc->spi_data.minSyncFactor = MPT_ASYNC;
@@ -4152,8 +4473,11 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
(ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
- if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
+ if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
ioc->spi_data.minSyncFactor = MPT_ULTRA;
+ ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
+ ioc->name, ioc->spi_data.minSyncFactor));
+ }
}
}
if (pbuf) {
@@ -4168,7 +4492,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
header.PageLength = 0;
header.PageNumber = 2;
header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
- cfg.hdr = &header;
+ cfg.cfghdr.hdr = &header;
cfg.physAddr = -1;
cfg.pageAddr = portnum;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4236,7 +4560,7 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
header.PageLength = 0;
header.PageNumber = 1;
header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
- cfg.hdr = &header;
+ cfg.cfghdr.hdr = &header;
cfg.physAddr = -1;
cfg.pageAddr = portnum;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4245,8 +4569,8 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
if (mpt_config(ioc, &cfg) != 0)
return -EFAULT;
- ioc->spi_data.sdp1version = cfg.hdr->PageVersion;
- ioc->spi_data.sdp1length = cfg.hdr->PageLength;
+ ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
+ ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
header.PageVersion = 0;
header.PageLength = 0;
@@ -4255,8 +4579,8 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
if (mpt_config(ioc, &cfg) != 0)
return -EFAULT;
- ioc->spi_data.sdp0version = cfg.hdr->PageVersion;
- ioc->spi_data.sdp0length = cfg.hdr->PageLength;
+ ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
+ ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
@@ -4298,7 +4622,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
header.PageLength = 0;
header.PageNumber = 2;
header.PageType = MPI_CONFIG_PAGETYPE_IOC;
- cfg.hdr = &header;
+ cfg.cfghdr.hdr = &header;
cfg.physAddr = -1;
cfg.pageAddr = 0;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4320,10 +4644,10 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
if (mpt_config(ioc, &cfg) != 0)
goto done_and_free;
- if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
+ if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
mem = kmalloc(iocpage2sz, GFP_ATOMIC);
if (mem) {
- ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
+ ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
} else {
goto done_and_free;
}
@@ -4340,7 +4664,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
/* At least 1 RAID Volume
*/
pIocRv = pIoc2->RaidVolume;
- ioc->spi_data.isRaid = 0;
+ ioc->raid_data.isRaid = 0;
for (jj = 0; jj < nVols; jj++, pIocRv++) {
vid = pIocRv->VolumeID;
vbus = pIocRv->VolumeBus;
@@ -4349,7 +4673,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
/* find the match
*/
if (vbus == 0) {
- ioc->spi_data.isRaid |= (1 << vid);
+ ioc->raid_data.isRaid |= (1 << vid);
} else {
/* Error! Always bus 0
*/
@@ -4384,8 +4708,8 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
/* Free the old page
*/
- kfree(ioc->spi_data.pIocPg3);
- ioc->spi_data.pIocPg3 = NULL;
+ kfree(ioc->raid_data.pIocPg3);
+ ioc->raid_data.pIocPg3 = NULL;
/* There is at least one physical disk.
* Read and save IOC Page 3
@@ -4394,7 +4718,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
header.PageLength = 0;
header.PageNumber = 3;
header.PageType = MPI_CONFIG_PAGETYPE_IOC;
- cfg.hdr = &header;
+ cfg.cfghdr.hdr = &header;
cfg.physAddr = -1;
cfg.pageAddr = 0;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4422,7 +4746,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
mem = kmalloc(iocpage3sz, GFP_ATOMIC);
if (mem) {
memcpy(mem, (u8 *)pIoc3, iocpage3sz);
- ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem;
+ ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
}
}
@@ -4446,7 +4770,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
header.PageLength = 0;
header.PageNumber = 4;
header.PageType = MPI_CONFIG_PAGETYPE_IOC;
- cfg.hdr = &header;
+ cfg.cfghdr.hdr = &header;
cfg.physAddr = -1;
cfg.pageAddr = 0;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4498,7 +4822,7 @@ mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
header.PageLength = 0;
header.PageNumber = 1;
header.PageType = MPI_CONFIG_PAGETYPE_IOC;
- cfg.hdr = &header;
+ cfg.cfghdr.hdr = &header;
cfg.physAddr = -1;
cfg.pageAddr = 0;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4580,13 +4904,13 @@ SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
if (evnp == NULL) {
- dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
+ devtprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
ioc->name));
return 0;
}
memset(evnp, 0, sizeof(*evnp));
- dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch));
+ devtprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
evnp->ChainOffset = 0;
@@ -4610,8 +4934,10 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
EventAck_t *pAck;
if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
- printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n",
- ioc->name);
+ printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
+ "request frame for Event=%x EventContext=%x EventData=%x!\n",
+ ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
+ le32_to_cpu(evnp->Data[0]));
return -1;
}
memset(pAck, 0, sizeof(*pAck));
@@ -4647,10 +4973,11 @@ int
mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
{
Config_t *pReq;
+ ConfigExtendedPageHeader_t *pExtHdr = NULL;
MPT_FRAME_HDR *mf;
unsigned long flags;
int ii, rc;
- u32 flagsLength;
+ int flagsLength;
int in_isr;
/* Prevent calling wait_event() (below), if caller happens
@@ -4675,16 +5002,30 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
pReq->Reserved = 0;
pReq->ChainOffset = 0;
pReq->Function = MPI_FUNCTION_CONFIG;
+
+ /* Assume page type is not extended and clear "reserved" fields. */
pReq->ExtPageLength = 0;
pReq->ExtPageType = 0;
pReq->MsgFlags = 0;
+
for (ii=0; ii < 8; ii++)
pReq->Reserved2[ii] = 0;
- pReq->Header.PageVersion = pCfg->hdr->PageVersion;
- pReq->Header.PageLength = pCfg->hdr->PageLength;
- pReq->Header.PageNumber = pCfg->hdr->PageNumber;
- pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
+ pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
+ pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
+ pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
+ pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
+
+ if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
+ pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
+ pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
+ pReq->ExtPageType = pExtHdr->ExtPageType;
+ pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+
+ /* Page Length must be treated as a reserved field for the extended header. */
+ pReq->Header.PageLength = 0;
+ }
+
pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
/* Add a SGE to the config request.
@@ -4694,12 +5035,20 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
else
flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
- flagsLength |= pCfg->hdr->PageLength * 4;
+ if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
+ flagsLength |= pExtHdr->ExtPageLength * 4;
- mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
+ dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
+ ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
+ }
+ else {
+ flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
+
+ dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
+ ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
+ }
- dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
- ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
+ mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
/* Append pCfg pointer to end of mf
*/
@@ -4789,8 +5138,8 @@ mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
pReq->Reserved3 = 0;
pReq->NumAddressBytes = 0x01;
pReq->Reserved4 = 0;
- pReq->DataLength = 0x04;
- pdev = (struct pci_dev *) ioc->pcidev;
+ pReq->DataLength = cpu_to_le16(0x04);
+ pdev = ioc->pcidev;
if (pdev->devfn & 1)
pReq->DeviceAddr = 0xB2;
else
@@ -5321,8 +5670,8 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static char *
-EventDescriptionStr(u8 event, u32 evData0)
+static void
+EventDescriptionStr(u8 event, u32 evData0, char *evStr)
{
char *ds;
@@ -5375,8 +5724,95 @@ EventDescriptionStr(u8 event, u32 evData0)
ds = "Events(OFF) Change";
break;
case MPI_EVENT_INTEGRATED_RAID:
- ds = "Integrated Raid";
+ {
+ u8 ReasonCode = (u8)(evData0 >> 16);
+ switch (ReasonCode) {
+ case MPI_EVENT_RAID_RC_VOLUME_CREATED :
+ ds = "Integrated Raid: Volume Created";
+ break;
+ case MPI_EVENT_RAID_RC_VOLUME_DELETED :
+ ds = "Integrated Raid: Volume Deleted";
+ break;
+ case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
+ ds = "Integrated Raid: Volume Settings Changed";
+ break;
+ case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
+ ds = "Integrated Raid: Volume Status Changed";
+ break;
+ case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
+ ds = "Integrated Raid: Volume Physdisk Changed";
+ break;
+ case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
+ ds = "Integrated Raid: Physdisk Created";
+ break;
+ case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
+ ds = "Integrated Raid: Physdisk Deleted";
+ break;
+ case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
+ ds = "Integrated Raid: Physdisk Settings Changed";
+ break;
+ case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
+ ds = "Integrated Raid: Physdisk Status Changed";
+ break;
+ case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
+ ds = "Integrated Raid: Domain Validation Needed";
+ break;
+ case MPI_EVENT_RAID_RC_SMART_DATA :
+ ds = "Integrated Raid; Smart Data";
+ break;
+ case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
+ ds = "Integrated Raid: Replace Action Started";
+ break;
+ default:
+ ds = "Integrated Raid";
+ break;
+ }
+ break;
+ }
+ case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
+ ds = "SCSI Device Status Change";
+ break;
+ case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
+ {
+ u8 ReasonCode = (u8)(evData0 >> 16);
+ switch (ReasonCode) {
+ case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
+ ds = "SAS Device Status Change: Added";
+ break;
+ case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
+ ds = "SAS Device Status Change: Deleted";
+ break;
+ case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
+ ds = "SAS Device Status Change: SMART Data";
+ break;
+ case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
+ ds = "SAS Device Status Change: No Persistancy Added";
+ break;
+ default:
+ ds = "SAS Device Status Change: Unknown";
+ break;
+ }
+ break;
+ }
+ case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
+ ds = "Bus Timer Expired";
+ break;
+ case MPI_EVENT_QUEUE_FULL:
+ ds = "Queue Full";
break;
+ case MPI_EVENT_SAS_SES:
+ ds = "SAS SES Event";
+ break;
+ case MPI_EVENT_PERSISTENT_TABLE_FULL:
+ ds = "Persistent Table Full";
+ break;
+ case MPI_EVENT_SAS_PHY_LINK_STATUS:
+ ds = "SAS PHY Link Status";
+ break;
+ case MPI_EVENT_SAS_DISCOVERY_ERROR:
+ ds = "SAS Discovery Error";
+ break;
+
/*
* MPT base "custom" events may be added here...
*/
@@ -5384,7 +5820,7 @@ EventDescriptionStr(u8 event, u32 evData0)
ds = "Unknown";
break;
}
- return ds;
+ strcpy(evStr,ds);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -5406,7 +5842,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
int ii;
int r = 0;
int handlers = 0;
- char *evStr;
+ char evStr[100];
u8 event;
/*
@@ -5419,7 +5855,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
evData0 = le32_to_cpu(pEventReply->Data[0]);
}
- evStr = EventDescriptionStr(event, evData0);
+ EventDescriptionStr(event, evData0, evStr);
devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
ioc->name,
evStr,
@@ -5436,20 +5872,6 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
* Do general / base driver event processing
*/
switch(event) {
- case MPI_EVENT_NONE: /* 00 */
- case MPI_EVENT_LOG_DATA: /* 01 */
- case MPI_EVENT_STATE_CHANGE: /* 02 */
- case MPI_EVENT_UNIT_ATTENTION: /* 03 */
- case MPI_EVENT_IOC_BUS_RESET: /* 04 */
- case MPI_EVENT_EXT_BUS_RESET: /* 05 */
- case MPI_EVENT_RESCAN: /* 06 */
- case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
- case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
- case MPI_EVENT_LOGOUT: /* 09 */
- case MPI_EVENT_INTEGRATED_RAID: /* 0B */
- case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: /* 0C */
- default:
- break;
case MPI_EVENT_EVENT_CHANGE: /* 0A */
if (evDataLen) {
u8 evState = evData0 & 0xFF;
@@ -5462,6 +5884,8 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
}
}
break;
+ default:
+ break;
}
/*
@@ -5504,6 +5928,8 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
* If needed, send (a single) EventAck.
*/
if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
+ devtprintk((MYIOC_s_WARN_FMT
+ "EventAck required\n",ioc->name));
if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
ioc->name, ii));
@@ -5584,7 +6010,7 @@ mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
case 0x00080000:
desc = "Outbound DMA Overrun";
break;
-
+
case 0x00090000:
desc = "Task Management";
break;
@@ -5600,12 +6026,117 @@ mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
case 0x000C0000:
desc = "Untagged Table Size";
break;
-
+
}
printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
}
+/* strings for sas loginfo */
+ static char *originator_str[] = {
+ "IOP", /* 00h */
+ "PL", /* 01h */
+ "IR" /* 02h */
+ };
+ static char *iop_code_str[] = {
+ NULL, /* 00h */
+ "Invalid SAS Address", /* 01h */
+ NULL, /* 02h */
+ "Invalid Page", /* 03h */
+ NULL, /* 04h */
+ "Task Terminated" /* 05h */
+ };
+ static char *pl_code_str[] = {
+ NULL, /* 00h */
+ "Open Failure", /* 01h */
+ "Invalid Scatter Gather List", /* 02h */
+ "Wrong Relative Offset or Frame Length", /* 03h */
+ "Frame Transfer Error", /* 04h */
+ "Transmit Frame Connected Low", /* 05h */
+ "SATA Non-NCQ RW Error Bit Set", /* 06h */
+ "SATA Read Log Receive Data Error", /* 07h */
+ "SATA NCQ Fail All Commands After Error", /* 08h */
+ "SATA Error in Receive Set Device Bit FIS", /* 09h */
+ "Receive Frame Invalid Message", /* 0Ah */
+ "Receive Context Message Valid Error", /* 0Bh */
+ "Receive Frame Current Frame Error", /* 0Ch */
+ "SATA Link Down", /* 0Dh */
+ "Discovery SATA Init W IOS", /* 0Eh */
+ "Config Invalid Page", /* 0Fh */
+ "Discovery SATA Init Timeout", /* 10h */
+ "Reset", /* 11h */
+ "Abort", /* 12h */
+ "IO Not Yet Executed", /* 13h */
+ "IO Executed", /* 14h */
+ NULL, /* 15h */
+ NULL, /* 16h */
+ NULL, /* 17h */
+ NULL, /* 18h */
+ NULL, /* 19h */
+ NULL, /* 1Ah */
+ NULL, /* 1Bh */
+ NULL, /* 1Ch */
+ NULL, /* 1Dh */
+ NULL, /* 1Eh */
+ NULL, /* 1Fh */
+ "Enclosure Management" /* 20h */
+ };
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ * mpt_sas_log_info - Log information returned from SAS IOC.
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @log_info: U32 LogInfo reply word from the IOC
+ *
+ * Refer to lsi/mpi_log_sas.h.
+ */
+static void
+mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
+{
+union loginfo_type {
+ u32 loginfo;
+ struct {
+ u32 subcode:16;
+ u32 code:8;
+ u32 originator:4;
+ u32 bus_type:4;
+ }dw;
+};
+ union loginfo_type sas_loginfo;
+ char *code_desc = NULL;
+
+ sas_loginfo.loginfo = log_info;
+ if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
+ (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
+ return;
+ if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
+ (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
+ code_desc = iop_code_str[sas_loginfo.dw.code];
+ }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
+ (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
+ code_desc = pl_code_str[sas_loginfo.dw.code];
+ }
+
+ if (code_desc != NULL)
+ printk(MYIOC_s_INFO_FMT
+ "LogInfo(0x%08x): Originator={%s}, Code={%s},"
+ " SubCode(0x%04x)\n",
+ ioc->name,
+ log_info,
+ originator_str[sas_loginfo.dw.originator],
+ code_desc,
+ sas_loginfo.dw.subcode);
+ else
+ printk(MYIOC_s_INFO_FMT
+ "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
+ " SubCode(0x%04x)\n",
+ ioc->name,
+ log_info,
+ originator_str[sas_loginfo.dw.originator],
+ sas_loginfo.dw.code,
+ sas_loginfo.dw.subcode);
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
@@ -5692,7 +6223,7 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
break;
case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
- /* This error is checked in scsi_io_done(). Skip.
+ /* This error is checked in scsi_io_done(). Skip.
desc = "SCSI Data Underrun";
*/
break;
@@ -5767,6 +6298,7 @@ EXPORT_SYMBOL(mpt_findImVolumes);
EXPORT_SYMBOL(mpt_read_ioc_pg_3);
EXPORT_SYMBOL(mpt_alloc_fw_memory);
EXPORT_SYMBOL(mpt_free_fw_memory);
+EXPORT_SYMBOL(mptbase_sas_persist_operation);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 848fb236b175..75105277e22f 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -65,6 +65,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/mpi_sas.h" /* SAS support */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -76,8 +77,8 @@
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
#endif
-#define MPT_LINUX_VERSION_COMMON "3.03.02"
-#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.02"
+#define MPT_LINUX_VERSION_COMMON "3.03.03"
+#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.03"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
@@ -423,7 +424,7 @@ typedef struct _MPT_IOCTL {
/*
* 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 */
@@ -451,16 +452,13 @@ typedef struct _mpt_ioctl_events {
#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 */
@@ -472,10 +470,28 @@ typedef struct _ScsiCfgData {
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 mpt_dv; /* command line option: enhanced=1, basic=0 */
+ 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;
/*
* Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
@@ -530,11 +546,16 @@ 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 __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 */
MPT_IOCTL *ioctl; /* ioctl data pointer */
struct proc_dir_entry *ioc_dentry;
struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */
@@ -554,31 +575,35 @@ typedef struct _MPT_ADAPTER
#else
u32 mfcnt;
#endif
- u32 NB_for_64_byte_frame;
+ 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;
- /*
+ /*
* 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 errata_flag_1064;
u8 FirstWhoInit;
u8 upload_fw; /* If set, do a fw upload */
u8 reload_fw; /* Force a FW Reload on next reset */
- u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */
+ u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */
u8 pad1[4];
int DoneCtx;
int TaskCtx;
int InternalCtx;
- struct list_head list;
+ struct list_head list;
struct net_device *netdev;
+ struct list_head sas_topology;
} MPT_ADAPTER;
/*
@@ -915,7 +940,10 @@ struct scsi_cmnd;
typedef struct _x_config_parms {
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 */
@@ -961,6 +989,7 @@ 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...
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 05ea5944c487..cb2d59d5f5af 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -242,7 +242,7 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
/* Set the command status to GOOD if IOC Status is GOOD
* OR if SCSI I/O cmd and data underrun or recovered error.
*/
- iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK;
+ iocStatus = le16_to_cpu(reply->u.reply.IOCStatus) & MPI_IOCSTATUS_MASK;
if (iocStatus == MPI_IOCSTATUS_SUCCESS)
ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
@@ -1326,7 +1326,7 @@ mptctl_gettargetinfo (unsigned long arg)
*/
if (hd && hd->Targets) {
mpt_findImVolumes(ioc);
- pIoc2 = ioc->spi_data.pIocPg2;
+ pIoc2 = ioc->raid_data.pIocPg2;
for ( id = 0; id <= max_id; ) {
if ( pIoc2 && pIoc2->NumActiveVolumes ) {
if ( id == pIoc2->RaidVolume[0].VolumeID ) {
@@ -1348,7 +1348,7 @@ mptctl_gettargetinfo (unsigned long arg)
--maxWordsLeft;
goto next_id;
} else {
- pIoc3 = ioc->spi_data.pIocPg3;
+ pIoc3 = ioc->raid_data.pIocPg3;
for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) {
if ( pIoc3->PhysDisk[jj].PhysDiskID == id )
goto next_id;
@@ -2324,7 +2324,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
hdr.PageLength = 0;
hdr.PageNumber = 0;
hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
- cfg.hdr = &hdr;
+ cfg.cfghdr.hdr = &hdr;
cfg.physAddr = -1;
cfg.pageAddr = 0;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -2333,7 +2333,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
strncpy(karg.serial_number, " ", 24);
if (mpt_config(ioc, &cfg) == 0) {
- if (cfg.hdr->PageLength > 0) {
+ if (cfg.cfghdr.hdr->PageLength > 0) {
/* Issue the second config page request */
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
@@ -2479,7 +2479,7 @@ mptctl_hp_targetinfo(unsigned long arg)
hdr.PageNumber = 0;
hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
- cfg.hdr = &hdr;
+ cfg.cfghdr.hdr = &hdr;
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
cfg.dir = 0;
cfg.timeout = 0;
@@ -2527,15 +2527,15 @@ mptctl_hp_targetinfo(unsigned long arg)
hdr.PageNumber = 3;
hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
- cfg.hdr = &hdr;
+ cfg.cfghdr.hdr = &hdr;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
cfg.dir = 0;
cfg.timeout = 0;
cfg.physAddr = -1;
- if ((mpt_config(ioc, &cfg) == 0) && (cfg.hdr->PageLength > 0)) {
+ if ((mpt_config(ioc, &cfg) == 0) && (cfg.cfghdr.hdr->PageLength > 0)) {
/* Issue the second config page request */
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
- data_sz = (int) cfg.hdr->PageLength * 4;
+ data_sz = (int) cfg.cfghdr.hdr->PageLength * 4;
pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
ioc->pcidev, data_sz, &page_dma);
if (pg3_alloc) {
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 13771abea13f..a628be9bbbad 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -189,7 +189,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
ioc->name, ioc);
- return -ENODEV;
+ return 0;
}
sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 52794be5a95c..ed3c891e388f 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -312,7 +312,12 @@ static int
mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{
struct net_device *dev = ioc->netdev;
- struct mpt_lan_priv *priv = netdev_priv(dev);
+ struct mpt_lan_priv *priv;
+
+ if (dev == NULL)
+ return(1);
+ else
+ priv = netdev_priv(dev);
dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
new file mode 100644
index 000000000000..7de19a84dc74
--- /dev/null
+++ b/drivers/message/fusion/mptsas.c
@@ -0,0 +1,1239 @@
+/*
+ * linux/drivers/message/fusion/mptsas.c
+ * For use with LSI Logic PCI chip/adapter(s)
+ * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
+ *
+ * Copyright (c) 1999-2005 LSI Logic Corporation
+ * (mailto:mpt_linux_developer@lsil.com)
+ * Copyright (c) 2005 Dell
+ */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ 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; version 2 of the License.
+
+ 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.
+
+ NO WARRANTY
+ THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+ LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+ solely responsible for determining the appropriateness of using and
+ distributing the Program and assumes all risks associated with its
+ exercise of rights under this Agreement, including but not limited to
+ the risks and costs of program errors, damage to or loss of data,
+ programs or equipment, and unavailability or interruption of operations.
+
+ DISCLAIMER OF LIABILITY
+ NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+ HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+ 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/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/workqueue.h>
+
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport_sas.h>
+
+#include "mptbase.h"
+#include "mptscsih.h"
+
+
+#define my_NAME "Fusion MPT SAS Host driver"
+#define my_VERSION MPT_LINUX_VERSION_COMMON
+#define MYNAM "mptsas"
+
+MODULE_AUTHOR(MODULEAUTHOR);
+MODULE_DESCRIPTION(my_NAME);
+MODULE_LICENSE("GPL");
+
+static int mpt_pq_filter;
+module_param(mpt_pq_filter, int, 0);
+MODULE_PARM_DESC(mpt_pq_filter,
+ "Enable peripheral qualifier filter: enable=1 "
+ "(default=0)");
+
+static int mpt_pt_clear;
+module_param(mpt_pt_clear, int, 0);
+MODULE_PARM_DESC(mpt_pt_clear,
+ "Clear persistency table: enable=1 "
+ "(default=MPTSCSIH_PT_CLEAR=0)");
+
+static int mptsasDoneCtx = -1;
+static int mptsasTaskCtx = -1;
+static int mptsasInternalCtx = -1; /* Used only for internal commands */
+
+
+/*
+ * SAS topology structures
+ *
+ * The MPT Fusion firmware interface spreads information about the
+ * SAS topology over many manufacture pages, thus we need some data
+ * structure to collect it and process it for the SAS transport class.
+ */
+
+struct mptsas_devinfo {
+ u16 handle; /* unique id to address this device */
+ u8 phy_id; /* phy number of parent device */
+ u8 port_id; /* sas physical port this device
+ is assoc'd with */
+ u8 target; /* logical target id of this device */
+ u8 bus; /* logical bus number of this device */
+ u64 sas_address; /* WWN of this device,
+ SATA is assigned by HBA,expander */
+ u32 device_info; /* bitfield detailed info about this device */
+};
+
+struct mptsas_phyinfo {
+ u8 phy_id; /* phy index */
+ u8 port_id; /* port number this phy is part of */
+ u8 negotiated_link_rate; /* nego'd link rate for this phy */
+ u8 hw_link_rate; /* hardware max/min phys link rate */
+ u8 programmed_link_rate; /* programmed max/min phy link rate */
+ struct mptsas_devinfo identify; /* point to phy device info */
+ struct mptsas_devinfo attached; /* point to attached device info */
+ struct sas_rphy *rphy;
+};
+
+struct mptsas_portinfo {
+ struct list_head list;
+ u16 handle; /* unique id to address this */
+ u8 num_phys; /* number of phys */
+ struct mptsas_phyinfo *phy_info;
+};
+
+/*
+ * This is pretty ugly. We will be able to seriously clean it up
+ * once the DV code in mptscsih goes away and we can properly
+ * implement ->target_alloc.
+ */
+static int
+mptsas_slave_alloc(struct scsi_device *device)
+{
+ struct Scsi_Host *host = device->host;
+ MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
+ struct sas_rphy *rphy;
+ struct mptsas_portinfo *p;
+ VirtDevice *vdev;
+ uint target = device->id;
+ int i;
+
+ if ((vdev = hd->Targets[target]) != NULL)
+ goto out;
+
+ vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
+ if (!vdev) {
+ printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
+ hd->ioc->name, sizeof(VirtDevice));
+ return -ENOMEM;
+ }
+
+ memset(vdev, 0, sizeof(VirtDevice));
+ vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
+ vdev->ioc_id = hd->ioc->id;
+
+ rphy = dev_to_rphy(device->sdev_target->dev.parent);
+ list_for_each_entry(p, &hd->ioc->sas_topology, list) {
+ for (i = 0; i < p->num_phys; i++) {
+ if (p->phy_info[i].attached.sas_address ==
+ rphy->identify.sas_address) {
+ vdev->target_id =
+ p->phy_info[i].attached.target;
+ vdev->bus_id = p->phy_info[i].attached.bus;
+ hd->Targets[device->id] = vdev;
+ goto out;
+ }
+ }
+ }
+
+ printk("No matching SAS device found!!\n");
+ kfree(vdev);
+ return -ENODEV;
+
+ out:
+ vdev->num_luns++;
+ device->hostdata = vdev;
+ return 0;
+}
+
+static struct scsi_host_template mptsas_driver_template = {
+ .proc_name = "mptsas",
+ .proc_info = mptscsih_proc_info,
+ .name = "MPT SPI Host",
+ .info = mptscsih_info,
+ .queuecommand = mptscsih_qcmd,
+ .slave_alloc = mptsas_slave_alloc,
+ .slave_configure = mptscsih_slave_configure,
+ .slave_destroy = mptscsih_slave_destroy,
+ .change_queue_depth = mptscsih_change_queue_depth,
+ .eh_abort_handler = mptscsih_abort,
+ .eh_device_reset_handler = mptscsih_dev_reset,
+ .eh_bus_reset_handler = mptscsih_bus_reset,
+ .eh_host_reset_handler = mptscsih_host_reset,
+ .bios_param = mptscsih_bios_param,
+ .can_queue = MPT_FC_CAN_QUEUE,
+ .this_id = -1,
+ .sg_tablesize = MPT_SCSI_SG_DEPTH,
+ .max_sectors = 8192,
+ .cmd_per_lun = 7,
+ .use_clustering = ENABLE_CLUSTERING,
+};
+
+static struct sas_function_template mptsas_transport_functions = {
+};
+
+static struct scsi_transport_template *mptsas_transport_template;
+
+#ifdef SASDEBUG
+static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
+{
+ printk("---- IO UNIT PAGE 0 ------------\n");
+ printk("Handle=0x%X\n",
+ le16_to_cpu(phy_data->AttachedDeviceHandle));
+ printk("Controller Handle=0x%X\n",
+ le16_to_cpu(phy_data->ControllerDevHandle));
+ printk("Port=0x%X\n", phy_data->Port);
+ printk("Port Flags=0x%X\n", phy_data->PortFlags);
+ printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
+ printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
+ printk("Controller PHY Device Info=0x%X\n",
+ le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
+ printk("DiscoveryStatus=0x%X\n",
+ le32_to_cpu(phy_data->DiscoveryStatus));
+ printk("\n");
+}
+
+static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
+{
+ __le64 sas_address;
+
+ memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
+
+ printk("---- SAS PHY PAGE 0 ------------\n");
+ printk("Attached Device Handle=0x%X\n",
+ le16_to_cpu(pg0->AttachedDevHandle));
+ printk("SAS Address=0x%llX\n",
+ (unsigned long long)le64_to_cpu(sas_address));
+ printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
+ printk("Attached Device Info=0x%X\n",
+ le32_to_cpu(pg0->AttachedDeviceInfo));
+ printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
+ printk("Change Count=0x%X\n", pg0->ChangeCount);
+ printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
+ printk("\n");
+}
+
+static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
+{
+ __le64 sas_address;
+
+ memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
+
+ printk("---- SAS DEVICE PAGE 0 ---------\n");
+ printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
+ printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
+ printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
+ printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
+ printk("Target ID=0x%X\n", pg0->TargetID);
+ printk("Bus=0x%X\n", pg0->Bus);
+ printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
+ printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
+ printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
+ printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
+ printk("Physical Port=0x%X\n", pg0->PhysicalPort);
+ printk("\n");
+}
+
+static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
+{
+ printk("---- SAS EXPANDER PAGE 1 ------------\n");
+
+ printk("Physical Port=0x%X\n", pg1->PhysicalPort);
+ printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
+ printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
+ printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
+ printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
+ printk("Owner Device Handle=0x%X\n",
+ le16_to_cpu(pg1->OwnerDevHandle));
+ printk("Attached Device Handle=0x%X\n",
+ le16_to_cpu(pg1->AttachedDevHandle));
+}
+#else
+#define mptsas_print_phy_data(phy_data) do { } while (0)
+#define mptsas_print_phy_pg0(pg0) do { } while (0)
+#define mptsas_print_device_pg0(pg0) do { } while (0)
+#define mptsas_print_expander_pg1(pg1) do { } while (0)
+#endif
+
+static int
+mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
+{
+ ConfigExtendedPageHeader_t hdr;
+ CONFIGPARMS cfg;
+ SasIOUnitPage0_t *buffer;
+ dma_addr_t dma_handle;
+ int error, i;
+
+ hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
+ hdr.ExtPageLength = 0;
+ hdr.PageNumber = 0;
+ hdr.Reserved1 = 0;
+ hdr.Reserved2 = 0;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+ hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
+
+ cfg.cfghdr.ehdr = &hdr;
+ cfg.physAddr = -1;
+ cfg.pageAddr = 0;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+ cfg.dir = 0; /* read */
+ cfg.timeout = 10;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out;
+ if (!hdr.ExtPageLength) {
+ error = -ENXIO;
+ goto out;
+ }
+
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ &dma_handle);
+ if (!buffer) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out_free_consistent;
+
+ port_info->num_phys = buffer->NumPhys;
+ port_info->phy_info = kcalloc(port_info->num_phys,
+ sizeof(struct mptsas_phyinfo),GFP_KERNEL);
+ if (!port_info->phy_info) {
+ error = -ENOMEM;
+ goto out_free_consistent;
+ }
+
+ for (i = 0; i < port_info->num_phys; i++) {
+ mptsas_print_phy_data(&buffer->PhyData[i]);
+ port_info->phy_info[i].phy_id = i;
+ port_info->phy_info[i].port_id =
+ buffer->PhyData[i].Port;
+ port_info->phy_info[i].negotiated_link_rate =
+ buffer->PhyData[i].NegotiatedLinkRate;
+ }
+
+ out_free_consistent:
+ pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ buffer, dma_handle);
+ out:
+ return error;
+}
+
+static int
+mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
+ u32 form, u32 form_specific)
+{
+ ConfigExtendedPageHeader_t hdr;
+ CONFIGPARMS cfg;
+ SasPhyPage0_t *buffer;
+ dma_addr_t dma_handle;
+ int error;
+
+ hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
+ hdr.ExtPageLength = 0;
+ hdr.PageNumber = 0;
+ hdr.Reserved1 = 0;
+ hdr.Reserved2 = 0;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+ hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
+
+ cfg.cfghdr.ehdr = &hdr;
+ cfg.dir = 0; /* read */
+ cfg.timeout = 10;
+
+ /* Get Phy Pg 0 for each Phy. */
+ cfg.physAddr = -1;
+ cfg.pageAddr = form + form_specific;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out;
+
+ if (!hdr.ExtPageLength) {
+ error = -ENXIO;
+ goto out;
+ }
+
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ &dma_handle);
+ if (!buffer) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out_free_consistent;
+
+ mptsas_print_phy_pg0(buffer);
+
+ phy_info->hw_link_rate = buffer->HwLinkRate;
+ phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
+ phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
+ phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
+
+ out_free_consistent:
+ pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ buffer, dma_handle);
+ out:
+ return error;
+}
+
+static int
+mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
+ u32 form, u32 form_specific)
+{
+ ConfigExtendedPageHeader_t hdr;
+ CONFIGPARMS cfg;
+ SasDevicePage0_t *buffer;
+ dma_addr_t dma_handle;
+ __le64 sas_address;
+ int error;
+
+ hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
+ hdr.ExtPageLength = 0;
+ hdr.PageNumber = 0;
+ hdr.Reserved1 = 0;
+ hdr.Reserved2 = 0;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+ hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
+
+ cfg.cfghdr.ehdr = &hdr;
+ cfg.pageAddr = form + form_specific;
+ cfg.physAddr = -1;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+ cfg.dir = 0; /* read */
+ cfg.timeout = 10;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out;
+ if (!hdr.ExtPageLength) {
+ error = -ENXIO;
+ goto out;
+ }
+
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ &dma_handle);
+ if (!buffer) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out_free_consistent;
+
+ mptsas_print_device_pg0(buffer);
+
+ device_info->handle = le16_to_cpu(buffer->DevHandle);
+ device_info->phy_id = buffer->PhyNum;
+ device_info->port_id = buffer->PhysicalPort;
+ device_info->target = buffer->TargetID;
+ device_info->bus = buffer->Bus;
+ memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
+ device_info->sas_address = le64_to_cpu(sas_address);
+ device_info->device_info =
+ le32_to_cpu(buffer->DeviceInfo);
+
+ out_free_consistent:
+ pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ buffer, dma_handle);
+ out:
+ return error;
+}
+
+static int
+mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
+ u32 form, u32 form_specific)
+{
+ ConfigExtendedPageHeader_t hdr;
+ CONFIGPARMS cfg;
+ SasExpanderPage0_t *buffer;
+ dma_addr_t dma_handle;
+ int error;
+
+ hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
+ hdr.ExtPageLength = 0;
+ hdr.PageNumber = 0;
+ hdr.Reserved1 = 0;
+ hdr.Reserved2 = 0;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+ hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
+
+ cfg.cfghdr.ehdr = &hdr;
+ cfg.physAddr = -1;
+ cfg.pageAddr = form + form_specific;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+ cfg.dir = 0; /* read */
+ cfg.timeout = 10;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out;
+
+ if (!hdr.ExtPageLength) {
+ error = -ENXIO;
+ goto out;
+ }
+
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ &dma_handle);
+ if (!buffer) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out_free_consistent;
+
+ /* save config data */
+ port_info->num_phys = buffer->NumPhys;
+ port_info->handle = le16_to_cpu(buffer->DevHandle);
+ port_info->phy_info = kcalloc(port_info->num_phys,
+ sizeof(struct mptsas_phyinfo),GFP_KERNEL);
+ if (!port_info->phy_info) {
+ error = -ENOMEM;
+ goto out_free_consistent;
+ }
+
+ out_free_consistent:
+ pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ buffer, dma_handle);
+ out:
+ return error;
+}
+
+static int
+mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
+ u32 form, u32 form_specific)
+{
+ ConfigExtendedPageHeader_t hdr;
+ CONFIGPARMS cfg;
+ SasExpanderPage1_t *buffer;
+ dma_addr_t dma_handle;
+ int error;
+
+ hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
+ hdr.ExtPageLength = 0;
+ hdr.PageNumber = 1;
+ hdr.Reserved1 = 0;
+ hdr.Reserved2 = 0;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+ hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
+
+ cfg.cfghdr.ehdr = &hdr;
+ cfg.physAddr = -1;
+ cfg.pageAddr = form + form_specific;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+ cfg.dir = 0; /* read */
+ cfg.timeout = 10;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out;
+
+ if (!hdr.ExtPageLength) {
+ error = -ENXIO;
+ goto out;
+ }
+
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ &dma_handle);
+ if (!buffer) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ error = mpt_config(ioc, &cfg);
+ if (error)
+ goto out_free_consistent;
+
+
+ mptsas_print_expander_pg1(buffer);
+
+ /* save config data */
+ phy_info->phy_id = buffer->PhyIdentifier;
+ phy_info->port_id = buffer->PhysicalPort;
+ phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
+ phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
+ phy_info->hw_link_rate = buffer->HwLinkRate;
+ phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
+ phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
+
+
+ out_free_consistent:
+ pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+ buffer, dma_handle);
+ out:
+ return error;
+}
+
+static void
+mptsas_parse_device_info(struct sas_identify *identify,
+ struct mptsas_devinfo *device_info)
+{
+ u16 protocols;
+
+ identify->sas_address = device_info->sas_address;
+ identify->phy_identifier = device_info->phy_id;
+
+ /*
+ * Fill in Phy Initiator Port Protocol.
+ * Bits 6:3, more than one bit can be set, fall through cases.
+ */
+ protocols = device_info->device_info & 0x78;
+ identify->initiator_port_protocols = 0;
+ if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
+ identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
+ if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
+ identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
+ if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
+ identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
+ if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
+ identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
+
+ /*
+ * Fill in Phy Target Port Protocol.
+ * Bits 10:7, more than one bit can be set, fall through cases.
+ */
+ protocols = device_info->device_info & 0x780;
+ identify->target_port_protocols = 0;
+ if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
+ identify->target_port_protocols |= SAS_PROTOCOL_SSP;
+ if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
+ identify->target_port_protocols |= SAS_PROTOCOL_STP;
+ if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
+ identify->target_port_protocols |= SAS_PROTOCOL_SMP;
+ if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
+ identify->target_port_protocols |= SAS_PROTOCOL_SATA;
+
+ /*
+ * Fill in Attached device type.
+ */
+ switch (device_info->device_info &
+ MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
+ case MPI_SAS_DEVICE_INFO_NO_DEVICE:
+ identify->device_type = SAS_PHY_UNUSED;
+ break;
+ case MPI_SAS_DEVICE_INFO_END_DEVICE:
+ identify->device_type = SAS_END_DEVICE;
+ break;
+ case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
+ identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
+ break;
+ case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
+ identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
+ break;
+ }
+}
+
+static int mptsas_probe_one_phy(struct device *dev,
+ struct mptsas_phyinfo *phy_info, int index)
+{
+ struct sas_phy *port;
+ int error;
+
+ port = sas_phy_alloc(dev, index);
+ if (!port)
+ return -ENOMEM;
+
+ port->port_identifier = phy_info->port_id;
+ mptsas_parse_device_info(&port->identify, &phy_info->identify);
+
+ /*
+ * Set Negotiated link rate.
+ */
+ switch (phy_info->negotiated_link_rate) {
+ case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
+ port->negotiated_linkrate = SAS_PHY_DISABLED;
+ break;
+ case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
+ port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
+ break;
+ case MPI_SAS_IOUNIT0_RATE_1_5:
+ port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
+ break;
+ case MPI_SAS_IOUNIT0_RATE_3_0:
+ port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
+ break;
+ case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
+ case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
+ default:
+ port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
+ break;
+ }
+
+ /*
+ * Set Max hardware link rate.
+ */
+ switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
+ case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
+ port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
+ break;
+ case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
+ port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Set Max programmed link rate.
+ */
+ switch (phy_info->programmed_link_rate &
+ MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
+ case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
+ port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
+ break;
+ case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
+ port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Set Min hardware link rate.
+ */
+ switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
+ case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
+ port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
+ break;
+ case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
+ port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Set Min programmed link rate.
+ */
+ switch (phy_info->programmed_link_rate &
+ MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
+ case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
+ port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
+ break;
+ case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
+ port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
+ break;
+ default:
+ break;
+ }
+
+ error = sas_phy_add(port);
+ if (error) {
+ sas_phy_free(port);
+ return error;
+ }
+
+ if (phy_info->attached.handle) {
+ struct sas_rphy *rphy;
+
+ rphy = sas_rphy_alloc(port);
+ if (!rphy)
+ return 0; /* non-fatal: an rphy can be added later */
+
+ mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
+ error = sas_rphy_add(rphy);
+ if (error) {
+ sas_rphy_free(rphy);
+ return error;
+ }
+
+ phy_info->rphy = rphy;
+ }
+
+ return 0;
+}
+
+static int
+mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
+{
+ struct mptsas_portinfo *port_info;
+ u32 handle = 0xFFFF;
+ int error = -ENOMEM, i;
+
+ port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
+ if (!port_info)
+ goto out;
+ memset(port_info, 0, sizeof(*port_info));
+
+ error = mptsas_sas_io_unit_pg0(ioc, port_info);
+ if (error)
+ goto out_free_port_info;
+
+ list_add_tail(&port_info->list, &ioc->sas_topology);
+
+ for (i = 0; i < port_info->num_phys; i++) {
+ mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
+ (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
+ MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
+
+ mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
+ (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
+ MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
+ port_info->phy_info[i].identify.phy_id =
+ port_info->phy_info[i].phy_id;
+ handle = port_info->phy_info[i].identify.handle;
+
+ if (port_info->phy_info[i].attached.handle) {
+ mptsas_sas_device_pg0(ioc,
+ &port_info->phy_info[i].attached,
+ (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
+ MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
+ port_info->phy_info[i].attached.handle);
+ }
+
+ mptsas_probe_one_phy(&ioc->sh->shost_gendev,
+ &port_info->phy_info[i], *index);
+ (*index)++;
+ }
+
+ return 0;
+
+ out_free_port_info:
+ kfree(port_info);
+ out:
+ return error;
+}
+
+static int
+mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
+{
+ struct mptsas_portinfo *port_info, *p;
+ int error = -ENOMEM, i, j;
+
+ port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
+ if (!port_info)
+ goto out;
+ memset(port_info, 0, sizeof(*port_info));
+
+ error = mptsas_sas_expander_pg0(ioc, port_info,
+ (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
+ MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
+ if (error)
+ goto out_free_port_info;
+
+ *handle = port_info->handle;
+
+ list_add_tail(&port_info->list, &ioc->sas_topology);
+ for (i = 0; i < port_info->num_phys; i++) {
+ struct device *parent;
+
+ mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
+ (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
+ MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
+
+ if (port_info->phy_info[i].identify.handle) {
+ mptsas_sas_device_pg0(ioc,
+ &port_info->phy_info[i].identify,
+ (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
+ MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
+ port_info->phy_info[i].identify.handle);
+ port_info->phy_info[i].identify.phy_id =
+ port_info->phy_info[i].phy_id;
+ }
+
+ if (port_info->phy_info[i].attached.handle) {
+ mptsas_sas_device_pg0(ioc,
+ &port_info->phy_info[i].attached,
+ (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
+ MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
+ port_info->phy_info[i].attached.handle);
+ }
+
+ /*
+ * If we find a parent port handle this expander is
+ * attached to another expander, else it hangs of the
+ * HBA phys.
+ */
+ parent = &ioc->sh->shost_gendev;
+ list_for_each_entry(p, &ioc->sas_topology, list) {
+ for (j = 0; j < p->num_phys; j++) {
+ if (port_info->phy_info[i].identify.handle ==
+ p->phy_info[j].attached.handle)
+ parent = &p->phy_info[j].rphy->dev;
+ }
+ }
+
+ mptsas_probe_one_phy(parent, &port_info->phy_info[i], *index);
+ (*index)++;
+ }
+
+ return 0;
+
+ out_free_port_info:
+ kfree(port_info);
+ out:
+ return error;
+}
+
+static void
+mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
+{
+ u32 handle = 0xFFFF;
+ int index = 0;
+
+ mptsas_probe_hba_phys(ioc, &index);
+ while (!mptsas_probe_expander_phys(ioc, &handle, &index))
+ ;
+}
+
+static int
+mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ struct Scsi_Host *sh;
+ MPT_SCSI_HOST *hd;
+ MPT_ADAPTER *ioc;
+ unsigned long flags;
+ int sz, ii;
+ int numSGE = 0;
+ int scale;
+ int ioc_cap;
+ u8 *mem;
+ int error=0;
+ int r;
+
+ r = mpt_attach(pdev,id);
+ if (r)
+ return r;
+
+ ioc = pci_get_drvdata(pdev);
+ ioc->DoneCtx = mptsasDoneCtx;
+ ioc->TaskCtx = mptsasTaskCtx;
+ ioc->InternalCtx = mptsasInternalCtx;
+
+ /* 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 (!ioc->active) {
+ printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
+ ioc->name);
+ return -ENODEV;
+ }
+
+ /* 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++;
+ }
+
+ if (!ioc_cap) {
+ printk(MYIOC_s_WARN_FMT
+ "Skipping ioc=%p because SCSI Initiator mode "
+ "is NOT enabled!\n", ioc->name, ioc);
+ return 0;
+ }
+
+ sh = scsi_host_alloc(&mptsas_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);
+
+ /* 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;
+
+ sh->max_id = ioc->pfacts->MaxDevices + 1;
+
+ sh->transportt = mptsas_transport_template;
+
+ sh->max_lun = MPT_LAST_LUN + 1;
+ sh->max_channel = 0;
+ sh->this_id = ioc->pfacts[0].PortSCSIID;
+
+ /* Required entry.
+ */
+ sh->unique_id = ioc->id;
+
+ INIT_LIST_HEAD(&ioc->sas_topology);
+
+ /* 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;
+ }
+
+ spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+
+ hd = (MPT_SCSI_HOST *) sh->hostdata;
+ hd->ioc = ioc;
+
+ /* SCSI needs scsi_cmnd lookup table!
+ * (with size equal to req_depth*PtrSz!)
+ */
+ sz = ioc->req_depth * sizeof(void *);
+ mem = kmalloc(sz, GFP_ATOMIC);
+ if (mem == NULL) {
+ error = -ENOMEM;
+ goto mptsas_probe_failed;
+ }
+
+ memset(mem, 0, sz);
+ hd->ScsiLookup = (struct scsi_cmnd **) mem;
+
+ dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
+ ioc->name, hd->ScsiLookup, sz));
+
+ /* 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 mptsas_probe_failed;
+ }
+
+ memset(mem, 0, sz);
+ hd->Targets = (VirtDevice **) mem;
+
+ dprintk((KERN_INFO
+ " Targets @ %p, sz=%d\n", hd->Targets, sz));
+
+ /* Clear the TM flags
+ */
+ hd->tmPending = 0;
+ hd->tmState = TM_STATE_NONE;
+ hd->resetPending = 0;
+ hd->abortSCpnt = NULL;
+
+ /* Clear the pointer used to store
+ * single-threaded commands, i.e., those
+ * issued during a bus scan, dv and
+ * configuration pages.
+ */
+ hd->cmdPtr = NULL;
+
+ /* 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;
+
+ hd->mpt_pq_filter = mpt_pq_filter;
+ ioc->sas_data.ptClear = mpt_pt_clear;
+
+ if (ioc->sas_data.ptClear==1) {
+ mptbase_sas_persist_operation(
+ ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
+ }
+
+ ddvprintk((MYIOC_s_INFO_FMT
+ "mpt_pq_filter %x mpt_pq_filter %x\n",
+ ioc->name,
+ mpt_pq_filter,
+ mpt_pq_filter));
+
+ init_waitqueue_head(&hd->scandv_waitq);
+ hd->scandv_wait_done = 0;
+ hd->last_queue_full = 0;
+
+ error = scsi_add_host(sh, &ioc->pcidev->dev);
+ if (error) {
+ dprintk((KERN_ERR MYNAM
+ "scsi_add_host failed\n"));
+ goto mptsas_probe_failed;
+ }
+
+ mptsas_scan_sas_topology(ioc);
+
+ return 0;
+
+mptsas_probe_failed:
+
+ mptscsih_remove(pdev);
+ return error;
+}
+
+static void __devexit mptsas_remove(struct pci_dev *pdev)
+{
+ MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
+ struct mptsas_portinfo *p, *n;
+
+ sas_remove_host(ioc->sh);
+
+ list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
+ list_del(&p->list);
+ kfree(p);
+ }
+
+ mptscsih_remove(pdev);
+}
+
+static struct pci_device_id mptsas_pci_table[] = {
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
+ PCI_ANY_ID, PCI_ANY_ID },
+ {0} /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
+
+
+static struct pci_driver mptsas_driver = {
+ .name = "mptsas",
+ .id_table = mptsas_pci_table,
+ .probe = mptsas_probe,
+ .remove = __devexit_p(mptsas_remove),
+ .shutdown = mptscsih_shutdown,
+#ifdef CONFIG_PM
+ .suspend = mptscsih_suspend,
+ .resume = mptscsih_resume,
+#endif
+};
+
+static int __init
+mptsas_init(void)
+{
+ show_mptmod_ver(my_NAME, my_VERSION);
+
+ mptsas_transport_template =
+ sas_attach_transport(&mptsas_transport_functions);
+ if (!mptsas_transport_template)
+ return -ENODEV;
+
+ mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
+ mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
+ mptsasInternalCtx =
+ mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
+
+ if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
+ devtprintk((KERN_INFO MYNAM
+ ": Registered for IOC event notifications\n"));
+ }
+
+ if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
+ dprintk((KERN_INFO MYNAM
+ ": Registered for IOC reset notifications\n"));
+ }
+
+ return pci_register_driver(&mptsas_driver);
+}
+
+static void __exit
+mptsas_exit(void)
+{
+ pci_unregister_driver(&mptsas_driver);
+ sas_release_transport(mptsas_transport_template);
+
+ mpt_reset_deregister(mptsasDoneCtx);
+ mpt_event_deregister(mptsasDoneCtx);
+
+ mpt_deregister(mptsasInternalCtx);
+ mpt_deregister(mptsasTaskCtx);
+ mpt_deregister(mptsasDoneCtx);
+}
+
+module_init(mptsas_init);
+module_exit(mptsas_exit);
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index b9d4f78725b4..5cb07eb224d7 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -62,6 +62,7 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_dbg.h>
#include "mptbase.h"
#include "mptscsih.h"
@@ -93,8 +94,9 @@ typedef struct _BIG_SENSE_BUF {
#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
-#define MPT_ICFLAG_PHYS_DISK 0x04 /* Any SCSI IO but do Phys Disk Format */
-#define MPT_ICFLAG_TAGGED_CMD 0x08 /* Do tagged IO */
+#define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
+#define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
+#define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
@@ -159,6 +161,8 @@ int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR
static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
+static struct work_struct mptscsih_persistTask;
+
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
static void mptscsih_domainValidation(void *hd);
@@ -167,6 +171,7 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
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);
+static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
#endif
void mptscsih_remove(struct pci_dev *);
@@ -281,12 +286,12 @@ mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
chain_idx = offset / ioc->req_sz;
rc = SUCCESS;
- dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
- ioc->name, *retIndex, chainBuf));
+ dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
+ ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
} else {
rc = FAILED;
chain_idx = MPT_HOST_NO_CHAIN;
- dfailprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
+ dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
ioc->name));
}
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
@@ -432,7 +437,7 @@ nextSGEset:
*/
pReq->ChainOffset = 0;
RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
- dsgprintk((MYIOC_s_ERR_FMT
+ dsgprintk((MYIOC_s_INFO_FMT
"Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
ioc->RequestNB[req_idx] = RequestNB;
}
@@ -491,11 +496,12 @@ nextSGEset:
/* NOTE: psge points to the beginning of the chain element
* in current buffer. Get a chain buffer.
*/
- dsgprintk((MYIOC_s_INFO_FMT
- "calling getFreeChainBuffer SCSI cmd=%02x (%p)\n",
- ioc->name, pReq->CDB[0], SCpnt));
- if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED)
+ if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
+ dfailprintk((MYIOC_s_INFO_FMT
+ "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
+ ioc->name, pReq->CDB[0], SCpnt));
return FAILED;
+ }
/* Update the tracking arrays.
* If chainSge == NULL, update ReqToChain, else ChainToChain
@@ -577,14 +583,20 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
return 1;
}
- 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;
+ if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
+ dmfprintk((MYIOC_s_INFO_FMT
+ "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
+ ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
+ }else{
+ dmfprintk((MYIOC_s_INFO_FMT
+ "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
+ ioc->name, mf, mr, sc, req_idx));
+ }
+
if (pScsiReply == NULL) {
/* special context reply handling */
;
@@ -599,11 +611,24 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
sc->resid = sc->request_bufflen - xfer_cnt;
+ /*
+ * if we get a data underrun indication, yet no data was
+ * transferred and the SCSI status indicates that the
+ * command was never started, change the data underrun
+ * to success
+ */
+ if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
+ (scsi_status == MPI_SCSI_STATUS_BUSY ||
+ scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
+ scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
+ status = MPI_IOCSTATUS_SUCCESS;
+ }
+
dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
"IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
"resid=%d bufflen=%d xfer_cnt=%d\n",
ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
- status, scsi_state, scsi_status, sc->resid,
+ status, scsi_state, scsi_status, sc->resid,
sc->request_bufflen, xfer_cnt));
if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
@@ -612,8 +637,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
/*
* Look for + dump FCP ResponseInfo[]!
*/
- if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
- printk(KERN_NOTICE " FCP_ResponseInfo=%08xh\n",
+ if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
+ pScsiReply->ResponseInfo) {
+ printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
+ "FCP_ResponseInfo=%08xh\n",
+ ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
le32_to_cpu(pScsiReply->ResponseInfo));
}
@@ -654,21 +682,13 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
break;
case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
- if ( xfer_cnt >= sc->underflow ) {
- /* Sufficient data transfer occurred */
+ sc->resid = sc->request_bufflen - xfer_cnt;
+ if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
+ sc->result=DID_SOFT_ERROR << 16;
+ else /* Sufficient data transfer occurred */
sc->result = (DID_OK << 16) | scsi_status;
- } else if ( xfer_cnt == 0 ) {
- /* A CRC Error causes this condition; retry */
- sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
- (CHECK_CONDITION << 1);
- sc->sense_buffer[0] = 0x70;
- sc->sense_buffer[2] = NO_SENSE;
- sc->sense_buffer[12] = 0;
- sc->sense_buffer[13] = 0;
- } else {
- sc->result = DID_SOFT_ERROR << 16;
- }
- dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
+ dreplyprintk((KERN_NOTICE
+ "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
break;
case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
@@ -683,7 +703,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
;
} else {
if (xfer_cnt < sc->underflow) {
- sc->result = DID_SOFT_ERROR << 16;
+ if (scsi_status == SAM_STAT_BUSY)
+ sc->result = SAM_STAT_BUSY;
+ else
+ sc->result = DID_SOFT_ERROR << 16;
}
if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
/* What to do?
@@ -708,8 +731,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
- scsi_status = pScsiReply->SCSIStatus;
- sc->result = (DID_OK << 16) | scsi_status;
+ if (scsi_status == MPI_SCSI_STATUS_BUSY)
+ sc->result = (DID_BUS_BUSY << 16) | scsi_status;
+ else
+ sc->result = (DID_OK << 16) | scsi_status;
if (scsi_state == 0) {
;
} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
@@ -796,7 +821,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
return 1;
}
-
/*
* mptscsih_flush_running_cmds - For each command found, search
* Scsi_Host instance taskQ and reply to OS.
@@ -882,12 +906,13 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
SCSIIORequest_t *mf = NULL;
int ii;
int max = hd->ioc->req_depth;
+ struct scsi_cmnd *sc;
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) {
+ if ((sc = hd->ScsiLookup[ii]) != NULL) {
mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
@@ -902,9 +927,22 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
hd->ScsiLookup[ii] = NULL;
mptscsih_freeChainBuffers(hd->ioc, ii);
mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
+ if (sc->use_sg) {
+ pci_unmap_sg(hd->ioc->pcidev,
+ (struct scatterlist *) sc->request_buffer,
+ sc->use_sg,
+ sc->sc_data_direction);
+ } else if (sc->request_bufflen) {
+ pci_unmap_single(hd->ioc->pcidev,
+ sc->SCp.dma_handle,
+ sc->request_bufflen,
+ sc->sc_data_direction);
+ }
+ sc->host_scribble = NULL;
+ sc->result = DID_NO_CONNECT << 16;
+ sc->scsi_done(sc);
}
}
-
return;
}
@@ -959,8 +997,10 @@ mptscsih_remove(struct pci_dev *pdev)
unsigned long flags;
int sz1;
- if(!host)
+ if(!host) {
+ mpt_detach(pdev);
return;
+ }
scsi_remove_host(host);
@@ -1017,7 +1057,7 @@ mptscsih_remove(struct pci_dev *pdev)
scsi_host_put(host);
mpt_detach(pdev);
-
+
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1072,7 +1112,7 @@ mptscsih_resume(struct pci_dev *pdev)
MPT_SCSI_HOST *hd;
mpt_resume(pdev);
-
+
if(!host)
return 0;
@@ -1214,8 +1254,8 @@ mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t off
int size = 0;
if (func) {
- /*
- * write is not supported
+ /*
+ * write is not supported
*/
} else {
if (start)
@@ -1248,8 +1288,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
MPT_SCSI_HOST *hd;
MPT_FRAME_HDR *mf;
SCSIIORequest_t *pScsiReq;
- VirtDevice *pTarget;
- int target;
+ VirtDevice *pTarget = SCpnt->device->hostdata;
int lun;
u32 datalen;
u32 scsictl;
@@ -1259,12 +1298,9 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
int ii;
hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
- target = SCpnt->device->id;
lun = SCpnt->device->lun;
SCpnt->scsi_done = done;
- pTarget = hd->Targets[target];
-
dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
@@ -1307,7 +1343,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Default to untagged. Once a target structure has been allocated,
* use the Inquiry data to determine if device supports tagged.
*/
- if ( pTarget
+ if (pTarget
&& (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
&& (SCpnt->device->tagged_supported)) {
scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
@@ -1317,8 +1353,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Use the above information to set up the message frame
*/
- pScsiReq->TargetID = (u8) target;
- pScsiReq->Bus = (u8) SCpnt->device->channel;
+ pScsiReq->TargetID = (u8) pTarget->target_id;
+ pScsiReq->Bus = pTarget->bus_id;
pScsiReq->ChainOffset = 0;
pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
pScsiReq->CDBLength = SCpnt->cmd_len;
@@ -1370,7 +1406,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
if (hd->ioc->bus_type == SCSI) {
- int dvStatus = hd->ioc->spi_data.dvStatus[target];
+ int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id];
int issueCmd = 1;
if (dvStatus || hd->ioc->spi_data.forceDv) {
@@ -1418,6 +1454,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
return 0;
fail:
+ hd->ScsiLookup[my_idx] = NULL;
mptscsih_freeChainBuffers(hd->ioc, my_idx);
mpt_free_msg_frame(hd->ioc, mf);
return SCSI_MLQUEUE_HOST_BUSY;
@@ -1535,17 +1572,17 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
*/
if (mptscsih_tm_pending_wait(hd) == FAILED) {
if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
- dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: "
+ dtmprintk((KERN_INFO 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: "
+ dtmprintk((KERN_INFO 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: "
+ dtmprintk((KERN_INFO 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))
@@ -1631,8 +1668,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
hd->ioc->name));
- //return FAILED;
- return -999;
+ return FAILED;
}
dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
hd->ioc->name, mf));
@@ -1661,9 +1697,8 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
pScsiTm->TaskMsgContext = ctx2abort;
- dtmprintk((MYIOC_s_INFO_FMT
- "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
- hd->ioc->name, ctx2abort, type));
+ dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
+ hd->ioc->name, ctx2abort, type));
DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
@@ -1707,24 +1742,23 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
MPT_FRAME_HDR *mf;
u32 ctx2abort;
int scpnt_idx;
+ int retval;
/* If we can't locate our host adapter structure, return FAILED status.
*/
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
SCpnt->result = DID_RESET << 16;
SCpnt->scsi_done(SCpnt);
- dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
+ dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
"Can't locate host! (sc=%p)\n",
SCpnt));
return FAILED;
}
ioc = hd->ioc;
- if (hd->resetPending)
+ 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++;
@@ -1732,16 +1766,20 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
/* Find this command
*/
if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
- /* Cmd not found in ScsiLookup.
+ /* Cmd not found in ScsiLookup.
* Do OS callback.
*/
SCpnt->result = DID_RESET << 16;
- dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
+ dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
"Command not in the active list! (sc=%p)\n",
hd->ioc->name, SCpnt));
return SUCCESS;
}
+ printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
+ hd->ioc->name, SCpnt);
+ scsi_print_command(SCpnt);
+
/* Most important! Set TaskMsgContext to SCpnt's MsgContext!
* (the IO to be ABORT'd)
*
@@ -1754,38 +1792,22 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
hd->abortSCpnt = SCpnt;
- if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
+ retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
- ctx2abort, 2 /* 2 second timeout */)
- < 0) {
+ ctx2abort, 2 /* 2 second timeout */);
- /* The TM request failed and the subsequent FW-reload failed!
- * Fatal error case.
- */
- printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
- hd->ioc->name, SCpnt);
+ printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
+ hd->ioc->name,
+ ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
- /* We must clear our pending flag before clearing our state.
- */
+ if (retval == 0)
+ return SUCCESS;
+
+ if(retval != FAILED ) {
hd->tmPending = 0;
hd->tmState = TM_STATE_NONE;
-
- /* Unmap the DMA buffers, if any. */
- if (SCpnt->use_sg) {
- pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
- SCpnt->use_sg, SCpnt->sc_data_direction);
- } else if (SCpnt->request_bufflen) {
- pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
- SCpnt->request_bufflen, SCpnt->sc_data_direction);
- }
- hd->ScsiLookup[scpnt_idx] = NULL;
- SCpnt->result = DID_RESET << 16;
- SCpnt->scsi_done(SCpnt); /* Issue the command callback */
- mptscsih_freeChainBuffers(ioc, scpnt_idx);
- mpt_free_msg_frame(ioc, mf);
- return FAILED;
}
- return SUCCESS;
+ return FAILED;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1801,11 +1823,12 @@ int
mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
+ int retval;
/* If we can't locate our host adapter structure, return FAILED status.
*/
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
- dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: "
+ dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
"Can't locate host! (sc=%p)\n",
SCpnt));
return FAILED;
@@ -1814,24 +1837,26 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
if (hd->resetPending)
return FAILED;
- printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
+ printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
hd->ioc->name, SCpnt);
+ scsi_print_command(SCpnt);
- if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
+ retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
SCpnt->device->channel, SCpnt->device->id,
- 0, 0, 5 /* 5 second timeout */)
- < 0){
- /* The TM request failed and the subsequent FW-reload failed!
- * Fatal error case.
- */
- printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
- hd->ioc->name, SCpnt);
+ 0, 0, 5 /* 5 second timeout */);
+
+ printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
+ hd->ioc->name,
+ ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+
+ if (retval == 0)
+ return SUCCESS;
+
+ if(retval != FAILED ) {
hd->tmPending = 0;
hd->tmState = TM_STATE_NONE;
- return FAILED;
}
-
- return SUCCESS;
+ return FAILED;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1847,41 +1872,39 @@ int
mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
- spinlock_t *host_lock = SCpnt->device->host->host_lock;
+ int retval;
/* If we can't locate our host adapter structure, return FAILED status.
*/
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
- dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: "
+ dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
"Can't locate host! (sc=%p)\n",
SCpnt ) );
return FAILED;
}
- printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
+ printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
hd->ioc->name, SCpnt);
+ scsi_print_command(SCpnt);
if (hd->timeouts < -1)
hd->timeouts++;
- /* We are now ready to execute the task management request. */
- if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
- SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
- < 0){
+ retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
+ SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */);
- /* The TM request failed and the subsequent FW-reload failed!
- * Fatal error case.
- */
- printk(MYIOC_s_WARN_FMT
- "Error processing TaskMgmt request (sc=%p)\n",
- hd->ioc->name, SCpnt);
+ printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
+ hd->ioc->name,
+ ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+
+ if (retval == 0)
+ return SUCCESS;
+
+ if(retval != FAILED ) {
hd->tmPending = 0;
hd->tmState = TM_STATE_NONE;
- spin_lock_irq(host_lock);
- return FAILED;
}
-
- return SUCCESS;
+ return FAILED;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1902,13 +1925,13 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
/* If we can't locate the host to reset, then we failed. */
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
- dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
+ dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
"Can't locate host! (sc=%p)\n",
SCpnt ) );
return FAILED;
}
- printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
+ printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
hd->ioc->name, SCpnt);
/* If our attempts to reset the host failed, then return a failed
@@ -1924,7 +1947,7 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
hd->tmState = TM_STATE_NONE;
}
- dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
+ dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
"Status = %s\n",
(status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
@@ -1951,8 +1974,8 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
if (hd->tmState == TM_STATE_NONE) {
hd->tmState = TM_STATE_IN_PROGRESS;
hd->tmPending = 1;
- status = SUCCESS;
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+ status = SUCCESS;
break;
}
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
@@ -1980,7 +2003,7 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
if(hd->tmPending == 0) {
status = SUCCESS;
- spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+ spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
break;
}
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
@@ -2163,7 +2186,7 @@ mptscsih_slave_alloc(struct scsi_device *device)
vdev->raidVolume = 0;
hd->Targets[device->id] = vdev;
if (hd->ioc->bus_type == SCSI) {
- if (hd->ioc->spi_data.isRaid & (1 << device->id)) {
+ if (hd->ioc->raid_data.isRaid & (1 << device->id)) {
vdev->raidVolume = 1;
ddvtprintk((KERN_INFO
"RAID Volume @ id %d\n", device->id));
@@ -2174,22 +2197,7 @@ mptscsih_slave_alloc(struct scsi_device *device)
out:
vdev->num_luns++;
- return 0;
-}
-
-static int
-mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
-{
- int i;
-
- if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
- return 0;
-
- for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
- if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
- return 1;
- }
-
+ device->hostdata = vdev;
return 0;
}
@@ -2220,7 +2228,7 @@ mptscsih_slave_destroy(struct scsi_device *device)
hd->Targets[target] = NULL;
if (hd->ioc->bus_type == SCSI) {
- if (mptscsih_is_raid_volume(hd, target)) {
+ if (mptscsih_is_phys_disk(hd->ioc, target)) {
hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
} else {
hd->ioc->spi_data.dvStatus[target] =
@@ -2318,10 +2326,10 @@ mptscsih_slave_configure(struct scsi_device *device)
if (pTarget == NULL) {
/* Driver doesn't know about this device.
* Kernel may generate a "Dummy Lun 0" which
- * may become a real Lun if a
+ * may become a real Lun if a
* "scsi add-single-device" command is executed
- * while the driver is active (hot-plug a
- * device). LSI Raid controllers need
+ * while the driver is active (hot-plug a
+ * device). LSI Raid controllers need
* queue_depth set to DEV_HIGH for this reason.
*/
scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
@@ -2433,6 +2441,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{
MPT_SCSI_HOST *hd;
unsigned long flags;
+ int ii;
dtmprintk((KERN_WARNING MYNAM
": IOC %s_reset routed to SCSI host driver!\n",
@@ -2490,11 +2499,8 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
/* ScsiLookup initialization
*/
- {
- int ii;
- for (ii=0; ii < hd->ioc->req_depth; ii++)
- hd->ScsiLookup[ii] = NULL;
- }
+ for (ii=0; ii < hd->ioc->req_depth; ii++)
+ hd->ScsiLookup[ii] = NULL;
/* 2. Chain Buffer initialization
*/
@@ -2543,6 +2549,16 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* work queue thread to clear the persitency table */
+static void
+mptscsih_sas_persist_clear_table(void * arg)
+{
+ MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
+
+ mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
int
mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
{
@@ -2552,18 +2568,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
ioc->name, event));
+ if (ioc->sh == NULL ||
+ ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
+ return 1;
+
switch (event) {
case MPI_EVENT_UNIT_ATTENTION: /* 03 */
/* FIXME! */
break;
case MPI_EVENT_IOC_BUS_RESET: /* 04 */
case MPI_EVENT_EXT_BUS_RESET: /* 05 */
- hd = NULL;
- if (ioc->sh) {
- hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
- if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
- hd->soft_resets++;
- }
+ if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
+ hd->soft_resets++;
break;
case MPI_EVENT_LOGOUT: /* 09 */
/* FIXME! */
@@ -2582,69 +2598,24 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
break;
case MPI_EVENT_INTEGRATED_RAID: /* 0B */
+ {
+ pMpiEventDataRaid_t pRaidEventData =
+ (pMpiEventDataRaid_t) pEvReply->Data;
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
- /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
- * if DV disabled. Need to check for target mode.
- */
- hd = NULL;
- if (ioc->sh)
- hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
-
- if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
- ScsiCfgData *pSpi;
- Ioc3PhysDisk_t *pPDisk;
- int numPDisk;
- u8 reason;
- u8 physDiskNum;
-
- reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
- if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
- /* New or replaced disk.
- * Set DV flag and schedule DV.
- */
- pSpi = &ioc->spi_data;
- physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
- ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
- if (pSpi->pIocPg3) {
- pPDisk = pSpi->pIocPg3->PhysDisk;
- numPDisk =pSpi->pIocPg3->NumPhysDisks;
-
- while (numPDisk) {
- if (physDiskNum == pPDisk->PhysDiskNum) {
- pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
- pSpi->forceDv = MPT_SCSICFG_NEED_DV;
- ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
- break;
- }
- pPDisk++;
- numPDisk--;
- }
-
- if (numPDisk == 0) {
- /* The physical disk that needs DV was not found
- * in the stored IOC Page 3. The driver must reload
- * this page. DV routine will set the NEED_DV flag for
- * all phys disks that have DV_NOT_DONE set.
- */
- pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
- ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
- }
- }
- }
- }
+ /* Domain Validation Needed */
+ if (ioc->bus_type == SCSI &&
+ pRaidEventData->ReasonCode ==
+ MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
+ mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
#endif
+ break;
+ }
-#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
- printk("Raid Event RF: ");
- {
- u32 *m = (u32 *)pEvReply;
- int ii;
- int n = (int)pEvReply->MsgLength;
- for (ii=6; ii < n; ii++)
- printk(" %08x", le32_to_cpu(m[ii]));
- printk("\n");
- }
-#endif
+ /* Persistent table is full. */
+ case MPI_EVENT_PERSISTENT_TABLE_FULL:
+ INIT_WORK(&mptscsih_persistTask,
+ mptscsih_sas_persist_clear_table,(void *)ioc);
+ schedule_work(&mptscsih_persistTask);
break;
case MPI_EVENT_NONE: /* 00 */
@@ -2681,7 +2652,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
{
int indexed_lun, lun_index;
VirtDevice *vdev;
- ScsiCfgData *pSpi;
+ SpiCfgData *pSpi;
char data_56;
dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
@@ -2691,7 +2662,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
* If the peripheral qualifier filter is enabled then if the target reports a 0x1
* (i.e. The targer is capable of supporting the specified peripheral device type
* on this logical unit; however, the physical device is not currently connected
- * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
+ * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
* capable of supporting a physical device on this logical unit). This is to work
* around a bug in th emid-layer in some distributions in which the mid-layer will
* continue to try to communicate to the LUN and evntually create a dummy LUN.
@@ -2788,7 +2759,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
static void
mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
{
- ScsiCfgData *pspi_data = &hd->ioc->spi_data;
+ SpiCfgData *pspi_data = &hd->ioc->spi_data;
int id = (int) target->target_id;
int nvram;
VirtDevice *vdev;
@@ -2967,11 +2938,13 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
static void
mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
{
+ MPT_ADAPTER *ioc = hd->ioc;
u8 cmd;
- ScsiCfgData *pSpi;
+ SpiCfgData *pSpi;
- ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
- pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
+ ddvtprintk((MYIOC_s_NOTE_FMT
+ " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
+ hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
return;
@@ -2979,12 +2952,12 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
cmd = pReq->CDB[0];
if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
- pSpi = &hd->ioc->spi_data;
- if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
+ pSpi = &ioc->spi_data;
+ if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) {
/* Set NEED_DV for all hidden disks
*/
- Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk;
- int numPDisk = pSpi->pIocPg3->NumPhysDisks;
+ Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
+ int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
while (numPDisk) {
pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
@@ -2998,6 +2971,50 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
}
}
+/* mptscsih_raid_set_dv_flags()
+ *
+ * New or replaced disk. Set DV flag and schedule DV.
+ */
+static void
+mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
+{
+ MPT_ADAPTER *ioc = hd->ioc;
+ SpiCfgData *pSpi = &ioc->spi_data;
+ Ioc3PhysDisk_t *pPDisk;
+ int numPDisk;
+
+ if (hd->negoNvram != 0)
+ return;
+
+ ddvtprintk(("DV requested for phys disk id %d\n", id));
+ if (ioc->raid_data.pIocPg3) {
+ pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
+ numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
+ while (numPDisk) {
+ if (id == pPDisk->PhysDiskNum) {
+ pSpi->dvStatus[pPDisk->PhysDiskID] =
+ (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
+ pSpi->forceDv = MPT_SCSICFG_NEED_DV;
+ ddvtprintk(("NEED_DV set for phys disk id %d\n",
+ pPDisk->PhysDiskID));
+ break;
+ }
+ pPDisk++;
+ numPDisk--;
+ }
+
+ if (numPDisk == 0) {
+ /* The physical disk that needs DV was not found
+ * in the stored IOC Page 3. The driver must reload
+ * this page. DV routine will set the NEED_DV flag for
+ * all phys disks that have DV_NOT_DONE set.
+ */
+ pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
+ ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
+ }
+ }
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* If no Target, bus reset on 1st I/O. Set the flag to
@@ -3085,7 +3102,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
MPT_ADAPTER *ioc = hd->ioc;
Config_t *pReq;
SCSIDevicePage1_t *pData;
- VirtDevice *pTarget;
+ VirtDevice *pTarget=NULL;
MPT_FRAME_HDR *mf;
dma_addr_t dataDma;
u16 req_idx;
@@ -3184,7 +3201,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
#endif
if (flags & MPT_SCSICFG_BLK_NEGO)
- negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
+ negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
mptscsih_setDevicePage1Flags(width, factor, offset,
&requested, &configuration, negoFlags);
@@ -3194,8 +3211,8 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
/* Get a MF for this command.
*/
if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
- dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
- ioc->name));
+ dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
+ ioc->name));
return -EAGAIN;
}
@@ -3289,7 +3306,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
/* Get a MF for this command.
*/
if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
- dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
+ dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
ioc->name));
return -EAGAIN;
}
@@ -3447,7 +3464,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
* some type of error occurred.
*/
MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
- if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS)
+ if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
completionCode = MPT_SCANDV_GOOD;
else
completionCode = MPT_SCANDV_SOME_ERROR;
@@ -3955,7 +3972,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
header1.PageLength = ioc->spi_data.sdp1length;
header1.PageNumber = 1;
header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
- cfg.hdr = &header1;
+ cfg.cfghdr.hdr = &header1;
cfg.physAddr = cfg1_dma_addr;
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
cfg.dir = 1;
@@ -3996,16 +4013,16 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
"offset=0 negoFlags=%x request=%x config=%x\n",
id, flags, requested, configuration));
- pcfg1Data->RequestedParameters = le32_to_cpu(requested);
+ pcfg1Data->RequestedParameters = cpu_to_le32(requested);
pcfg1Data->Reserved = 0;
- pcfg1Data->Configuration = le32_to_cpu(configuration);
+ pcfg1Data->Configuration = cpu_to_le32(configuration);
cfg.pageAddr = (bus<<8) | id;
mpt_config(hd->ioc, &cfg);
}
/* If target Ptr NULL or if this target is NOT a disk, skip.
*/
- if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){
+ if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){
for (lun=0; lun <= MPT_LAST_LUN; lun++) {
/* If LUN present, issue the command
*/
@@ -4100,9 +4117,9 @@ mptscsih_domainValidation(void *arg)
if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
mpt_read_ioc_pg_3(ioc);
- if (ioc->spi_data.pIocPg3) {
- Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
- int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
+ if (ioc->raid_data.pIocPg3) {
+ Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
+ int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
while (numPDisk) {
if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
@@ -4141,7 +4158,7 @@ mptscsih_domainValidation(void *arg)
isPhysDisk = mptscsih_is_phys_disk(ioc, id);
if (isPhysDisk) {
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
- if (hd->ioc->spi_data.isRaid & (1 << ii)) {
+ if (hd->ioc->raid_data.isRaid & (1 << ii)) {
hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
}
}
@@ -4160,7 +4177,7 @@ mptscsih_domainValidation(void *arg)
if (isPhysDisk) {
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
- if (hd->ioc->spi_data.isRaid & (1 << ii)) {
+ if (hd->ioc->raid_data.isRaid & (1 << ii)) {
hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
}
}
@@ -4182,21 +4199,21 @@ mptscsih_domainValidation(void *arg)
/* Search IOC page 3 to determine if this is hidden physical disk
*/
-static int
+/* Search IOC page 3 to determine if this is hidden physical disk
+ */
+static int
mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
{
- if (ioc->spi_data.pIocPg3) {
- Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
- int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
+ int i;
- while (numPDisk) {
- if (pPDisk->PhysDiskID == id) {
- return 1;
- }
- pPDisk++;
- numPDisk--;
- }
+ if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
+ return 0;
+
+ for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
+ if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
+ return 1;
}
+
return 0;
}
@@ -4353,7 +4370,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* Prep cfg structure
*/
cfg.pageAddr = (bus<<8) | id;
- cfg.hdr = NULL;
+ cfg.cfghdr.hdr = NULL;
/* Prep SDP0 header
*/
@@ -4399,10 +4416,10 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
cfg1_dma_addr = dvbuf_dma + sz;
- /* Skip this ID? Set cfg.hdr to force config page write
+ /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
*/
{
- ScsiCfgData *pspi_data = &hd->ioc->spi_data;
+ SpiCfgData *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;
@@ -4417,7 +4434,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
dv.cmd = MPT_SET_MAX;
mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
- cfg.hdr = &header1;
+ cfg.cfghdr.hdr = &header1;
/* Save the final negotiated settings to
* SCSI device page 1.
@@ -4432,11 +4449,11 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
}
/* Finish iocmd inititialization - hidden or visible disk? */
- if (ioc->spi_data.pIocPg3) {
+ if (ioc->raid_data.pIocPg3) {
/* Search IOC page 3 for matching id
*/
- Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
- int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
+ Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
+ int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
while (numPDisk) {
if (pPDisk->PhysDiskID == id) {
@@ -4460,7 +4477,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* RAID Volume ID's may double for a physical device. If RAID but
* not a physical ID as well, skip DV.
*/
- if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
+ if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
goto target_done;
@@ -4483,7 +4500,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
dv.cmd = MPT_SET_MIN;
mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
- cfg.hdr = &header1;
+ cfg.cfghdr.hdr = &header1;
cfg.physAddr = cfg1_dma_addr;
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
cfg.dir = 1;
@@ -4596,8 +4613,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
if ((pbuf1[56] & 0x02) == 0) {
pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
- ddvprintk((MYIOC_s_NOTE_FMT
- "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
+ ddvprintk((MYIOC_s_NOTE_FMT
+ "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
ioc->name, id, pbuf1[56]));
}
}
@@ -4637,7 +4654,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
u32 sdp0_info;
u32 sdp0_nego;
- cfg.hdr = &header0;
+ cfg.cfghdr.hdr = &header0;
cfg.physAddr = cfg0_dma_addr;
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
cfg.dir = 0;
@@ -4673,7 +4690,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
if (!firstPass)
doFallback = 1;
} else {
- ddvprintk((MYIOC_s_NOTE_FMT
+ ddvprintk((MYIOC_s_NOTE_FMT
"DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
mptscsih_initTarget(hd,
@@ -4689,8 +4706,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
} else if (rc == MPT_SCANDV_ISSUE_SENSE)
doFallback = 1; /* set fallback flag */
- else if ((rc == MPT_SCANDV_DID_RESET) ||
- (rc == MPT_SCANDV_SENSE) ||
+ else if ((rc == MPT_SCANDV_DID_RESET) ||
+ (rc == MPT_SCANDV_SENSE) ||
(rc == MPT_SCANDV_FALLBACK))
doFallback = 1; /* set fallback flag */
else
@@ -4722,7 +4739,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
* 4) release
* 5) update nego parms to target struct
*/
- cfg.hdr = &header1;
+ cfg.cfghdr.hdr = &header1;
cfg.physAddr = cfg1_dma_addr;
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
cfg.dir = 1;
@@ -4809,6 +4826,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
notDone = 0;
if (iocmd.flags & MPT_ICFLAG_ECHO) {
bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
+ if (pbuf1[0] & 0x01)
+ iocmd.flags |= MPT_ICFLAG_EBOS;
} else {
bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
}
@@ -4905,6 +4924,9 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
}
iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
+ if (iocmd.flags & MPT_ICFLAG_EBOS)
+ goto skip_Reserve;
+
repeat = 5;
while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
iocmd.cmd = RESERVE;
@@ -4948,6 +4970,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
}
}
+skip_Reserve:
mptscsih_fillbuf(pbuf1, sz, patt, 1);
iocmd.cmd = WRITE_BUFFER;
iocmd.data_dma = buf1_dma;
@@ -5121,12 +5144,12 @@ target_done:
/* Set if cfg1_dma_addr contents is valid
*/
- if ((cfg.hdr != NULL) && (retcode == 0)){
+ if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){
/* If disk, not U320, disable QAS
*/
if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
- ddvprintk((MYIOC_s_NOTE_FMT
+ ddvprintk((MYIOC_s_NOTE_FMT
"noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
}
@@ -5137,7 +5160,7 @@ target_done:
* skip save of the final negotiated settings to
* SCSI device page 1.
*
- cfg.hdr = &header1;
+ cfg.cfghdr.hdr = &header1;
cfg.physAddr = cfg1_dma_addr;
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
cfg.dir = 1;
@@ -5192,11 +5215,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
* If not an LVD bus, the adapter minSyncFactor has been
* already throttled back.
*/
+ negoFlags = hd->ioc->spi_data.noQas;
if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
width = pTarget->maxWidth;
offset = pTarget->maxOffset;
factor = pTarget->minSyncFactor;
- negoFlags = pTarget->negoFlags;
+ negoFlags |= pTarget->negoFlags;
} else {
if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
data = hd->ioc->spi_data.nvram[id];
@@ -5217,7 +5241,6 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
}
/* Set the negotiation flags */
- negoFlags = hd->ioc->spi_data.noQas;
if (!width)
negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
@@ -5248,7 +5271,7 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
/* Update tmax values with those from Device Page 0.*/
pPage0 = (SCSIDevicePage0_t *) pPage;
if (pPage0) {
- val = cpu_to_le32(pPage0->NegotiatedParameters);
+ val = le32_to_cpu(pPage0->NegotiatedParameters);
dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
@@ -5276,12 +5299,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
dv->now.offset, &val, &configuration, dv->now.flags);
dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
- pPage1->RequestedParameters = le32_to_cpu(val);
+ pPage1->RequestedParameters = cpu_to_le32(val);
pPage1->Reserved = 0;
- pPage1->Configuration = le32_to_cpu(configuration);
+ pPage1->Configuration = cpu_to_le32(configuration);
}
- ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n",
+ ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n",
id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
break;
@@ -5301,9 +5324,9 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
offset, &val, &configuration, negoFlags);
dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
id, width, factor, offset, negoFlags, val, configuration));
- pPage1->RequestedParameters = le32_to_cpu(val);
+ pPage1->RequestedParameters = cpu_to_le32(val);
pPage1->Reserved = 0;
- pPage1->Configuration = le32_to_cpu(configuration);
+ pPage1->Configuration = cpu_to_le32(configuration);
}
ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
id, width, factor, offset, val, configuration, negoFlags));
@@ -5377,12 +5400,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
if (pPage1) {
mptscsih_setDevicePage1Flags (width, factor, offset, &val,
&configuration, dv->now.flags);
- dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n",
+ dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n",
id, width, offset, factor, dv->now.flags, val, configuration));
- pPage1->RequestedParameters = le32_to_cpu(val);
+ pPage1->RequestedParameters = cpu_to_le32(val);
pPage1->Reserved = 0;
- pPage1->Configuration = le32_to_cpu(configuration);
+ pPage1->Configuration = cpu_to_le32(configuration);
}
ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 51c0255ac16e..971fda4b8b57 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -1,5 +1,5 @@
/*
- * linux/drivers/message/fusion/mptscsi.h
+ * linux/drivers/message/fusion/mptscsih.h
* High performance SCSI / Fibre Channel SCSI Host device driver.
* For use with PCI chip/adapter(s):
* LSIFC9xx/LSI409xx Fibre Channel
@@ -53,8 +53,8 @@
* SCSI Public stuff...
*/
-#define MPT_SCSI_CMD_PER_DEV_HIGH 31
-#define MPT_SCSI_CMD_PER_DEV_LOW 7
+#define MPT_SCSI_CMD_PER_DEV_HIGH 64
+#define MPT_SCSI_CMD_PER_DEV_LOW 32
#define MPT_SCSI_CMD_PER_LUN 7
@@ -77,6 +77,7 @@
#define MPTSCSIH_MAX_WIDTH 1
#define MPTSCSIH_MIN_SYNC 0x08
#define MPTSCSIH_SAF_TE 0
+#define MPTSCSIH_PT_CLEAR 0
#endif
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index dfa8806b1e13..5c0e307d1d5d 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -162,15 +162,15 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
u8 *mem;
int error=0;
int r;
-
+
if ((r = mpt_attach(pdev,id)) != 0)
return r;
-
+
ioc = pci_get_drvdata(pdev);
ioc->DoneCtx = mptspiDoneCtx;
ioc->TaskCtx = mptspiTaskCtx;
ioc->InternalCtx = mptspiInternalCtx;
-
+
/* Added sanity check on readiness of the MPT adapter.
*/
if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
@@ -199,7 +199,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
ioc->name, ioc);
- return -ENODEV;
+ return 0;
}
sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST));