summaryrefslogtreecommitdiff
path: root/drivers/message/fusion
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r--drivers/message/fusion/Kconfig2
-rw-r--r--drivers/message/fusion/Makefile6
-rw-r--r--drivers/message/fusion/lsi/fc_log.h89
-rw-r--r--drivers/message/fusion/lsi/mpi.h5
-rw-r--r--drivers/message/fusion/lsi/mpi_cnfg.h158
-rw-r--r--drivers/message/fusion/lsi/mpi_history.txt76
-rw-r--r--drivers/message/fusion/lsi/mpi_init.h4
-rw-r--r--drivers/message/fusion/lsi/mpi_ioc.h154
-rw-r--r--drivers/message/fusion/lsi/mpi_log_sas.h82
-rw-r--r--drivers/message/fusion/lsi/mpi_sas.h13
-rw-r--r--drivers/message/fusion/lsi/mpi_targ.h5
-rw-r--r--drivers/message/fusion/mptbase.c174
-rw-r--r--drivers/message/fusion/mptbase.h23
-rw-r--r--drivers/message/fusion/mptctl.c4
-rw-r--r--drivers/message/fusion/mptctl.h5
-rw-r--r--drivers/message/fusion/mptfc.c122
-rw-r--r--drivers/message/fusion/mptsas.c1045
-rw-r--r--drivers/message/fusion/mptscsih.c118
-rw-r--r--drivers/message/fusion/mptspi.c14
19 files changed, 1429 insertions, 670 deletions
diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig
index bbc229852881..ea31d8470510 100644
--- a/drivers/message/fusion/Kconfig
+++ b/drivers/message/fusion/Kconfig
@@ -48,10 +48,8 @@ config FUSION_SAS
List of supported controllers:
LSISAS1064
- LSISAS1066
LSISAS1068
LSISAS1064E
- LSISAS1066E
LSISAS1068E
config FUSION_MAX_SGE
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile
index 51740b346224..341691390e86 100644
--- a/drivers/message/fusion/Makefile
+++ b/drivers/message/fusion/Makefile
@@ -9,7 +9,6 @@
#EXTRA_CFLAGS += -DMPT_DEBUG_EXIT
#EXTRA_CFLAGS += -DMPT_DEBUG_FAIL
-
#
# driver/module specifics...
#
@@ -33,6 +32,11 @@
# For mptfc:
#CFLAGS_mptfc.o += -DMPT_DEBUG_FC
+# For mptsas:
+#CFLAGS_mptsas.o += -DMPT_DEBUG_SAS
+#CFLAGS_mptsas.o += -DMPT_DEBUG_SAS_WIDE
+
+
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC
obj-$(CONFIG_FUSION_SPI) += mptbase.o mptscsih.o mptspi.o
diff --git a/drivers/message/fusion/lsi/fc_log.h b/drivers/message/fusion/lsi/fc_log.h
deleted file mode 100644
index dc98d46f9071..000000000000
--- a/drivers/message/fusion/lsi/fc_log.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2000-2001 LSI Logic Corporation. All rights reserved.
- *
- * NAME: fc_log.h
- * SUMMARY: MPI IocLogInfo definitions for the SYMFC9xx chips
- * DESCRIPTION: Contains the enumerated list of values that may be returned
- * in the IOCLogInfo field of a MPI Default Reply Message.
- *
- * CREATION DATE: 6/02/2000
- * ID: $Id: fc_log.h,v 4.6 2001/07/26 14:41:33 sschremm Exp $
- */
-
-
-/*
- * MpiIocLogInfo_t enum
- *
- * These 32 bit values are used in the IOCLogInfo field of the MPI reply
- * messages.
- * The value is 0xabcccccc where
- * a = The type of log info as per the MPI spec. Since these codes are
- * all for Fibre Channel this value will always be 2.
- * b = Specifies a subclass of the firmware where
- * 0 = FCP Initiator
- * 1 = FCP Target
- * 2 = LAN
- * 3 = MPI Message Layer
- * 4 = FC Link
- * 5 = Context Manager
- * 6 = Invalid Field Offset
- * 7 = State Change Info
- * all others are reserved for future use
- * c = A specific value within the subclass.
- *
- * NOTE: Any new values should be added to the end of each subclass so that the
- * codes remain consistent across firmware releases.
- */
-typedef enum _MpiIocLogInfoFc
-{
- MPI_IOCLOGINFO_FC_INIT_BASE = 0x20000000,
- MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME = 0x20000001, /* received an out of order frame - unsupported */
- MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primative */
- MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME = 0x20000003, /* Bad Rx Frame, bad end of frame primative */
- MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN = 0x20000004, /* Bad Rx Frame, overrun */
- MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER = 0x20000005, /* Other errors caught by IOC which require retries */
- MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD = 0x20000006, /* Main processor could not initialize sub-processor */
- MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OVERRUN = 0x20000007, /* Scatter Gather overrun */
- MPI_IOCLOGINFO_FC_INIT_ERROR_RX_BAD_STATUS = 0x20000008, /* Receiver detected context mismatch via invalid header */
- MPI_IOCLOGINFO_FC_INIT_ERROR_RX_UNEXPECTED_FRAME= 0x20000009, /* CtxMgr detected unsupported frame type */
- MPI_IOCLOGINFO_FC_INIT_ERROR_LINK_FAILURE = 0x2000000A, /* Link failure occurred */
- MPI_IOCLOGINFO_FC_INIT_ERROR_TX_TIMEOUT = 0x2000000B, /* Transmitter timeout error */
-
- MPI_IOCLOGINFO_FC_TARGET_BASE = 0x21000000,
- MPI_IOCLOGINFO_FC_TARGET_NO_PDISC = 0x21000001, /* not sent because we are waiting for a PDISC from the initiator */
- MPI_IOCLOGINFO_FC_TARGET_NO_LOGIN = 0x21000002, /* not sent because we are not logged in to the remote node */
- MPI_IOCLOGINFO_FC_TARGET_DOAR_KILLED_BY_LIP = 0x21000003, /* Data Out, Auto Response, not sent due to a LIP */
- MPI_IOCLOGINFO_FC_TARGET_DIAR_KILLED_BY_LIP = 0x21000004, /* Data In, Auto Response, not sent due to a LIP */
- MPI_IOCLOGINFO_FC_TARGET_DIAR_MISSING_DATA = 0x21000005, /* Data In, Auto Response, missing data frames */
- MPI_IOCLOGINFO_FC_TARGET_DONR_KILLED_BY_LIP = 0x21000006, /* Data Out, No Response, not sent due to a LIP */
- MPI_IOCLOGINFO_FC_TARGET_WRSP_KILLED_BY_LIP = 0x21000007, /* Auto-response after a write not sent due to a LIP */
- MPI_IOCLOGINFO_FC_TARGET_DINR_KILLED_BY_LIP = 0x21000008, /* Data In, No Response, not completed due to a LIP */
- MPI_IOCLOGINFO_FC_TARGET_DINR_MISSING_DATA = 0x21000009, /* Data In, No Response, missing data frames */
- MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP = 0x2100000a, /* Manual Response not sent due to a LIP */
- MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3 = 0x2100000b, /* not sent because remote node does not support Class 3 */
- MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID = 0x2100000c, /* not sent because login to remote node not validated */
- MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND = 0x2100000e, /* cleared from the outbound queue after a logout */
- MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN = 0x2100000f, /* cleared waiting for data after a logout */
-
- MPI_IOCLOGINFO_FC_LAN_BASE = 0x22000000,
- MPI_IOCLOGINFO_FC_LAN_TRANS_SGL_MISSING = 0x22000001, /* Transaction Context Sgl Missing */
- MPI_IOCLOGINFO_FC_LAN_TRANS_WRONG_PLACE = 0x22000002, /* Transaction Context found before an EOB */
- MPI_IOCLOGINFO_FC_LAN_TRANS_RES_BITS_SET = 0x22000003, /* Transaction Context value has reserved bits set */
- MPI_IOCLOGINFO_FC_LAN_WRONG_SGL_FLAG = 0x22000004, /* Invalid SGL Flags */
-
- MPI_IOCLOGINFO_FC_MSG_BASE = 0x23000000,
-
- MPI_IOCLOGINFO_FC_LINK_BASE = 0x24000000,
- MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT = 0x24000001, /* Loop initialization timed out */
- MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED = 0x24000002, /* Another system controller already initialized the loop */
- MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED = 0x24000003, /* Not synchronized to signal or still negotiating (possible cable problem) */
- MPI_IOCLOGINFO_FC_LINK_CRC_ERROR = 0x24000004, /* CRC check detected error on received frame */
-
- MPI_IOCLOGINFO_FC_CTX_BASE = 0x25000000,
-
- MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid */
- MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET = 0x26ffffff,
-
- MPI_IOCLOGINFO_FC_STATE_CHANGE = 0x27000000 /* The lower 24 bits give additional information concerning state change */
-
-} MpiIocLogInfoFc_t;
diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h
index 02cdc840a06b..81ad77622dac 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.10
+ * mpi.h Version: 01.05.11
*
* Version History
* ---------------
@@ -76,6 +76,7 @@
* Added EEDP IOCStatus codes.
* 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT.
* 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target.
+ * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT.
* --------------------------------------------------------------------------
*/
@@ -106,7 +107,7 @@
/* Note: The major versions of 0xe0 through 0xff are reserved */
/* versioning for this MPI header set */
-#define MPI_HEADER_VERSION_UNIT (0x0C)
+#define MPI_HEADER_VERSION_UNIT (0x0D)
#define MPI_HEADER_VERSION_DEV (0x00)
#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI_HEADER_VERSION_UNIT_SHIFT (8)
diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h
index b1becec27e1b..47e13e360c10 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.11
+ * mpi_cnfg.h Version: 01.05.12
*
* Version History
* ---------------
@@ -266,6 +266,16 @@
* Added postpone SATA Init bit to SAS IO Unit Page 1
* ControlFlags.
* Changed LogEntry format for Log Page 0.
+ * 03-27-06 01.05.12 Added two new Flags defines for Manufacturing Page 4.
+ * Added Manufacturing Page 7.
+ * Added MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING.
+ * Added IOC Page 6.
+ * Added PrevBootDeviceForm field to CONFIG_PAGE_BIOS_2.
+ * Added MaxLBAHigh field to RAID Volume Page 0.
+ * Added Nvdata version fields to SAS IO Unit Page 0.
+ * Added AdditionalControlFlags, MaxTargetPortConnectTime,
+ * ReportDeviceMissingDelay, and IODeviceMissingDelay
+ * fields to SAS IO Unit Page 1.
* --------------------------------------------------------------------------
*/
@@ -631,9 +641,11 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
} CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,
ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t;
-#define MPI_MANUFACTURING4_PAGEVERSION (0x03)
+#define MPI_MANUFACTURING4_PAGEVERSION (0x04)
/* defines for the Flags field */
+#define MPI_MANPAGE4_FORCE_BAD_BLOCK_TABLE (0x80)
+#define MPI_MANPAGE4_FORCE_OFFLINE_FAILOVER (0x40)
#define MPI_MANPAGE4_IME_DISABLE (0x20)
#define MPI_MANPAGE4_IM_DISABLE (0x10)
#define MPI_MANPAGE4_IS_DISABLE (0x08)
@@ -668,6 +680,66 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_6
#define MPI_MANUFACTURING6_PAGEVERSION (0x00)
+typedef struct _MPI_MANPAGE7_CONNECTOR_INFO
+{
+ U32 Pinout; /* 00h */
+ U8 Connector[16]; /* 04h */
+ U8 Location; /* 14h */
+ U8 Reserved1; /* 15h */
+ U16 Slot; /* 16h */
+ U32 Reserved2; /* 18h */
+} MPI_MANPAGE7_CONNECTOR_INFO, MPI_POINTER PTR_MPI_MANPAGE7_CONNECTOR_INFO,
+ MpiManPage7ConnectorInfo_t, MPI_POINTER pMpiManPage7ConnectorInfo_t;
+
+/* defines for the Pinout field */
+#define MPI_MANPAGE7_PINOUT_SFF_8484_L4 (0x00080000)
+#define MPI_MANPAGE7_PINOUT_SFF_8484_L3 (0x00040000)
+#define MPI_MANPAGE7_PINOUT_SFF_8484_L2 (0x00020000)
+#define MPI_MANPAGE7_PINOUT_SFF_8484_L1 (0x00010000)
+#define MPI_MANPAGE7_PINOUT_SFF_8470_L4 (0x00000800)
+#define MPI_MANPAGE7_PINOUT_SFF_8470_L3 (0x00000400)
+#define MPI_MANPAGE7_PINOUT_SFF_8470_L2 (0x00000200)
+#define MPI_MANPAGE7_PINOUT_SFF_8470_L1 (0x00000100)
+#define MPI_MANPAGE7_PINOUT_SFF_8482 (0x00000002)
+#define MPI_MANPAGE7_PINOUT_CONNECTION_UNKNOWN (0x00000001)
+
+/* defines for the Location field */
+#define MPI_MANPAGE7_LOCATION_UNKNOWN (0x01)
+#define MPI_MANPAGE7_LOCATION_INTERNAL (0x02)
+#define MPI_MANPAGE7_LOCATION_EXTERNAL (0x04)
+#define MPI_MANPAGE7_LOCATION_SWITCHABLE (0x08)
+#define MPI_MANPAGE7_LOCATION_AUTO (0x10)
+#define MPI_MANPAGE7_LOCATION_NOT_PRESENT (0x20)
+#define MPI_MANPAGE7_LOCATION_NOT_CONNECTED (0x80)
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check NumPhys at runtime.
+ */
+#ifndef MPI_MANPAGE7_CONNECTOR_INFO_MAX
+#define MPI_MANPAGE7_CONNECTOR_INFO_MAX (1)
+#endif
+
+typedef struct _CONFIG_PAGE_MANUFACTURING_7
+{
+ CONFIG_PAGE_HEADER Header; /* 00h */
+ U32 Reserved1; /* 04h */
+ U32 Reserved2; /* 08h */
+ U32 Flags; /* 0Ch */
+ U8 EnclosureName[16]; /* 10h */
+ U8 NumPhys; /* 20h */
+ U8 Reserved3; /* 21h */
+ U16 Reserved4; /* 22h */
+ MPI_MANPAGE7_CONNECTOR_INFO ConnectorInfo[MPI_MANPAGE7_CONNECTOR_INFO_MAX]; /* 24h */
+} CONFIG_PAGE_MANUFACTURING_7, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_7,
+ ManufacturingPage7_t, MPI_POINTER pManufacturingPage7_t;
+
+#define MPI_MANUFACTURING7_PAGEVERSION (0x00)
+
+/* defines for the Flags field */
+#define MPI_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001)
+
+
/****************************************************************************
* IO Unit Config Pages
****************************************************************************/
@@ -867,7 +939,7 @@ 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 (0x03)
+#define MPI_IOCPAGE2_PAGEVERSION (0x04)
/* IOC Page 2 Capabilities flags */
@@ -878,6 +950,7 @@ typedef struct _CONFIG_PAGE_IOC_2
#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_RAID_64_BIT_ADDRESSING (0x10000000)
#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)
@@ -975,6 +1048,44 @@ typedef struct _CONFIG_PAGE_IOC_5
#define MPI_IOCPAGE5_PAGEVERSION (0x00)
+typedef struct _CONFIG_PAGE_IOC_6
+{
+ CONFIG_PAGE_HEADER Header; /* 00h */
+ U32 CapabilitiesFlags; /* 04h */
+ U8 MaxDrivesIS; /* 08h */
+ U8 MaxDrivesIM; /* 09h */
+ U8 MaxDrivesIME; /* 0Ah */
+ U8 Reserved1; /* 0Bh */
+ U8 MinDrivesIS; /* 0Ch */
+ U8 MinDrivesIM; /* 0Dh */
+ U8 MinDrivesIME; /* 0Eh */
+ U8 Reserved2; /* 0Fh */
+ U8 MaxGlobalHotSpares; /* 10h */
+ U8 Reserved3; /* 11h */
+ U16 Reserved4; /* 12h */
+ U32 Reserved5; /* 14h */
+ U32 SupportedStripeSizeMapIS; /* 18h */
+ U32 SupportedStripeSizeMapIME; /* 1Ch */
+ U32 Reserved6; /* 20h */
+ U8 MetadataSize; /* 24h */
+ U8 Reserved7; /* 25h */
+ U16 Reserved8; /* 26h */
+ U16 MaxBadBlockTableEntries; /* 28h */
+ U16 Reserved9; /* 2Ah */
+ U16 IRNvsramUsage; /* 2Ch */
+ U16 Reserved10; /* 2Eh */
+ U32 IRNvsramVersion; /* 30h */
+ U32 Reserved11; /* 34h */
+ U32 Reserved12; /* 38h */
+} CONFIG_PAGE_IOC_6, MPI_POINTER PTR_CONFIG_PAGE_IOC_6,
+ IOCPage6_t, MPI_POINTER pIOCPage6_t;
+
+#define MPI_IOCPAGE6_PAGEVERSION (0x00)
+
+/* IOC Page 6 Capabilities Flags */
+
+#define MPI_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE (0x00000001)
+
/****************************************************************************
* BIOS Config Pages
@@ -1218,13 +1329,13 @@ typedef struct _CONFIG_PAGE_BIOS_2
U32 Reserved5; /* 14h */
U32 Reserved6; /* 18h */
U8 BootDeviceForm; /* 1Ch */
- U8 Reserved7; /* 1Dh */
+ U8 PrevBootDeviceForm; /* 1Ch */
U16 Reserved8; /* 1Eh */
MPI_BIOSPAGE2_BOOT_DEVICE BootDevice; /* 20h */
} CONFIG_PAGE_BIOS_2, MPI_POINTER PTR_CONFIG_PAGE_BIOS_2,
BIOSPage2_t, MPI_POINTER pBIOSPage2_t;
-#define MPI_BIOSPAGE2_PAGEVERSION (0x01)
+#define MPI_BIOSPAGE2_PAGEVERSION (0x02)
#define MPI_BIOSPAGE2_FORM_MASK (0x0F)
#define MPI_BIOSPAGE2_FORM_ADAPTER_ORDER (0x00)
@@ -2080,7 +2191,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0
RAID_VOL0_STATUS VolumeStatus; /* 08h */
RAID_VOL0_SETTINGS VolumeSettings; /* 0Ch */
U32 MaxLBA; /* 10h */
- U32 Reserved1; /* 14h */
+ U32 MaxLBAHigh; /* 14h */
U32 StripeSize; /* 18h */
U32 Reserved2; /* 1Ch */
U32 Reserved3; /* 20h */
@@ -2092,7 +2203,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 (0x05)
+#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x06)
/* values for RAID Volume Page 0 InactiveStatus field */
#define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00)
@@ -2324,7 +2435,8 @@ typedef struct _MPI_SAS_IO_UNIT0_PHY_DATA
typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
{
CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
- U32 Reserved1; /* 08h */
+ U16 NvdataVersionDefault; /* 08h */
+ U16 NvdataVersionPersistent; /* 0Ah */
U8 NumPhys; /* 0Ch */
U8 Reserved2; /* 0Dh */
U16 Reserved3; /* 0Eh */
@@ -2332,7 +2444,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 (0x03)
+#define MPI_SASIOUNITPAGE0_PAGEVERSION (0x04)
/* values for SAS IO Unit Page 0 PortFlags */
#define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS (0x08)
@@ -2373,12 +2485,13 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA
{
- U8 Port; /* 00h */
- U8 PortFlags; /* 01h */
- U8 PhyFlags; /* 02h */
- U8 MaxMinLinkRate; /* 03h */
- U32 ControllerPhyDeviceInfo;/* 04h */
- U32 Reserved1; /* 08h */
+ U8 Port; /* 00h */
+ U8 PortFlags; /* 01h */
+ U8 PhyFlags; /* 02h */
+ U8 MaxMinLinkRate; /* 03h */
+ U32 ControllerPhyDeviceInfo; /* 04h */
+ U16 MaxTargetPortConnectTime; /* 08h */
+ U16 Reserved1; /* 0Ah */
} MPI_SAS_IO_UNIT1_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT1_PHY_DATA,
SasIOUnit1PhyData, MPI_POINTER pSasIOUnit1PhyData;
@@ -2395,15 +2508,17 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U16 ControlFlags; /* 08h */
U16 MaxNumSATATargets; /* 0Ah */
- U32 Reserved1; /* 0Ch */
+ U16 AdditionalControlFlags; /* 0Ch */
+ U16 Reserved1; /* 0Eh */
U8 NumPhys; /* 10h */
U8 SATAMaxQDepth; /* 11h */
- U16 Reserved2; /* 12h */
+ U8 ReportDeviceMissingDelay; /* 12h */
+ U8 IODeviceMissingDelay; /* 13h */
MPI_SAS_IO_UNIT1_PHY_DATA PhyData[MPI_SAS_IOUNIT1_PHY_MAX]; /* 14h */
} CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1,
SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t;
-#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x05)
+#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x06)
/* values for SAS IO Unit Page 1 ControlFlags */
#define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000)
@@ -2428,6 +2543,13 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
#define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002)
#define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001)
+/* values for SAS IO Unit Page 1 AdditionalControlFlags */
+#define MPI_SAS_IOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE (0x0001)
+
+/* defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */
+#define MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK (0x7F)
+#define MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16 (0x80)
+
/* values for SAS IO Unit Page 1 PortFlags */
#define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM (0x00)
#define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM (0x04)
diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt
index 4a5f8dd1d766..582cfe7c2aa1 100644
--- a/drivers/message/fusion/lsi/mpi_history.txt
+++ b/drivers/message/fusion/lsi/mpi_history.txt
@@ -6,25 +6,25 @@
Copyright (c) 2000-2005 LSI Logic Corporation.
---------------------------------------
- Header Set Release Version: 01.05.12
- Header Set Release Date: 08-30-05
+ Header Set Release Version: 01.05.13
+ Header Set Release Date: 03-27-06
---------------------------------------
Filename Current version Prior version
---------- --------------- -------------
- mpi.h 01.05.10 01.05.09
- mpi_ioc.h 01.05.10 01.05.09
- mpi_cnfg.h 01.05.11 01.05.10
- mpi_init.h 01.05.06 01.05.06
- mpi_targ.h 01.05.05 01.05.05
+ mpi.h 01.05.11 01.05.10
+ mpi_ioc.h 01.05.11 01.05.10
+ mpi_cnfg.h 01.05.12 01.05.11
+ mpi_init.h 01.05.07 01.05.06
+ mpi_targ.h 01.05.06 01.05.05
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.02 01.05.01
- mpi_type.h 01.05.02 01.05.01
- mpi_history.txt 01.05.12 01.05.11
+ mpi_sas.h 01.05.03 01.05.02
+ mpi_type.h 01.05.02 01.05.02
+ mpi_history.txt 01.05.13 01.05.12
* Date Version Description
@@ -93,6 +93,7 @@ mpi.h
* Added EEDP IOCStatus codes.
* 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT.
* 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target.
+ * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT.
* --------------------------------------------------------------------------
mpi_ioc.h
@@ -170,6 +171,17 @@ mpi_ioc.h
* Added new ReasonCode value for SAS Device Status Change
* event.
* Added new family code for FC949E.
+ * 03-27-06 01.05.11 Added MPI_IOCFACTS_CAPABILITY_TLR.
+ * Added additional Reason Codes and more event data fields
+ * to EVENT_DATA_SAS_DEVICE_STATUS_CHANGE.
+ * Added EVENT_DATA_SAS_BROADCAST_PRIMITIVE structure and
+ * new event.
+ * Added MPI_EVENT_SAS_SMP_ERROR and event data structure.
+ * Added MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE and event
+ * data structure.
+ * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event
+ * data structure.
+ * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION.
* --------------------------------------------------------------------------
mpi_cnfg.h
@@ -425,6 +437,16 @@ mpi_cnfg.h
* Added postpone SATA Init bit to SAS IO Unit Page 1
* ControlFlags.
* Changed LogEntry format for Log Page 0.
+ * 03-27-06 01.05.12 Added two new Flags defines for Manufacturing Page 4.
+ * Added Manufacturing Page 7.
+ * Added MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING.
+ * Added IOC Page 6.
+ * Added PrevBootDeviceForm field to CONFIG_PAGE_BIOS_2.
+ * Added MaxLBAHigh field to RAID Volume Page 0.
+ * Added Nvdata version fields to SAS IO Unit Page 0.
+ * Added AdditionalControlFlags, MaxTargetPortConnectTime,
+ * ReportDeviceMissingDelay, and IODeviceMissingDelay
+ * fields to SAS IO Unit Page 1.
* --------------------------------------------------------------------------
mpi_init.h
@@ -467,6 +489,7 @@ mpi_init.h
* Added four new defines for SEP SlotStatus.
* 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them
* unique in the first 32 characters.
+ * 03-27-06 01.05.07 Added Task Management type of Clear ACA.
* --------------------------------------------------------------------------
mpi_targ.h
@@ -511,6 +534,7 @@ mpi_targ.h
* 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.
+ * 03-27-06 01.05.06 Added a comment.
* --------------------------------------------------------------------------
mpi_fc.h
@@ -610,6 +634,10 @@ mpi_sas.h
* 08-30-05 01.05.02 Added DeviceInfo bit for SEP.
* Added PrimFlags and Primitive field to SAS IO Unit
* Control request, and added a new operation code.
+ * 03-27-06 01.05.03 Added Force Full Discovery, Transmit Port Select Signal,
+ * and Remove Device operations to SAS IO Unit Control.
+ * Added DevHandle field to SAS IO Unit Control request and
+ * reply.
* --------------------------------------------------------------------------
mpi_type.h
@@ -625,20 +653,20 @@ mpi_type.h
mpi_history.txt Parts list history
-Filename 01.05.12 01.05.11 01.05.10 01.05.09
----------- -------- -------- -------- --------
-mpi.h 01.05.10 01.05.09 01.05.08 01.05.07
-mpi_ioc.h 01.05.10 01.05.09 01.05.09 01.05.08
-mpi_cnfg.h 01.05.11 01.05.10 01.05.09 01.05.08
-mpi_init.h 01.05.06 01.05.06 01.05.05 01.05.04
-mpi_targ.h 01.05.05 01.05.05 01.05.05 01.05.04
-mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01
-mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01
-mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02
-mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03
-mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01
-mpi_sas.h 01.05.02 01.05.01 01.05.01 01.05.01
-mpi_type.h 01.05.02 01.05.01 01.05.01 01.05.01
+Filename 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09
+---------- -------- -------- -------- -------- --------
+mpi.h 01.05.11 01.05.10 01.05.09 01.05.08 01.05.07
+mpi_ioc.h 01.05.11 01.05.10 01.05.09 01.05.09 01.05.08
+mpi_cnfg.h 01.05.12 01.05.11 01.05.10 01.05.09 01.05.08
+mpi_init.h 01.05.07 01.05.06 01.05.06 01.05.05 01.05.04
+mpi_targ.h 01.05.06 01.05.05 01.05.05 01.05.05 01.05.04
+mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
+mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
+mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02
+mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03
+mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
+mpi_sas.h 01.05.03 01.05.02 01.05.01 01.05.01 01.05.01
+mpi_type.h 01.05.02 01.05.02 01.05.01 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 68941f459ca3..c1c678989a23 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.06
+ * mpi_init.h Version: 01.05.07
*
* Version History
* ---------------
@@ -52,6 +52,7 @@
* Added four new defines for SEP SlotStatus.
* 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them
* unique in the first 32 characters.
+ * 03-27-06 01.05.07 Added Task Management type of Clear ACA.
* --------------------------------------------------------------------------
*/
@@ -427,6 +428,7 @@ typedef struct _MSG_SCSI_TASK_MGMT
#define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05)
#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06)
#define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07)
+#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_ACA (0x08)
/* MsgFlags bits */
#define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00)
diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h
index 2c5f43fa7c73..18ba407fd399 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.10
+ * mpi_ioc.h Version: 01.05.11
*
* Version History
* ---------------
@@ -87,6 +87,17 @@
* Added new ReasonCode value for SAS Device Status Change
* event.
* Added new family code for FC949E.
+ * 03-27-06 01.05.11 Added MPI_IOCFACTS_CAPABILITY_TLR.
+ * Added additional Reason Codes and more event data fields
+ * to EVENT_DATA_SAS_DEVICE_STATUS_CHANGE.
+ * Added EVENT_DATA_SAS_BROADCAST_PRIMITIVE structure and
+ * new event.
+ * Added MPI_EVENT_SAS_SMP_ERROR and event data structure.
+ * Added MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE and event
+ * data structure.
+ * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event
+ * data structure.
+ * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION.
* --------------------------------------------------------------------------
*/
@@ -272,6 +283,7 @@ typedef struct _MSG_IOC_FACTS_REPLY
#define MPI_IOCFACTS_CAPABILITY_MULTICAST (0x00000100)
#define MPI_IOCFACTS_CAPABILITY_SCSIIO32 (0x00000200)
#define MPI_IOCFACTS_CAPABILITY_NO_SCSIIO16 (0x00000400)
+#define MPI_IOCFACTS_CAPABILITY_TLR (0x00000800)
/*****************************************************************************
@@ -448,30 +460,34 @@ typedef struct _MSG_EVENT_ACK_REPLY
/* Event */
-#define MPI_EVENT_NONE (0x00000000)
-#define MPI_EVENT_LOG_DATA (0x00000001)
-#define MPI_EVENT_STATE_CHANGE (0x00000002)
-#define MPI_EVENT_UNIT_ATTENTION (0x00000003)
-#define MPI_EVENT_IOC_BUS_RESET (0x00000004)
-#define MPI_EVENT_EXT_BUS_RESET (0x00000005)
-#define MPI_EVENT_RESCAN (0x00000006)
-#define MPI_EVENT_LINK_STATUS_CHANGE (0x00000007)
-#define MPI_EVENT_LOOP_STATE_CHANGE (0x00000008)
-#define MPI_EVENT_LOGOUT (0x00000009)
-#define MPI_EVENT_EVENT_CHANGE (0x0000000A)
-#define MPI_EVENT_INTEGRATED_RAID (0x0000000B)
-#define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C)
-#define MPI_EVENT_ON_BUS_TIMER_EXPIRED (0x0000000D)
-#define MPI_EVENT_QUEUE_FULL (0x0000000E)
-#define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE (0x0000000F)
-#define MPI_EVENT_SAS_SES (0x00000010)
-#define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011)
-#define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012)
-#define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013)
-#define MPI_EVENT_IR_RESYNC_UPDATE (0x00000014)
-#define MPI_EVENT_IR2 (0x00000015)
-#define MPI_EVENT_SAS_DISCOVERY (0x00000016)
-#define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021)
+#define MPI_EVENT_NONE (0x00000000)
+#define MPI_EVENT_LOG_DATA (0x00000001)
+#define MPI_EVENT_STATE_CHANGE (0x00000002)
+#define MPI_EVENT_UNIT_ATTENTION (0x00000003)
+#define MPI_EVENT_IOC_BUS_RESET (0x00000004)
+#define MPI_EVENT_EXT_BUS_RESET (0x00000005)
+#define MPI_EVENT_RESCAN (0x00000006)
+#define MPI_EVENT_LINK_STATUS_CHANGE (0x00000007)
+#define MPI_EVENT_LOOP_STATE_CHANGE (0x00000008)
+#define MPI_EVENT_LOGOUT (0x00000009)
+#define MPI_EVENT_EVENT_CHANGE (0x0000000A)
+#define MPI_EVENT_INTEGRATED_RAID (0x0000000B)
+#define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C)
+#define MPI_EVENT_ON_BUS_TIMER_EXPIRED (0x0000000D)
+#define MPI_EVENT_QUEUE_FULL (0x0000000E)
+#define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE (0x0000000F)
+#define MPI_EVENT_SAS_SES (0x00000010)
+#define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011)
+#define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012)
+#define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013)
+#define MPI_EVENT_IR_RESYNC_UPDATE (0x00000014)
+#define MPI_EVENT_IR2 (0x00000015)
+#define MPI_EVENT_SAS_DISCOVERY (0x00000016)
+#define MPI_EVENT_SAS_BROADCAST_PRIMITIVE (0x00000017)
+#define MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x00000018)
+#define MPI_EVENT_SAS_INIT_TABLE_OVERFLOW (0x00000019)
+#define MPI_EVENT_SAS_SMP_ERROR (0x0000001A)
+#define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021)
/* AckRequired field values */
@@ -558,18 +574,25 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
U8 PhyNum; /* 0Eh */
U8 Reserved1; /* 0Fh */
U64 SASAddress; /* 10h */
+ U8 LUN[8]; /* 18h */
+ U16 TaskTag; /* 20h */
+ U16 Reserved2; /* 22h */
} EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
MPI_POINTER PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
MpiEventDataSasDeviceStatusChange_t,
MPI_POINTER pMpiEventDataSasDeviceStatusChange_t;
/* MPI SAS Device Status Change Event data ReasonCode values */
-#define MPI_EVENT_SAS_DEV_STAT_RC_ADDED (0x03)
-#define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING (0x04)
-#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05)
-#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06)
-#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07)
-#define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08)
+#define MPI_EVENT_SAS_DEV_STAT_RC_ADDED (0x03)
+#define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING (0x04)
+#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05)
+#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06)
+#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07)
+#define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08)
+#define MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL (0x09)
+#define MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A)
+#define MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B)
+#define MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C)
/* SCSI Event data for Queue Full event */
@@ -742,6 +765,27 @@ typedef struct _EVENT_DATA_SAS_SES
} EVENT_DATA_SAS_SES, MPI_POINTER PTR_EVENT_DATA_SAS_SES,
MpiEventDataSasSes_t, MPI_POINTER pMpiEventDataSasSes_t;
+/* SAS Broadcast Primitive Event data */
+
+typedef struct _EVENT_DATA_SAS_BROADCAST_PRIMITIVE
+{
+ U8 PhyNum; /* 00h */
+ U8 Port; /* 01h */
+ U8 PortWidth; /* 02h */
+ U8 Primitive; /* 04h */
+} EVENT_DATA_SAS_BROADCAST_PRIMITIVE,
+ MPI_POINTER PTR_EVENT_DATA_SAS_BROADCAST_PRIMITIVE,
+ MpiEventDataSasBroadcastPrimitive_t,
+ MPI_POINTER pMpiEventDataSasBroadcastPrimitive_t;
+
+#define MPI_EVENT_PRIMITIVE_CHANGE (0x01)
+#define MPI_EVENT_PRIMITIVE_EXPANDER (0x03)
+#define MPI_EVENT_PRIMITIVE_RESERVED2 (0x04)
+#define MPI_EVENT_PRIMITIVE_RESERVED3 (0x05)
+#define MPI_EVENT_PRIMITIVE_RESERVED4 (0x06)
+#define MPI_EVENT_PRIMITIVE_CHANGE0_RESERVED (0x07)
+#define MPI_EVENT_PRIMITIVE_CHANGE1_RESERVED (0x08)
+
/* SAS Phy Link Status Event data */
typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS
@@ -804,6 +848,53 @@ typedef struct _EVENT_DATA_DISCOVERY_ERROR
#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS (0x00000800)
#define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS (0x00001000)
+/* SAS SMP Error Event data */
+
+typedef struct _EVENT_DATA_SAS_SMP_ERROR
+{
+ U8 Status; /* 00h */
+ U8 Port; /* 01h */
+ U8 SMPFunctionResult; /* 02h */
+ U8 Reserved1; /* 03h */
+ U64 SASAddress; /* 04h */
+} EVENT_DATA_SAS_SMP_ERROR, MPI_POINTER PTR_EVENT_DATA_SAS_SMP_ERROR,
+ MpiEventDataSasSmpError_t, MPI_POINTER pMpiEventDataSasSmpError_t;
+
+/* defines for the Status field of the SAS SMP Error event */
+#define MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID (0x00)
+#define MPI_EVENT_SAS_SMP_CRC_ERROR (0x01)
+#define MPI_EVENT_SAS_SMP_TIMEOUT (0x02)
+#define MPI_EVENT_SAS_SMP_NO_DESTINATION (0x03)
+#define MPI_EVENT_SAS_SMP_BAD_DESTINATION (0x04)
+
+/* SAS Initiator Device Status Change Event data */
+
+typedef struct _EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE
+{
+ U8 ReasonCode; /* 00h */
+ U8 Port; /* 01h */
+ U16 DevHandle; /* 02h */
+ U64 SASAddress; /* 04h */
+} EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE,
+ MPI_POINTER PTR_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE,
+ MpiEventDataSasInitDevStatusChange_t,
+ MPI_POINTER pMpiEventDataSasInitDevStatusChange_t;
+
+/* defines for the ReasonCode field of the SAS Initiator Device Status Change event */
+#define MPI_EVENT_SAS_INIT_RC_ADDED (0x01)
+
+/* SAS Initiator Device Table Overflow Event data */
+
+typedef struct _EVENT_DATA_SAS_INIT_TABLE_OVERFLOW
+{
+ U8 MaxInit; /* 00h */
+ U8 CurrentInit; /* 01h */
+ U16 Reserved1; /* 02h */
+} EVENT_DATA_SAS_INIT_TABLE_OVERFLOW,
+ MPI_POINTER PTR_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW,
+ MpiEventDataSasInitTableOverflow_t,
+ MPI_POINTER pMpiEventDataSasInitTableOverflow_t;
+
/*****************************************************************************
*
@@ -1013,5 +1104,6 @@ typedef struct _MPI_EXT_IMAGE_HEADER
#define MPI_EXT_IMAGE_TYPE_FW (0x01)
#define MPI_EXT_IMAGE_TYPE_NVDATA (0x03)
#define MPI_EXT_IMAGE_TYPE_BOOTLOADER (0x04)
+#define MPI_EXT_IMAGE_TYPE_INITIALIZATION (0x05)
#endif
diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h
index a9c14ad132ce..871ebc08b706 100644
--- a/drivers/message/fusion/lsi/mpi_log_sas.h
+++ b/drivers/message/fusion/lsi/mpi_log_sas.h
@@ -13,6 +13,8 @@
#ifndef IOPI_IOCLOGINFO_H_INCLUDED
#define IOPI_IOCLOGINFO_H_INCLUDED
+#define SAS_LOGINFO_NEXUS_LOSS 0x31170000
+#define SAS_LOGINFO_MASK 0xFFFF0000
/****************************************************************************/
/* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */
@@ -51,6 +53,9 @@
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */
+
+#define IOP_LOGINFO_CODE_DIAG_MSG_ERROR (0x00040000) /* Error handling diag msg - or'd with diag status */
+
#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000)
#define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */
@@ -103,6 +108,7 @@
#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000)
#define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000)
#define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000)
+#define PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY (0x00170000)
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100)
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101)
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */
@@ -165,11 +171,81 @@
/****************************************************************************/
/* IR LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IR */
/****************************************************************************/
-#define IR_LOGINFO_CODE_UNUSED1 (0x00010000)
-#define IR_LOGINFO_CODE_UNUSED2 (0x00020000)
+#define IR_LOGINFO_RAID_ACTION_ERROR (0x00010000)
+#define IR_LOGINFO_CODE_UNUSED2 (0x00020000)
+
+/* Amount of information passed down for Create Volume is too large */
+#define IR_LOGINFO_VOLUME_CREATE_INVALID_LENGTH (0x00010001)
+/* Creation of duplicate volume attempted (Bus/Target ID checked) */
+#define IR_LOGINFO_VOLUME_CREATE_DUPLICATE (0x00010002)
+/* Creation failed due to maximum number of supported volumes exceeded */
+#define IR_LOGINFO_VOLUME_CREATE_NO_SLOTS (0x00010003)
+/* Creation failed due to DMA error in trying to read from host */
+#define IR_LOGINFO_VOLUME_CREATE_DMA_ERROR (0x00010004)
+/* Creation failed due to invalid volume type passed down */
+#define IR_LOGINFO_VOLUME_CREATE_INVALID_VOLUME_TYPE (0x00010005)
+/* Creation failed due to error reading MFG Page 4 */
+#define IR_LOGINFO_VOLUME_MFG_PAGE4_ERROR (0x00010006)
+/* Creation failed when trying to create internal structures */
+#define IR_LOGINFO_VOLUME_INTERNAL_CONFIG_STRUCTURE_ERROR (0x00010007)
+
+/* Activation failed due to trying to activate an already active volume */
+#define IR_LOGINFO_VOLUME_ACTIVATING_AN_ACTIVE_VOLUME (0x00010010)
+/* Activation failed due to trying to active unsupported volume type */
+#define IR_LOGINFO_VOLUME_ACTIVATING_INVALID_VOLUME_TYPE (0x00010011)
+/* Activation failed due to trying to active too many volumes */
+#define IR_LOGINFO_VOLUME_ACTIVATING_TOO_MANY_VOLUMES (0x00010012)
+/* Activation failed due to Volume ID in use already */
+#define IR_LOGINFO_VOLUME_ACTIVATING_VOLUME_ID_IN_USE (0x00010013)
+/* Activation failed call to activateVolume returned failure */
+#define IR_LOGINFO_VOLUME_ACTIVATE_VOLUME_FAILED (0x00010014)
+/* Activation failed trying to import the volume */
+#define IR_LOGINFO_VOLUME_ACTIVATING_IMPORT_VOLUME_FAILED (0x00010015)
+
+/* Phys Disk failed, too many phys disks */
+#define IR_LOGINFO_PHYSDISK_CREATE_TOO_MANY_DISKS (0x00010020)
+/* Amount of information passed down for Create Pnysdisk is too large */
+#define IR_LOGINFO_PHYSDISK_CREATE_INVALID_LENGTH (0x00010021)
+/* Creation failed due to DMA error in trying to read from host */
+#define IR_LOGINFO_PHYSDISK_CREATE_DMA_ERROR (0x00010022)
+/* Creation failed due to invalid Bus TargetID passed down */
+#define IR_LOGINFO_PHYSDISK_CREATE_BUS_TID_INVALID (0x00010023)
+/* Creation failed due to error in creating RAID Phys Disk Config Page */
+#define IR_LOGINFO_PHYSDISK_CREATE_CONFIG_PAGE_ERROR (0x00010024)
+
+
+/* Compatibility Error : IR Disabled */
+#define IR_LOGINFO_COMPAT_ERROR_RAID_DISABLED (0x00010030)
+/* Compatibility Error : Inquiry Comand failed */
+#define IR_LOGINFO_COMPAT_ERROR_INQUIRY_FAILED (0x00010031)
+/* Compatibility Error : Device not direct access device */
+#define IR_LOGINFO_COMPAT_ERROR_NOT_DIRECT_ACCESS (0x00010032)
+/* Compatibility Error : Removable device found */
+#define IR_LOGINFO_COMPAT_ERROR_REMOVABLE_FOUND (0x00010033)
+/* Compatibility Error : Device SCSI Version not 2 or higher */
+#define IR_LOGINFO_COMPAT_ERROR_NEED_SCSI_2_OR_HIGHER (0x00010034)
+/* Compatibility Error : SATA device, 48 BIT LBA not supported */
+#define IR_LOGINFO_COMPAT_ERROR_SATA_48BIT_LBA_NOT_SUPPORTED (0x00010035)
+/* Compatibility Error : Device does not have 512 byte block sizes */
+#define IR_LOGINFO_COMPAT_ERROR_DEVICE_NOT_512_BYTE_BLOCK (0x00010036)
+/* Compatibility Error : Volume Type check failed */
+#define IR_LOGINFO_COMPAT_ERROR_VOLUME_TYPE_CHECK_FAILED (0x00010037)
+/* Compatibility Error : Volume Type is unsupported by FW */
+#define IR_LOGINFO_COMPAT_ERROR_UNSUPPORTED_VOLUME_TYPE (0x00010038)
+/* Compatibility Error : Disk drive too small for use in volume */
+#define IR_LOGINFO_COMPAT_ERROR_DISK_TOO_SMALL (0x00010039)
+/* Compatibility Error : Phys disk for Create Volume not found */
+#define IR_LOGINFO_COMPAT_ERROR_PHYS_DISK_NOT_FOUND (0x0001003A)
+/* Compatibility Error : membership count error, too many or too few disks for volume type */
+#define IR_LOGINFO_COMPAT_ERROR_MEMBERSHIP_COUNT (0x0001003B)
+/* Compatibility Error : Disk stripe sizes must be 64KB */
+#define IR_LOGINFO_COMPAT_ERROR_NON_64K_STRIPE_SIZE (0x0001003C)
+/* Compatibility Error : IME size limited to < 2TB */
+#define IR_LOGINFO_COMPAT_ERROR_IME_VOL_NOT_CURRENTLY_SUPPORTED (0x0001003D)
+
/****************************************************************************/
-/* Defines for convienence */
+/* Defines for convenience */
/****************************************************************************/
#define IOC_LOGINFO_PREFIX_IOP ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IOP)
#define IOC_LOGINFO_PREFIX_PL ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_PL)
diff --git a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h
index 70514867bddf..50b8f0a8f456 100644
--- a/drivers/message/fusion/lsi/mpi_sas.h
+++ b/drivers/message/fusion/lsi/mpi_sas.h
@@ -6,7 +6,7 @@
* Title: MPI Serial Attached SCSI structures and definitions
* Creation Date: August 19, 2004
*
- * mpi_sas.h Version: 01.05.02
+ * mpi_sas.h Version: 01.05.03
*
* Version History
* ---------------
@@ -17,6 +17,10 @@
* 08-30-05 01.05.02 Added DeviceInfo bit for SEP.
* Added PrimFlags and Primitive field to SAS IO Unit
* Control request, and added a new operation code.
+ * 03-27-06 01.05.03 Added Force Full Discovery, Transmit Port Select Signal,
+ * and Remove Device operations to SAS IO Unit Control.
+ * Added DevHandle field to SAS IO Unit Control request and
+ * reply.
* --------------------------------------------------------------------------
*/
@@ -209,7 +213,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
U8 Reserved1; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
- U16 Reserved2; /* 04h */
+ U16 DevHandle; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
@@ -231,6 +235,9 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08)
#define MPI_SAS_OP_MAP_CURRENT (0x09)
#define MPI_SAS_OP_SEND_PRIMITIVE (0x0A)
+#define MPI_SAS_OP_FORCE_FULL_DISCOVERY (0x0B)
+#define MPI_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C)
+#define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE (0x0D)
/* values for the PrimFlags field */
#define MPI_SAS_PRIMFLAGS_SINGLE (0x08)
@@ -245,7 +252,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REPLY
U8 Reserved1; /* 01h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
- U16 Reserved2; /* 04h */
+ U16 DevHandle; /* 04h */
U8 Reserved3; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
diff --git a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h
index 3f462859ceea..20b667315773 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.05
+ * mpi_targ.h Version: 01.05.06
*
* Version History
* ---------------
@@ -54,6 +54,7 @@
* 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.
+ * 03-27-06 01.05.06 Added a comment.
* --------------------------------------------------------------------------
*/
@@ -351,7 +352,7 @@ typedef struct _MSG_TARGET_ASSIST_REQUEST
#define TARGET_ASSIST_FLAGS_CONFIRMED (0x08)
#define TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER (0x80)
-
+/* Standard Target Mode Reply message */
typedef struct _MSG_TARGET_ERROR_REPLY
{
U16 Reserved; /* 00h */
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 57543603d6c8..29d0635cce1d 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -368,20 +368,21 @@ static irqreturn_t
mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
{
MPT_ADAPTER *ioc = bus_id;
- u32 pa;
+ u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
+
+ if (pa == 0xFFFFFFFF)
+ return IRQ_NONE;
/*
* Drain the reply FIFO!
*/
- while (1) {
- pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
- if (pa == 0xFFFFFFFF)
- return IRQ_HANDLED;
- else if (pa & MPI_ADDRESS_REPLY_A_BIT)
+ do {
+ if (pa & MPI_ADDRESS_REPLY_A_BIT)
mpt_reply(ioc, pa);
else
mpt_turbo_reply(ioc, pa);
- }
+ pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
+ } while (pa != 0xFFFFFFFF);
return IRQ_HANDLED;
}
@@ -435,8 +436,6 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
*/
if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
freereq = 0;
- devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
- ioc->name, pEvReply));
} else {
devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
ioc->name, pEvReply));
@@ -677,19 +676,19 @@ int
mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
{
MPT_ADAPTER *ioc;
+ const struct pci_device_id *id;
- if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
+ if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
return -EINVAL;
- }
MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
/* call per pci device probe entry point */
list_for_each_entry(ioc, &ioc_list, list) {
- if(dd_cbfunc->probe) {
- dd_cbfunc->probe(ioc->pcidev,
- ioc->pcidev->driver->id_table);
- }
+ id = ioc->pcidev->driver ?
+ ioc->pcidev->driver->id_table : NULL;
+ if (dd_cbfunc->probe)
+ dd_cbfunc->probe(ioc->pcidev, id);
}
return 0;
@@ -1055,9 +1054,8 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
dinitprintk((MYIOC_s_INFO_FMT
"host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
- ioc->name,
- ioc->HostPageBuffer,
- ioc->HostPageBuffer_dma,
+ ioc->name, ioc->HostPageBuffer,
+ (u32)ioc->HostPageBuffer_dma,
host_page_buffer_sz));
ioc->alloc_total += host_page_buffer_sz;
ioc->HostPageBuffer_sz = host_page_buffer_sz;
@@ -1219,31 +1217,25 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
port = psize = 0;
for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
+ if (psize)
+ continue;
/* Get I/O space! */
port = pci_resource_start(pdev, ii);
psize = pci_resource_len(pdev,ii);
} else {
+ if (msize)
+ continue;
/* Get memmap */
mem_phys = pci_resource_start(pdev, ii);
msize = pci_resource_len(pdev,ii);
- break;
}
}
ioc->mem_size = msize;
- if (ii == DEVICE_COUNT_RESOURCE) {
- printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
- kfree(ioc);
- return -EINVAL;
- }
-
- dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
- dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
-
mem = NULL;
/* Get logical ptr for PciMem0 space */
/*mem = ioremap(mem_phys, msize);*/
- mem = ioremap(mem_phys, 0x100);
+ mem = ioremap(mem_phys, msize);
if (mem == NULL) {
printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
kfree(ioc);
@@ -1343,11 +1335,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
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;
@@ -1357,14 +1344,14 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
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;
}
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
+ ioc->prod_name = "LSISAS1078";
+ ioc->bus_type = SAS;
+ }
if (ioc->errata_flag_1064)
pci_disable_io_access(pdev);
@@ -1390,6 +1377,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
printk(KERN_WARNING MYNAM
": WARNING - %s did not initialize properly! (%d)\n",
ioc->name, r);
+
list_del(&ioc->list);
if (ioc->alt_ioc)
ioc->alt_ioc->alt_ioc = NULL;
@@ -1772,9 +1760,9 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
* 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));
+ ioc->alt_ioc->cached_fw = NULL;
}
} else {
printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
@@ -1895,7 +1883,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
/* FIXME? Examine results here? */
}
-out:
+ out:
if ((ret != 0) && irq_allocated) {
free_irq(ioc->pci_irq, ioc);
if (mpt_msi_enable)
@@ -2680,6 +2668,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
ioc->name, count));
+ ioc->aen_event_read_flag=0;
return r;
}
@@ -2747,6 +2736,8 @@ mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
+ ioc->alloc_total += size;
+ ioc->alt_ioc->alloc_total -= size;
} else {
if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
ioc->alloc_total += size;
@@ -3176,6 +3167,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
static int
mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
{
+ MPT_ADAPTER *iocp=NULL;
u32 diag0val;
u32 doorbell;
int hard_reset_done = 0;
@@ -3184,6 +3176,37 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
u32 diag1val = 0;
#endif
+ if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
+ drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
+ "address=%p\n", ioc->name, __FUNCTION__,
+ &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
+ CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
+ if (sleepFlag == CAN_SLEEP)
+ msleep(1);
+ else
+ mdelay(1);
+
+ for (count = 0; count < 60; count ++) {
+ doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
+ doorbell &= MPI_IOC_STATE_MASK;
+
+ drsprintk((MYIOC_s_INFO_FMT
+ "looking for READY STATE: doorbell=%x"
+ " count=%d\n",
+ ioc->name, doorbell, count));
+ if (doorbell == MPI_IOC_STATE_READY) {
+ return 0;
+ }
+
+ /* wait 1 sec */
+ if (sleepFlag == CAN_SLEEP)
+ msleep(1000);
+ else
+ mdelay(1000);
+ }
+ return -1;
+ }
+
/* Clear any existing interrupts */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
@@ -3280,17 +3303,23 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
/* FIXME? Examine results here? */
}
- if (ioc->cached_fw) {
+ if (ioc->cached_fw)
+ iocp = ioc;
+ else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
+ iocp = ioc->alt_ioc;
+ if (iocp) {
/* If the DownloadBoot operation fails, the
* IOC will be left unusable. This is a fatal error
* case. _diag_reset will return < 0
*/
for (count = 0; count < 30; count ++) {
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
break;
}
+ dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n",
+ iocp->name, diag0val, count));
/* wait 1 sec */
if (sleepFlag == CAN_SLEEP) {
msleep (1000);
@@ -3299,7 +3328,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
}
}
if ((count = mpt_downloadboot(ioc,
- (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
+ (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
printk(KERN_WARNING MYNAM
": firmware downloadboot failure (%d)!\n", count);
}
@@ -3886,18 +3915,18 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
if (sleepFlag == CAN_SLEEP) {
while (--cntdn) {
+ msleep (1);
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break;
- msleep (1);
count++;
}
} else {
while (--cntdn) {
+ mdelay (1);
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break;
- mdelay (1);
count++;
}
}
@@ -4862,6 +4891,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
if (!pIoc4)
return;
+ ioc->alloc_total += iocpage4sz;
} else {
ioc4_dma = ioc->spi_data.IocPg4_dma;
iocpage4sz = ioc->spi_data.IocPg4Sz;
@@ -4878,6 +4908,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
} else {
pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
ioc->spi_data.pIocPg4 = NULL;
+ ioc->alloc_total -= iocpage4sz;
}
}
@@ -5009,19 +5040,18 @@ 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 for Event=%x EventContext=%x EventData=%x!\n",
- ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
- le32_to_cpu(evnp->Data[0]));
+ dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
+ ioc->name,__FUNCTION__));
return -1;
}
- memset(pAck, 0, sizeof(*pAck));
- dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
+ devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
pAck->Function = MPI_FUNCTION_EVENT_ACK;
pAck->ChainOffset = 0;
+ pAck->Reserved[0] = pAck->Reserved[1] = 0;
pAck->MsgFlags = 0;
+ pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
pAck->Event = evnp->Event;
pAck->EventContext = evnp->EventContext;
@@ -5683,9 +5713,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
break;
case MPI_EVENT_EVENT_CHANGE:
if (evData0)
- ds = "Events(ON) Change";
+ ds = "Events ON";
else
- ds = "Events(OFF) Change";
+ ds = "Events OFF";
break;
case MPI_EVENT_INTEGRATED_RAID:
{
@@ -5756,8 +5786,27 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
break;
case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
snprintf(evStr, EVENT_DESCR_STR_SZ,
- "SAS Device Status Change: No Persistancy "
- "Added: id=%d", id);
+ "SAS Device Status Change: No Persistancy: id=%d", id);
+ break;
+ case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS Device Status Change: Internal Device Reset : id=%d", id);
+ break;
+ case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS Device Status Change: Internal Task Abort : id=%d", id);
+ break;
+ case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS Device Status Change: Internal Abort Task Set : id=%d", id);
+ break;
+ case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS Device Status Change: Internal Clear Task Set : id=%d", id);
+ break;
+ case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS Device Status Change: Internal Query Task : id=%d", id);
break;
default:
snprintf(evStr, EVENT_DESCR_STR_SZ,
@@ -6013,7 +6062,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
* @ioc: Pointer to MPT_ADAPTER structure
* @log_info: U32 LogInfo reply word from the IOC
*
- * Refer to lsi/fc_log.h.
+ * Refer to lsi/mpi_log_fc.h.
*/
static void
mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
@@ -6110,8 +6159,10 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
"Invalid SAS Address", /* 01h */
NULL, /* 02h */
"Invalid Page", /* 03h */
- NULL, /* 04h */
- "Task Terminated" /* 05h */
+ "Diag Message Error", /* 04h */
+ "Task Terminated", /* 05h */
+ "Enclosure Management", /* 06h */
+ "Target Mode" /* 07h */
};
static char *pl_code_str[] = {
NULL, /* 00h */
@@ -6137,7 +6188,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
"IO Executed", /* 14h */
"Persistant Reservation Out Not Affiliation Owner", /* 15h */
"Open Transmit DMA Abort", /* 16h */
- NULL, /* 17h */
+ "IO Device Missing Delay Retry", /* 17h */
NULL, /* 18h */
NULL, /* 19h */
NULL, /* 1Ah */
@@ -6217,7 +6268,7 @@ static void
mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
{
u32 status = ioc_status & MPI_IOCSTATUS_MASK;
- char *desc = "";
+ char *desc = NULL;
switch (status) {
case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
@@ -6327,7 +6378,7 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
desc = "Others";
break;
}
- if (desc != "")
+ if (desc != NULL)
printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
}
@@ -6365,7 +6416,6 @@ EXPORT_SYMBOL(mpt_alloc_fw_memory);
EXPORT_SYMBOL(mpt_free_fw_memory);
EXPORT_SYMBOL(mptbase_sas_persist_operation);
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* fusion_init - Fusion MPT base driver initialization routine.
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 32ae4d664545..c537d71c18e4 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -75,8 +75,8 @@
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
#endif
-#define MPT_LINUX_VERSION_COMMON "3.03.10"
-#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.10"
+#define MPT_LINUX_VERSION_COMMON "3.04.01"
+#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.01"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
@@ -307,7 +307,8 @@ typedef struct _SYSIF_REGS
u32 HostIndex; /* 50 Host Index register */
u32 Reserved4[15]; /* 54-8F */
u32 Fubar; /* 90 For Fubar usage */
- u32 Reserved5[27]; /* 94-FF */
+ u32 Reserved5[1050];/* 94-10F8 */
+ u32 Reset_1078; /* 10FC Reset 1078 */
} SYSIF_REGS;
/*
@@ -341,6 +342,7 @@ typedef struct _VirtTarget {
u8 negoFlags; /* bit field, see above */
u8 raidVolume; /* set, if RAID Volume */
u8 type; /* byte 0 of Inquiry data */
+ u8 deleted; /* target in process of being removed */
u32 num_luns;
u32 luns[8]; /* Max LUNs is 256 */
} VirtTarget;
@@ -361,6 +363,7 @@ typedef struct _VirtDevice {
#define MPT_TARGET_FLAGS_VALID_56 0x10
#define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20
#define MPT_TARGET_FLAGS_RAID_COMPONENT 0x40
+#define MPT_TARGET_FLAGS_LED_ON 0x80
/*
* /proc/mpt interface
@@ -629,15 +632,14 @@ typedef struct _MPT_ADAPTER
struct mutex sas_discovery_mutex;
u8 sas_discovery_runtime;
u8 sas_discovery_ignore_events;
+ u16 handle;
int sas_index; /* index refrencing */
MPT_SAS_MGMT sas_mgmt;
- int num_ports;
- struct work_struct mptscsih_persistTask;
+ struct work_struct sas_persist_task;
struct work_struct fc_setup_reset_work;
struct list_head fc_rports;
spinlock_t fc_rescan_work_lock;
- int fc_rescan_work_count;
struct work_struct fc_rescan_work;
char fc_rescan_work_q_name[KOBJ_NAME_LEN];
struct workqueue_struct *fc_rescan_work_q;
@@ -892,6 +894,13 @@ typedef struct _mpt_sge {
#define DBG_DUMP_REQUEST_FRAME_HDR(mfp)
#endif
+// debug sas wide ports
+#ifdef MPT_DEBUG_SAS_WIDE
+#define dsaswideprintk(x) printk x
+#else
+#define dsaswideprintk(x)
+#endif
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -971,7 +980,7 @@ typedef struct _MPT_SCSI_HOST {
wait_queue_head_t scandv_waitq;
int scandv_wait_done;
long last_queue_full;
- u8 mpt_pq_filter;
+ u16 tm_iocstatus;
} MPT_SCSI_HOST;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index b4967bb8a7d6..30975ccd9947 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -2332,7 +2332,7 @@ done_free_mem:
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* Prototype Routine for the HP HOST INFO command.
+/* Prototype Routine for the HOST INFO command.
*
* Outputs: None.
* Return: 0 if successful
@@ -2568,7 +2568,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* Prototype Routine for the HP TARGET INFO command.
+/* Prototype Routine for the TARGET INFO command.
*
* Outputs: None.
* Return: 0 if successful
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h
index a2f8a97992e6..043941882c6e 100644
--- a/drivers/message/fusion/mptctl.h
+++ b/drivers/message/fusion/mptctl.h
@@ -354,9 +354,6 @@ struct mpt_ioctl_command32 {
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * HP Specific IOCTL Defines and Structures
- */
#define CPQFCTS_IOC_MAGIC 'Z'
#define HP_IOC_MAGIC 'Z'
@@ -364,8 +361,6 @@ struct mpt_ioctl_command32 {
#define HP_GETHOSTINFO1 _IOR(HP_IOC_MAGIC, 20, hp_host_info_rev0_t)
#define HP_GETTARGETINFO _IOR(HP_IOC_MAGIC, 21, hp_target_info_t)
-/* All HP IOCTLs must include this header
- */
typedef struct _hp_header {
unsigned int iocnum;
unsigned int host;
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 3ff8378ea660..85696f34c310 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -77,10 +77,6 @@ MODULE_DESCRIPTION(my_NAME);
MODULE_LICENSE("GPL");
/* Command line args */
-static int mpt_pq_filter = 0;
-module_param(mpt_pq_filter, int, 0);
-MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
-
#define MPTFC_DEV_LOSS_TMO (60)
static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */
module_param(mptfc_dev_loss_tmo, int, 0);
@@ -132,21 +128,21 @@ static struct scsi_host_template mptfc_driver_template = {
*/
static struct pci_device_id mptfc_pci_table[] = {
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC909,
PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919,
PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929,
PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919X,
PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929X,
PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC939X,
PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949X,
PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949ES,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E,
PCI_ANY_ID, PCI_ANY_ID },
{0} /* Terminating entry */
};
@@ -513,8 +509,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
if (vtarget->num_luns == 0) {
vtarget->ioc_id = hd->ioc->id;
- vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
- MPT_TARGET_FLAGS_VALID_INQUIRY;
+ vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
hd->Targets[sdev->id] = vtarget;
}
@@ -674,7 +669,10 @@ mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
* if still doing discovery,
* hang loose a while until finished
*/
- if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {
+ if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) ||
+ (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE &&
+ (pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK)
+ == MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) {
if (count-- > 0) {
msleep(100);
goto try_again;
@@ -900,59 +898,45 @@ mptfc_rescan_devices(void *arg)
{
MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
int ii;
- int work_to_do;
u64 pn;
- unsigned long flags;
struct mptfc_rport_info *ri;
- do {
- /* start by tagging all ports as missing */
- list_for_each_entry(ri, &ioc->fc_rports, list) {
- if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
- ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
- }
+ /* start by tagging all ports as missing */
+ list_for_each_entry(ri, &ioc->fc_rports, list) {
+ if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
+ ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
}
+ }
- /*
- * now rescan devices known to adapter,
- * will reregister existing rports
- */
- for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
- (void) mptfc_GetFcPortPage0(ioc, ii);
- mptfc_init_host_attr(ioc,ii); /* refresh */
- mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
- }
+ /*
+ * now rescan devices known to adapter,
+ * will reregister existing rports
+ */
+ for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
+ (void) mptfc_GetFcPortPage0(ioc, ii);
+ mptfc_init_host_attr(ioc, ii); /* refresh */
+ mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
+ }
- /* delete devices still missing */
- list_for_each_entry(ri, &ioc->fc_rports, list) {
- /* if newly missing, delete it */
- if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
+ /* delete devices still missing */
+ list_for_each_entry(ri, &ioc->fc_rports, list) {
+ /* if newly missing, delete it */
+ if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
- ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
- MPT_RPORT_INFO_FLAGS_MISSING);
- fc_remote_port_delete(ri->rport); /* won't sleep */
- ri->rport = NULL;
+ ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
+ MPT_RPORT_INFO_FLAGS_MISSING);
+ fc_remote_port_delete(ri->rport); /* won't sleep */
+ ri->rport = NULL;
- pn = (u64)ri->pg0.WWPN.High << 32 |
- (u64)ri->pg0.WWPN.Low;
- dfcprintk ((MYIOC_s_INFO_FMT
- "mptfc_rescan.%d: %llx deleted\n",
- ioc->name,
- ioc->sh->host_no,
- (unsigned long long)pn));
- }
+ pn = (u64)ri->pg0.WWPN.High << 32 |
+ (u64)ri->pg0.WWPN.Low;
+ dfcprintk ((MYIOC_s_INFO_FMT
+ "mptfc_rescan.%d: %llx deleted\n",
+ ioc->name,
+ ioc->sh->host_no,
+ (unsigned long long)pn));
}
-
- /*
- * allow multiple passes as target state
- * might have changed during scan
- */
- spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
- if (ioc->fc_rescan_work_count > 2) /* only need one more */
- ioc->fc_rescan_work_count = 2;
- work_to_do = --ioc->fc_rescan_work_count;
- spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
- } while (work_to_do);
+ }
}
static int
@@ -1129,13 +1113,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hd->timer.data = (unsigned long) hd;
hd->timer.function = mptscsih_timer_expired;
- hd->mpt_pq_filter = mpt_pq_filter;
-
- ddvprintk((MYIOC_s_INFO_FMT
- "mpt_pq_filter %x\n",
- ioc->name,
- mpt_pq_filter));
-
init_waitqueue_head(&hd->scandv_waitq);
hd->scandv_wait_done = 0;
hd->last_queue_full = 0;
@@ -1171,7 +1148,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
* by doing it via the workqueue, some locking is eliminated
*/
- ioc->fc_rescan_work_count = 1;
queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
flush_workqueue(ioc->fc_rescan_work_q);
@@ -1214,10 +1190,8 @@ mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
case MPI_EVENT_RESCAN:
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
if (ioc->fc_rescan_work_q) {
- if (ioc->fc_rescan_work_count++ == 0) {
- queue_work(ioc->fc_rescan_work_q,
- &ioc->fc_rescan_work);
- }
+ queue_work(ioc->fc_rescan_work_q,
+ &ioc->fc_rescan_work);
}
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
break;
@@ -1260,10 +1234,8 @@ mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
mptfc_SetFcPortPage1_defaults(ioc);
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
if (ioc->fc_rescan_work_q) {
- if (ioc->fc_rescan_work_count++ == 0) {
- queue_work(ioc->fc_rescan_work_q,
- &ioc->fc_rescan_work);
- }
+ queue_work(ioc->fc_rescan_work_q,
+ &ioc->fc_rescan_work);
}
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
}
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 85689ab46cbc..f66f2203143a 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -50,11 +50,14 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/workqueue.h>
+#include <linux/delay.h> /* for mdelay */
+#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_sas.h>
+#include <scsi/scsi_dbg.h>
#include "mptbase.h"
#include "mptscsih.h"
@@ -64,20 +67,19 @@
#define my_VERSION MPT_LINUX_VERSION_COMMON
#define MYNAM "mptsas"
+/*
+ * Reserved channel for integrated raid
+ */
+#define MPTSAS_RAID_CHANNEL 1
+
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 "
+ " Clear persistency table: enable=1 "
"(default=MPTSCSIH_PT_CLEAR=0)");
static int mptsasDoneCtx = -1;
@@ -137,23 +139,36 @@ struct mptsas_devinfo {
u32 device_info; /* bitfield detailed info about this device */
};
+/*
+ * Specific details on ports, wide/narrow
+ */
+struct mptsas_portinfo_details{
+ u16 num_phys; /* number of phys belong to this port */
+ u64 phy_bitmask; /* TODO, extend support for 255 phys */
+ struct sas_rphy *rphy; /* transport layer rphy object */
+ struct sas_port *port; /* transport layer port object */
+ struct scsi_target *starget;
+ struct mptsas_portinfo *port_info;
+};
+
struct mptsas_phyinfo {
u8 phy_id; /* phy index */
- u8 port_id; /* port number this phy is part of */
+ u8 port_id; /* firmware port identifier */
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 */
+ u8 sas_port_add_phy; /* flag to request sas_port_add_phy*/
struct mptsas_devinfo identify; /* point to phy device info */
struct mptsas_devinfo attached; /* point to attached device info */
- struct sas_phy *phy;
- struct sas_rphy *rphy;
- struct scsi_target *starget;
+ struct sas_phy *phy; /* transport layer phy object */
+ struct mptsas_portinfo *portinfo;
+ struct mptsas_portinfo_details * port_details;
};
struct mptsas_portinfo {
struct list_head list;
u16 handle; /* unique id to address this */
- u8 num_phys; /* number of phys */
+ u16 num_phys; /* number of phys */
struct mptsas_phyinfo *phy_info;
};
@@ -169,7 +184,7 @@ struct mptsas_enclosure {
u8 sep_channel; /* SEP channel logical channel id */
};
-#ifdef SASDEBUG
+#ifdef MPT_DEBUG_SAS
static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
{
printk("---- IO UNIT PAGE 0 ------------\n");
@@ -305,7 +320,7 @@ mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
static inline int
mptsas_is_end_device(struct mptsas_devinfo * attached)
{
- if ((attached->handle) &&
+ if ((attached->sas_address) &&
(attached->device_info &
MPI_SAS_DEVICE_INFO_END_DEVICE) &&
((attached->device_info &
@@ -319,6 +334,247 @@ mptsas_is_end_device(struct mptsas_devinfo * attached)
return 0;
}
+/* no mutex */
+static void
+mptsas_port_delete(struct mptsas_portinfo_details * port_details)
+{
+ struct mptsas_portinfo *port_info;
+ struct mptsas_phyinfo *phy_info;
+ u8 i;
+
+ if (!port_details)
+ return;
+
+ port_info = port_details->port_info;
+ phy_info = port_info->phy_info;
+
+ dsaswideprintk((KERN_DEBUG "%s: [%p]: num_phys=%02d "
+ "bitmask=0x%016llX\n",
+ __FUNCTION__, port_details, port_details->num_phys,
+ port_details->phy_bitmask));
+
+ for (i = 0; i < port_info->num_phys; i++, phy_info++) {
+ if(phy_info->port_details != port_details)
+ continue;
+ memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
+ phy_info->port_details = NULL;
+ }
+ kfree(port_details);
+}
+
+static inline struct sas_rphy *
+mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
+{
+ if (phy_info->port_details)
+ return phy_info->port_details->rphy;
+ else
+ return NULL;
+}
+
+static inline void
+mptsas_set_rphy(struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
+{
+ if (phy_info->port_details) {
+ phy_info->port_details->rphy = rphy;
+ dsaswideprintk((KERN_DEBUG "sas_rphy_add: rphy=%p\n", rphy));
+ }
+
+#ifdef MPT_DEBUG_SAS_WIDE
+ if (rphy) {
+ dev_printk(KERN_DEBUG, &rphy->dev, "add:");
+ printk("rphy=%p release=%p\n",
+ rphy, rphy->dev.release);
+ }
+#endif
+}
+
+static inline struct sas_port *
+mptsas_get_port(struct mptsas_phyinfo *phy_info)
+{
+ if (phy_info->port_details)
+ return phy_info->port_details->port;
+ else
+ return NULL;
+}
+
+static inline void
+mptsas_set_port(struct mptsas_phyinfo *phy_info, struct sas_port *port)
+{
+ if (phy_info->port_details)
+ phy_info->port_details->port = port;
+
+#ifdef MPT_DEBUG_SAS_WIDE
+ if (port) {
+ dev_printk(KERN_DEBUG, &port->dev, "add: ");
+ printk("port=%p release=%p\n",
+ port, port->dev.release);
+ }
+#endif
+}
+
+static inline struct scsi_target *
+mptsas_get_starget(struct mptsas_phyinfo *phy_info)
+{
+ if (phy_info->port_details)
+ return phy_info->port_details->starget;
+ else
+ return NULL;
+}
+
+static inline void
+mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
+starget)
+{
+ if (phy_info->port_details)
+ phy_info->port_details->starget = starget;
+}
+
+
+/*
+ * mptsas_setup_wide_ports
+ *
+ * Updates for new and existing narrow/wide port configuration
+ * in the sas_topology
+ */
+static void
+mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
+{
+ struct mptsas_portinfo_details * port_details;
+ struct mptsas_phyinfo *phy_info, *phy_info_cmp;
+ u64 sas_address;
+ int i, j;
+
+ mutex_lock(&ioc->sas_topology_mutex);
+
+ phy_info = port_info->phy_info;
+ for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
+ if (phy_info->attached.handle)
+ continue;
+ port_details = phy_info->port_details;
+ if (!port_details)
+ continue;
+ if (port_details->num_phys < 2)
+ continue;
+ /*
+ * Removing a phy from a port, letting the last
+ * phy be removed by firmware events.
+ */
+ dsaswideprintk((KERN_DEBUG
+ "%s: [%p]: deleting phy = %d\n",
+ __FUNCTION__, port_details, i));
+ port_details->num_phys--;
+ port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
+ memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
+ sas_port_delete_phy(port_details->port, phy_info->phy);
+ phy_info->port_details = NULL;
+ }
+
+ /*
+ * Populate and refresh the tree
+ */
+ phy_info = port_info->phy_info;
+ for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
+ sas_address = phy_info->attached.sas_address;
+ dsaswideprintk((KERN_DEBUG "phy_id=%d sas_address=0x%018llX\n",
+ i, sas_address));
+ if (!sas_address)
+ continue;
+ port_details = phy_info->port_details;
+ /*
+ * Forming a port
+ */
+ if (!port_details) {
+ port_details = kzalloc(sizeof(*port_details),
+ GFP_KERNEL);
+ if (!port_details)
+ goto out;
+ port_details->num_phys = 1;
+ port_details->port_info = port_info;
+ if (phy_info->phy_id < 64 )
+ port_details->phy_bitmask |=
+ (1 << phy_info->phy_id);
+ phy_info->sas_port_add_phy=1;
+ dsaswideprintk((KERN_DEBUG "\t\tForming port\n\t\t"
+ "phy_id=%d sas_address=0x%018llX\n",
+ i, sas_address));
+ phy_info->port_details = port_details;
+ }
+
+ if (i == port_info->num_phys - 1)
+ continue;
+ phy_info_cmp = &port_info->phy_info[i + 1];
+ for (j = i + 1 ; j < port_info->num_phys ; j++,
+ phy_info_cmp++) {
+ if (!phy_info_cmp->attached.sas_address)
+ continue;
+ if (sas_address != phy_info_cmp->attached.sas_address)
+ continue;
+ if (phy_info_cmp->port_details == port_details )
+ continue;
+ dsaswideprintk((KERN_DEBUG
+ "\t\tphy_id=%d sas_address=0x%018llX\n",
+ j, phy_info_cmp->attached.sas_address));
+ if (phy_info_cmp->port_details) {
+ port_details->rphy =
+ mptsas_get_rphy(phy_info_cmp);
+ port_details->port =
+ mptsas_get_port(phy_info_cmp);
+ port_details->starget =
+ mptsas_get_starget(phy_info_cmp);
+ port_details->num_phys =
+ phy_info_cmp->port_details->num_phys;
+ if (!phy_info_cmp->port_details->num_phys)
+ kfree(phy_info_cmp->port_details);
+ } else
+ phy_info_cmp->sas_port_add_phy=1;
+ /*
+ * Adding a phy to a port
+ */
+ phy_info_cmp->port_details = port_details;
+ if (phy_info_cmp->phy_id < 64 )
+ port_details->phy_bitmask |=
+ (1 << phy_info_cmp->phy_id);
+ port_details->num_phys++;
+ }
+ }
+
+ out:
+
+#ifdef MPT_DEBUG_SAS_WIDE
+ for (i = 0; i < port_info->num_phys; i++) {
+ port_details = port_info->phy_info[i].port_details;
+ if (!port_details)
+ continue;
+ dsaswideprintk((KERN_DEBUG
+ "%s: [%p]: phy_id=%02d num_phys=%02d "
+ "bitmask=0x%016llX\n",
+ __FUNCTION__,
+ port_details, i, port_details->num_phys,
+ port_details->phy_bitmask));
+ dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n",
+ port_details->port, port_details->rphy));
+ }
+ dsaswideprintk((KERN_DEBUG"\n"));
+#endif
+ mutex_unlock(&ioc->sas_topology_mutex);
+}
+
+static void
+mptsas_target_reset(MPT_ADAPTER *ioc, VirtTarget * vtarget)
+{
+ MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
+
+ if (mptscsih_TMHandler(hd,
+ MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
+ vtarget->bus_id, vtarget->target_id, 0, 0, 5) < 0) {
+ hd->tmPending = 0;
+ hd->tmState = TM_STATE_NONE;
+ printk(MYIOC_s_WARN_FMT
+ "Error processing TaskMgmt id=%d TARGET_RESET\n",
+ ioc->name, vtarget->target_id);
+ }
+}
+
static int
mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
u32 form, u32 form_specific)
@@ -387,24 +643,112 @@ mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
static int
mptsas_slave_configure(struct scsi_device *sdev)
{
- struct Scsi_Host *host = sdev->host;
- MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
- /*
- * RAID volumes placed beyond the last expected port.
- * Ignore sending sas mode pages in that case..
- */
- if (sdev->channel < hd->ioc->num_ports)
- sas_read_port_mode_page(sdev);
+ if (sdev->channel == MPTSAS_RAID_CHANNEL)
+ goto out;
+ sas_read_port_mode_page(sdev);
+
+ out:
return mptscsih_slave_configure(sdev);
}
-/*
- * 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_target_alloc(struct scsi_target *starget)
+{
+ struct Scsi_Host *host = dev_to_shost(&starget->dev);
+ MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
+ VirtTarget *vtarget;
+ u32 target_id;
+ u32 channel;
+ struct sas_rphy *rphy;
+ struct mptsas_portinfo *p;
+ int i;
+
+ vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
+ if (!vtarget)
+ return -ENOMEM;
+
+ vtarget->starget = starget;
+ vtarget->ioc_id = hd->ioc->id;
+ vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
+
+ target_id = starget->id;
+ channel = 0;
+
+ hd->Targets[target_id] = vtarget;
+
+ if (starget->channel == MPTSAS_RAID_CHANNEL)
+ goto out;
+
+ rphy = dev_to_rphy(starget->dev.parent);
+ mutex_lock(&hd->ioc->sas_topology_mutex);
+ 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)
+ continue;
+ target_id = p->phy_info[i].attached.id;
+ channel = p->phy_info[i].attached.channel;
+ mptsas_set_starget(&p->phy_info[i], starget);
+
+ /*
+ * Exposing hidden raid components
+ */
+ if (mptscsih_is_phys_disk(hd->ioc, target_id)) {
+ target_id = mptscsih_raid_id_to_num(hd,
+ target_id);
+ vtarget->tflags |=
+ MPT_TARGET_FLAGS_RAID_COMPONENT;
+ }
+ mutex_unlock(&hd->ioc->sas_topology_mutex);
+ goto out;
+ }
+ }
+ mutex_unlock(&hd->ioc->sas_topology_mutex);
+
+ kfree(vtarget);
+ return -ENXIO;
+
+ out:
+ vtarget->target_id = target_id;
+ vtarget->bus_id = channel;
+ starget->hostdata = vtarget;
+ return 0;
+}
+
+static void
+mptsas_target_destroy(struct scsi_target *starget)
+{
+ struct Scsi_Host *host = dev_to_shost(&starget->dev);
+ MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
+ struct sas_rphy *rphy;
+ struct mptsas_portinfo *p;
+ int i;
+
+ if (!starget->hostdata)
+ return;
+
+ if (starget->channel == MPTSAS_RAID_CHANNEL)
+ goto out;
+
+ rphy = dev_to_rphy(starget->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)
+ continue;
+ mptsas_set_starget(&p->phy_info[i], NULL);
+ goto out;
+ }
+ }
+
+ out:
+ kfree(starget->hostdata);
+ starget->hostdata = NULL;
+}
+
+
static int
mptsas_slave_alloc(struct scsi_device *sdev)
{
@@ -412,61 +756,38 @@ mptsas_slave_alloc(struct scsi_device *sdev)
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
struct sas_rphy *rphy;
struct mptsas_portinfo *p;
- VirtTarget *vtarget;
VirtDevice *vdev;
struct scsi_target *starget;
- u32 target_id;
- int i;
+ int i;
vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
if (!vdev) {
- printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
+ printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
hd->ioc->name, sizeof(VirtDevice));
return -ENOMEM;
}
- sdev->hostdata = vdev;
starget = scsi_target(sdev);
- vtarget = starget->hostdata;
- vtarget->ioc_id = hd->ioc->id;
- vdev->vtarget = vtarget;
- if (vtarget->num_luns == 0) {
- vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
- hd->Targets[sdev->id] = vtarget;
- }
+ vdev->vtarget = starget->hostdata;
- /*
- RAID volumes placed beyond the last expected port.
- */
- if (sdev->channel == hd->ioc->num_ports) {
- target_id = sdev->id;
- vtarget->bus_id = 0;
- vdev->lun = 0;
+ if (sdev->channel == MPTSAS_RAID_CHANNEL)
goto out;
- }
rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
mutex_lock(&hd->ioc->sas_topology_mutex);
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) {
- target_id = p->phy_info[i].attached.id;
- vtarget->bus_id = p->phy_info[i].attached.channel;
- vdev->lun = sdev->lun;
- p->phy_info[i].starget = sdev->sdev_target;
- /*
- * Exposing hidden disk (RAID)
- */
- if (mptscsih_is_phys_disk(hd->ioc, target_id)) {
- target_id = mptscsih_raid_id_to_num(hd,
- target_id);
- vdev->vtarget->tflags |=
- MPT_TARGET_FLAGS_RAID_COMPONENT;
- sdev->no_uld_attach = 1;
- }
- mutex_unlock(&hd->ioc->sas_topology_mutex);
- goto out;
- }
+ if (p->phy_info[i].attached.sas_address !=
+ rphy->identify.sas_address)
+ continue;
+ vdev->lun = sdev->lun;
+ /*
+ * Exposing hidden raid components
+ */
+ if (mptscsih_is_phys_disk(hd->ioc,
+ p->phy_info[i].attached.id))
+ sdev->no_uld_attach = 1;
+ mutex_unlock(&hd->ioc->sas_topology_mutex);
+ goto out;
}
}
mutex_unlock(&hd->ioc->sas_topology_mutex);
@@ -475,57 +796,39 @@ mptsas_slave_alloc(struct scsi_device *sdev)
return -ENXIO;
out:
- vtarget->target_id = target_id;
- vtarget->num_luns++;
+ vdev->vtarget->num_luns++;
+ sdev->hostdata = vdev;
return 0;
}
-static void
-mptsas_slave_destroy(struct scsi_device *sdev)
+static int
+mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{
- struct Scsi_Host *host = sdev->host;
- MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
- VirtDevice *vdev;
-
- /*
- * Issue target reset to flush firmware outstanding commands.
- */
- vdev = sdev->hostdata;
- if (vdev->configured_lun){
- if (mptscsih_TMHandler(hd,
- MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
- vdev->vtarget->bus_id,
- vdev->vtarget->target_id,
- 0, 0, 5 /* 5 second timeout */)
- < 0){
-
- /* The TM request failed!
- * Fatal error case.
- */
- printk(MYIOC_s_WARN_FMT
- "Error processing TaskMgmt id=%d TARGET_RESET\n",
- hd->ioc->name,
- vdev->vtarget->target_id);
+ VirtDevice *vdev = SCpnt->device->hostdata;
- hd->tmPending = 0;
- hd->tmState = TM_STATE_NONE;
- }
+// scsi_print_command(SCpnt);
+ if (vdev->vtarget->deleted) {
+ SCpnt->result = DID_NO_CONNECT << 16;
+ done(SCpnt);
+ return 0;
}
- mptscsih_slave_destroy(sdev);
+
+ return mptscsih_qcmd(SCpnt,done);
}
+
static struct scsi_host_template mptsas_driver_template = {
.module = THIS_MODULE,
.proc_name = "mptsas",
.proc_info = mptscsih_proc_info,
.name = "MPT SPI Host",
.info = mptscsih_info,
- .queuecommand = mptscsih_qcmd,
- .target_alloc = mptscsih_target_alloc,
+ .queuecommand = mptsas_qcmd,
+ .target_alloc = mptsas_target_alloc,
.slave_alloc = mptsas_slave_alloc,
.slave_configure = mptsas_slave_configure,
- .target_destroy = mptscsih_target_destroy,
- .slave_destroy = mptsas_slave_destroy,
+ .target_destroy = mptsas_target_destroy,
+ .slave_destroy = mptscsih_slave_destroy,
.change_queue_depth = mptscsih_change_queue_depth,
.eh_abort_handler = mptscsih_abort,
.eh_device_reset_handler = mptscsih_dev_reset,
@@ -795,7 +1098,7 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
port_info->num_phys = buffer->NumPhys;
port_info->phy_info = kcalloc(port_info->num_phys,
- sizeof(struct mptsas_phyinfo),GFP_KERNEL);
+ sizeof(*port_info->phy_info),GFP_KERNEL);
if (!port_info->phy_info) {
error = -ENOMEM;
goto out_free_consistent;
@@ -811,6 +1114,7 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
buffer->PhyData[i].Port;
port_info->phy_info[i].negotiated_link_rate =
buffer->PhyData[i].NegotiatedLinkRate;
+ port_info->phy_info[i].portinfo = port_info;
}
out_free_consistent:
@@ -968,7 +1272,7 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
CONFIGPARMS cfg;
SasExpanderPage0_t *buffer;
dma_addr_t dma_handle;
- int error;
+ int i, error;
hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
hdr.ExtPageLength = 0;
@@ -1013,12 +1317,15 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
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);
+ sizeof(*port_info->phy_info),GFP_KERNEL);
if (!port_info->phy_info) {
error = -ENOMEM;
goto out_free_consistent;
}
+ for (i = 0; i < port_info->num_phys; i++)
+ port_info->phy_info[i].portinfo = port_info;
+
out_free_consistent:
pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
buffer, dma_handle);
@@ -1161,19 +1468,23 @@ static int mptsas_probe_one_phy(struct device *dev,
{
MPT_ADAPTER *ioc;
struct sas_phy *phy;
- int error;
+ struct sas_port *port;
+ int error = 0;
- if (!dev)
- return -ENODEV;
+ if (!dev) {
+ error = -ENODEV;
+ goto out;
+ }
if (!phy_info->phy) {
phy = sas_phy_alloc(dev, index);
- if (!phy)
- return -ENOMEM;
+ if (!phy) {
+ error = -ENOMEM;
+ goto out;
+ }
} else
phy = phy_info->phy;
- phy->port_identifier = phy_info->port_id;
mptsas_parse_device_info(&phy->identify, &phy_info->identify);
/*
@@ -1265,19 +1576,51 @@ static int mptsas_probe_one_phy(struct device *dev,
error = sas_phy_add(phy);
if (error) {
sas_phy_free(phy);
- return error;
+ goto out;
}
phy_info->phy = phy;
}
- if ((phy_info->attached.handle) &&
- (!phy_info->rphy)) {
+ if (!phy_info->attached.handle ||
+ !phy_info->port_details)
+ goto out;
+
+ port = mptsas_get_port(phy_info);
+ ioc = phy_to_ioc(phy_info->phy);
+
+ if (phy_info->sas_port_add_phy) {
+
+ if (!port) {
+ port = sas_port_alloc_num(dev);
+ if (!port) {
+ error = -ENOMEM;
+ goto out;
+ }
+ error = sas_port_add(port);
+ if (error) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
+ goto out;
+ }
+ mptsas_set_port(phy_info, port);
+ dsaswideprintk((KERN_DEBUG
+ "sas_port_alloc: port=%p dev=%p port_id=%d\n",
+ port, dev, port->port_identifier));
+ }
+ dsaswideprintk((KERN_DEBUG "sas_port_add_phy: phy_id=%d\n",
+ phy_info->phy_id));
+ sas_port_add_phy(port, phy_info->phy);
+ phy_info->sas_port_add_phy = 0;
+ }
+
+ if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
struct sas_rphy *rphy;
+ struct device *parent;
struct sas_identify identify;
- ioc = phy_to_ioc(phy_info->phy);
-
+ parent = dev->parent->parent;
/*
* Let the hotplug_work thread handle processing
* the adding/removing of devices that occur
@@ -1285,36 +1628,63 @@ static int mptsas_probe_one_phy(struct device *dev,
*/
if (ioc->sas_discovery_runtime &&
mptsas_is_end_device(&phy_info->attached))
- return 0;
+ goto out;
mptsas_parse_device_info(&identify, &phy_info->attached);
+ if (scsi_is_host_device(parent)) {
+ struct mptsas_portinfo *port_info;
+ int i;
+
+ mutex_lock(&ioc->sas_topology_mutex);
+ port_info = mptsas_find_portinfo_by_handle(ioc,
+ ioc->handle);
+ mutex_unlock(&ioc->sas_topology_mutex);
+
+ for (i = 0; i < port_info->num_phys; i++)
+ if (port_info->phy_info[i].identify.sas_address ==
+ identify.sas_address)
+ goto out;
+
+ } else if (scsi_is_sas_rphy(parent)) {
+ struct sas_rphy *parent_rphy = dev_to_rphy(parent);
+ if (identify.sas_address ==
+ parent_rphy->identify.sas_address)
+ goto out;
+ }
+
switch (identify.device_type) {
case SAS_END_DEVICE:
- rphy = sas_end_device_alloc(phy);
+ rphy = sas_end_device_alloc(port);
break;
case SAS_EDGE_EXPANDER_DEVICE:
case SAS_FANOUT_EXPANDER_DEVICE:
- rphy = sas_expander_alloc(phy, identify.device_type);
+ rphy = sas_expander_alloc(port, identify.device_type);
break;
default:
rphy = NULL;
break;
}
- if (!rphy)
- return 0; /* non-fatal: an rphy can be added later */
+ if (!rphy) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
+ goto out;
+ }
rphy->identify = identify;
-
error = sas_rphy_add(rphy);
if (error) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
sas_rphy_free(rphy);
- return error;
+ goto out;
}
-
- phy_info->rphy = rphy;
+ mptsas_set_rphy(phy_info, rphy);
}
- return 0;
+ out:
+ return error;
}
static int
@@ -1333,6 +1703,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
goto out_free_port_info;
mutex_lock(&ioc->sas_topology_mutex);
+ ioc->handle = hba->handle;
port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle);
if (!port_info) {
port_info = hba;
@@ -1342,13 +1713,11 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
for (i = 0; i < hba->num_phys; i++)
port_info->phy_info[i].negotiated_link_rate =
hba->phy_info[i].negotiated_link_rate;
- if (hba->phy_info)
- kfree(hba->phy_info);
+ kfree(hba->phy_info);
kfree(hba);
hba = NULL;
}
mutex_unlock(&ioc->sas_topology_mutex);
- ioc->num_ports = port_info->num_phys;
for (i = 0; i < port_info->num_phys; i++) {
mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
@@ -1362,18 +1731,19 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
port_info->phy_info[i].phy_id;
handle = port_info->phy_info[i].identify.handle;
- if (port_info->phy_info[i].attached.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_setup_wide_ports(ioc, port_info);
+
+ for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
mptsas_probe_one_phy(&ioc->sh->shost_gendev,
&port_info->phy_info[i], ioc->sas_index, 1);
- ioc->sas_index++;
- }
return 0;
@@ -1387,6 +1757,8 @@ static int
mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
{
struct mptsas_portinfo *port_info, *p, *ex;
+ struct device *parent;
+ struct sas_rphy *rphy;
int error = -ENOMEM, i, j;
ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
@@ -1408,16 +1780,13 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
list_add_tail(&port_info->list, &ioc->sas_topology);
} else {
port_info->handle = ex->handle;
- if (ex->phy_info)
- kfree(ex->phy_info);
+ kfree(ex->phy_info);
kfree(ex);
ex = NULL;
}
mutex_unlock(&ioc->sas_topology_mutex);
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);
@@ -1441,34 +1810,34 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
port_info->phy_info[i].attached.phy_id =
port_info->phy_info[i].phy_id;
}
+ }
- /*
- * 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;
+ parent = &ioc->sh->shost_gendev;
+ for (i = 0; i < port_info->num_phys; i++) {
mutex_lock(&ioc->sas_topology_mutex);
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 ==
+ if (port_info->phy_info[i].identify.handle !=
p->phy_info[j].attached.handle)
- parent = &p->phy_info[j].rphy->dev;
+ continue;
+ rphy = mptsas_get_rphy(&p->phy_info[j]);
+ parent = &rphy->dev;
}
}
mutex_unlock(&ioc->sas_topology_mutex);
+ }
+ mptsas_setup_wide_ports(ioc, port_info);
+
+ for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
mptsas_probe_one_phy(parent, &port_info->phy_info[i],
ioc->sas_index, 0);
- ioc->sas_index++;
- }
return 0;
out_free_port_info:
if (ex) {
- if (ex->phy_info)
- kfree(ex->phy_info);
+ kfree(ex->phy_info);
kfree(ex);
}
out:
@@ -1487,7 +1856,12 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
{
struct mptsas_portinfo buffer;
struct mptsas_portinfo *port_info, *n, *parent;
+ struct mptsas_phyinfo *phy_info;
+ struct scsi_target * starget;
+ VirtTarget * vtarget;
+ struct sas_port * port;
int i;
+ u64 expander_sas_address;
mutex_lock(&ioc->sas_topology_mutex);
list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
@@ -1502,6 +1876,25 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) {
/*
+ * Issue target reset to all child end devices
+ * then mark them deleted to prevent further
+ * IO going to them.
+ */
+ phy_info = port_info->phy_info;
+ for (i = 0; i < port_info->num_phys; i++, phy_info++) {
+ starget = mptsas_get_starget(phy_info);
+ if (!starget)
+ continue;
+ vtarget = starget->hostdata;
+ if(vtarget->deleted)
+ continue;
+ vtarget->deleted = 1;
+ mptsas_target_reset(ioc, vtarget);
+ sas_port_delete(mptsas_get_port(phy_info));
+ mptsas_port_delete(phy_info->port_details);
+ }
+
+ /*
* Obtain the port_info instance to the parent port
*/
parent = mptsas_find_portinfo_by_handle(ioc,
@@ -1510,34 +1903,44 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
if (!parent)
goto next_port;
+ expander_sas_address =
+ port_info->phy_info[0].identify.sas_address;
+
/*
* Delete rphys in the parent that point
* to this expander. The transport layer will
* cleanup all the children.
*/
- for (i = 0; i < parent->num_phys; i++) {
- if ((!parent->phy_info[i].rphy) ||
- (parent->phy_info[i].attached.sas_address !=
- port_info->phy_info[i].identify.sas_address))
+ phy_info = parent->phy_info;
+ for (i = 0; i < parent->num_phys; i++, phy_info++) {
+ port = mptsas_get_port(phy_info);
+ if (!port)
continue;
- sas_rphy_delete(parent->phy_info[i].rphy);
- memset(&parent->phy_info[i].attached, 0,
- sizeof(struct mptsas_devinfo));
- parent->phy_info[i].rphy = NULL;
- parent->phy_info[i].starget = NULL;
+ if (phy_info->attached.sas_address !=
+ expander_sas_address)
+ continue;
+#ifdef MPT_DEBUG_SAS_WIDE
+ dev_printk(KERN_DEBUG, &port->dev,
+ "delete port (%d)\n", port->port_identifier);
+#endif
+ sas_port_delete(port);
+ mptsas_port_delete(phy_info->port_details);
}
next_port:
+
+ phy_info = port_info->phy_info;
+ for (i = 0; i < port_info->num_phys; i++, phy_info++)
+ mptsas_port_delete(phy_info->port_details);
+
list_del(&port_info->list);
- if (port_info->phy_info)
- kfree(port_info->phy_info);
+ kfree(port_info->phy_info);
kfree(port_info);
}
/*
* Free this memory allocated from inside
* mptsas_sas_expander_pg0
*/
- if (buffer.phy_info)
- kfree(buffer.phy_info);
+ kfree(buffer.phy_info);
}
mutex_unlock(&ioc->sas_topology_mutex);
}
@@ -1563,7 +1966,7 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
goto out;
for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
- scsi_add_device(ioc->sh, ioc->num_ports,
+ scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
}
out:
@@ -1573,60 +1976,59 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
/*
* Work queue thread to handle Runtime discovery
* Mere purpose is the hot add/delete of expanders
+ *(Mutex UNLOCKED)
*/
static void
-mptscsih_discovery_work(void * arg)
+__mptsas_discovery_work(MPT_ADAPTER *ioc)
{
- struct mptsas_discovery_event *ev = arg;
- MPT_ADAPTER *ioc = ev->ioc;
u32 handle = 0xFFFF;
- mutex_lock(&ioc->sas_discovery_mutex);
ioc->sas_discovery_runtime=1;
mptsas_delete_expander_phys(ioc);
mptsas_probe_hba_phys(ioc);
while (!mptsas_probe_expander_phys(ioc, &handle))
;
- kfree(ev);
ioc->sas_discovery_runtime=0;
+}
+
+/*
+ * Work queue thread to handle Runtime discovery
+ * Mere purpose is the hot add/delete of expanders
+ *(Mutex LOCKED)
+ */
+static void
+mptsas_discovery_work(void * arg)
+{
+ struct mptsas_discovery_event *ev = arg;
+ MPT_ADAPTER *ioc = ev->ioc;
+
+ mutex_lock(&ioc->sas_discovery_mutex);
+ __mptsas_discovery_work(ioc);
mutex_unlock(&ioc->sas_discovery_mutex);
+ kfree(ev);
}
static struct mptsas_phyinfo *
-mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)
+mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
{
struct mptsas_portinfo *port_info;
- struct mptsas_devinfo device_info;
struct mptsas_phyinfo *phy_info = NULL;
- int i, error;
-
- /*
- * Retrieve the parent sas_address
- */
- error = mptsas_sas_device_pg0(ioc, &device_info,
- (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
- MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
- parent_handle);
- if (error)
- return NULL;
+ int i;
- /*
- * The phy_info structures are never deallocated during lifetime of
- * a host, so the code below is safe without additional refcounting.
- */
mutex_lock(&ioc->sas_topology_mutex);
list_for_each_entry(port_info, &ioc->sas_topology, list) {
for (i = 0; i < port_info->num_phys; i++) {
- if (port_info->phy_info[i].identify.sas_address ==
- device_info.sas_address &&
- port_info->phy_info[i].phy_id == phy_id) {
- phy_info = &port_info->phy_info[i];
- break;
- }
+ if (port_info->phy_info[i].attached.sas_address
+ != sas_address)
+ continue;
+ if (!mptsas_is_end_device(
+ &port_info->phy_info[i].attached))
+ continue;
+ phy_info = &port_info->phy_info[i];
+ break;
}
}
mutex_unlock(&ioc->sas_topology_mutex);
-
return phy_info;
}
@@ -1637,21 +2039,19 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
struct mptsas_phyinfo *phy_info = NULL;
int i;
- /*
- * The phy_info structures are never deallocated during lifetime of
- * a host, so the code below is safe without additional refcounting.
- */
mutex_lock(&ioc->sas_topology_mutex);
list_for_each_entry(port_info, &ioc->sas_topology, list) {
- for (i = 0; i < port_info->num_phys; i++)
- if (mptsas_is_end_device(&port_info->phy_info[i].attached))
- if (port_info->phy_info[i].attached.id == id) {
- phy_info = &port_info->phy_info[i];
- break;
- }
+ for (i = 0; i < port_info->num_phys; i++) {
+ if (port_info->phy_info[i].attached.id != id)
+ continue;
+ if (!mptsas_is_end_device(
+ &port_info->phy_info[i].attached))
+ continue;
+ phy_info = &port_info->phy_info[i];
+ break;
+ }
}
mutex_unlock(&ioc->sas_topology_mutex);
-
return phy_info;
}
@@ -1659,7 +2059,7 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
* Work queue thread to clear the persitency table
*/
static void
-mptscsih_sas_persist_clear_table(void * arg)
+mptsas_persist_clear_table(void * arg)
{
MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
@@ -1680,7 +2080,6 @@ mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
mptsas_reprobe_lun);
}
-
/*
* Work queue thread to handle SAS hotplug events
*/
@@ -1691,14 +2090,17 @@ mptsas_hotplug_work(void *arg)
MPT_ADAPTER *ioc = ev->ioc;
struct mptsas_phyinfo *phy_info;
struct sas_rphy *rphy;
+ struct sas_port *port;
struct scsi_device *sdev;
+ struct scsi_target * starget;
struct sas_identify identify;
char *ds = NULL;
struct mptsas_devinfo sas_device;
VirtTarget *vtarget;
+ VirtDevice *vdevice;
- mutex_lock(&ioc->sas_discovery_mutex);
+ mutex_lock(&ioc->sas_discovery_mutex);
switch (ev->event_type) {
case MPTSAS_DEL_DEVICE:
@@ -1707,24 +2109,50 @@ mptsas_hotplug_work(void *arg)
/*
* Sanity checks, for non-existing phys and remote rphys.
*/
- if (!phy_info)
+ if (!phy_info || !phy_info->port_details) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
break;
- if (!phy_info->rphy)
+ }
+ rphy = mptsas_get_rphy(phy_info);
+ if (!rphy) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
break;
- if (phy_info->starget) {
- vtarget = phy_info->starget->hostdata;
+ }
+ port = mptsas_get_port(phy_info);
+ if (!port) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
+ break;
+ }
- if (!vtarget)
+ starget = mptsas_get_starget(phy_info);
+ if (starget) {
+ vtarget = starget->hostdata;
+
+ if (!vtarget) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
break;
+ }
+
/*
* Handling RAID components
*/
if (ev->phys_disk_num_valid) {
vtarget->target_id = ev->phys_disk_num;
vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
- mptsas_reprobe_target(vtarget->starget, 1);
+ mptsas_reprobe_target(starget, 1);
break;
}
+
+ vtarget->deleted = 1;
+ mptsas_target_reset(ioc, vtarget);
}
if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
@@ -1738,10 +2166,12 @@ mptsas_hotplug_work(void *arg)
"removing %s device, channel %d, id %d, phy %d\n",
ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
- sas_rphy_delete(phy_info->rphy);
- memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
- phy_info->rphy = NULL;
- phy_info->starget = NULL;
+#ifdef MPT_DEBUG_SAS_WIDE
+ dev_printk(KERN_DEBUG, &port->dev,
+ "delete port (%d)\n", port->port_identifier);
+#endif
+ sas_port_delete(port);
+ mptsas_port_delete(phy_info->port_details);
break;
case MPTSAS_ADD_DEVICE:
@@ -1753,59 +2183,60 @@ mptsas_hotplug_work(void *arg)
*/
if (mptsas_sas_device_pg0(ioc, &sas_device,
(MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
- MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id))
+ MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
break;
+ }
- phy_info = mptsas_find_phyinfo_by_parent(ioc,
- sas_device.handle_parent, sas_device.phy_id);
+ ssleep(2);
+ __mptsas_discovery_work(ioc);
- if (!phy_info) {
- u32 handle = 0xFFFF;
+ phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
+ sas_device.sas_address);
- /*
- * Its possible when an expander has been hot added
- * containing attached devices, the sas firmware
- * may send a RC_ADDED event prior to the
- * DISCOVERY STOP event. If that occurs, our
- * view of the topology in the driver in respect to this
- * expander might of not been setup, and we hit this
- * condition.
- * Therefore, this code kicks off discovery to
- * refresh the data.
- * Then again, we check whether the parent phy has
- * been created.
- */
- ioc->sas_discovery_runtime=1;
- mptsas_delete_expander_phys(ioc);
- mptsas_probe_hba_phys(ioc);
- while (!mptsas_probe_expander_phys(ioc, &handle))
- ;
- ioc->sas_discovery_runtime=0;
-
- phy_info = mptsas_find_phyinfo_by_parent(ioc,
- sas_device.handle_parent, sas_device.phy_id);
- if (!phy_info)
- break;
+ if (!phy_info || !phy_info->port_details) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
+ break;
}
- if (phy_info->starget) {
- vtarget = phy_info->starget->hostdata;
+ starget = mptsas_get_starget(phy_info);
+ if (starget) {
+ vtarget = starget->hostdata;
- if (!vtarget)
+ if (!vtarget) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
break;
+ }
/*
* Handling RAID components
*/
if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
vtarget->target_id = ev->id;
- mptsas_reprobe_target(phy_info->starget, 0);
+ mptsas_reprobe_target(starget, 0);
}
break;
}
- if (phy_info->rphy)
+ if (mptsas_get_rphy(phy_info)) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
+ break;
+ }
+ port = mptsas_get_port(phy_info);
+ if (!port) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
break;
+ }
memcpy(&phy_info->attached, &sas_device,
sizeof(struct mptsas_devinfo));
@@ -1822,59 +2253,48 @@ mptsas_hotplug_work(void *arg)
ioc->name, ds, ev->channel, ev->id, ev->phy_id);
mptsas_parse_device_info(&identify, &phy_info->attached);
- switch (identify.device_type) {
- case SAS_END_DEVICE:
- rphy = sas_end_device_alloc(phy_info->phy);
- break;
- case SAS_EDGE_EXPANDER_DEVICE:
- case SAS_FANOUT_EXPANDER_DEVICE:
- rphy = sas_expander_alloc(phy_info->phy, identify.device_type);
- break;
- default:
- rphy = NULL;
- break;
- }
- if (!rphy)
+ rphy = sas_end_device_alloc(port);
+ if (!rphy) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
break; /* non-fatal: an rphy can be added later */
+ }
rphy->identify = identify;
if (sas_rphy_add(rphy)) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
sas_rphy_free(rphy);
break;
}
-
- phy_info->rphy = rphy;
+ mptsas_set_rphy(phy_info, rphy);
break;
case MPTSAS_ADD_RAID:
- sdev = scsi_device_lookup(
- ioc->sh,
- ioc->num_ports,
- ev->id,
- 0);
+ sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
+ ev->id, 0);
if (sdev) {
scsi_device_put(sdev);
break;
}
printk(MYIOC_s_INFO_FMT
"attaching raid volume, channel %d, id %d\n",
- ioc->name, ioc->num_ports, ev->id);
- scsi_add_device(ioc->sh,
- ioc->num_ports,
- ev->id,
- 0);
+ ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
+ scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
mpt_findImVolumes(ioc);
break;
case MPTSAS_DEL_RAID:
- sdev = scsi_device_lookup(
- ioc->sh,
- ioc->num_ports,
- ev->id,
- 0);
+ sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
+ ev->id, 0);
if (!sdev)
break;
printk(MYIOC_s_INFO_FMT
"removing raid volume, channel %d, id %d\n",
- ioc->name, ioc->num_ports, ev->id);
+ ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
+ vdevice = sdev->hostdata;
+ vdevice->vtarget->deleted = 1;
+ mptsas_target_reset(ioc, vdevice->vtarget);
scsi_remove_device(sdev);
scsi_device_put(sdev);
mpt_findImVolumes(ioc);
@@ -1884,12 +2304,13 @@ mptsas_hotplug_work(void *arg)
break;
}
- kfree(ev);
mutex_unlock(&ioc->sas_discovery_mutex);
+ kfree(ev);
+
}
static void
-mptscsih_send_sas_event(MPT_ADAPTER *ioc,
+mptsas_send_sas_event(MPT_ADAPTER *ioc,
EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
{
struct mptsas_hotplug_event *ev;
@@ -1905,7 +2326,7 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc,
switch (sas_event_data->ReasonCode) {
case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
- ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
+ ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
if (!ev) {
printk(KERN_WARNING "mptsas: lost hotplug event\n");
break;
@@ -1935,10 +2356,9 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc,
/*
* Persistent table is full.
*/
- INIT_WORK(&ioc->mptscsih_persistTask,
- mptscsih_sas_persist_clear_table,
- (void *)ioc);
- schedule_work(&ioc->mptscsih_persistTask);
+ INIT_WORK(&ioc->sas_persist_task,
+ mptsas_persist_clear_table, (void *)ioc);
+ schedule_work(&ioc->sas_persist_task);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
/* TODO */
@@ -1950,7 +2370,7 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc,
}
static void
-mptscsih_send_raid_event(MPT_ADAPTER *ioc,
+mptsas_send_raid_event(MPT_ADAPTER *ioc,
EVENT_DATA_RAID *raid_event_data)
{
struct mptsas_hotplug_event *ev;
@@ -1960,13 +2380,12 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
if (ioc->bus_type != SAS)
return;
- ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
+ ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
if (!ev) {
printk(KERN_WARNING "mptsas: lost hotplug event\n");
return;
}
- memset(ev,0,sizeof(struct mptsas_hotplug_event));
INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
ev->ioc = ioc;
ev->id = raid_event_data->VolumeID;
@@ -2028,7 +2447,7 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
}
static void
-mptscsih_send_discovery(MPT_ADAPTER *ioc,
+mptsas_send_discovery_event(MPT_ADAPTER *ioc,
EVENT_DATA_SAS_DISCOVERY *discovery_data)
{
struct mptsas_discovery_event *ev;
@@ -2043,11 +2462,10 @@ mptscsih_send_discovery(MPT_ADAPTER *ioc,
if (discovery_data->DiscoveryStatus)
return;
- ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
+ ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
if (!ev)
return;
- memset(ev,0,sizeof(struct mptsas_discovery_event));
- INIT_WORK(&ev->work, mptscsih_discovery_work, ev);
+ INIT_WORK(&ev->work, mptsas_discovery_work, ev);
ev->ioc = ioc;
schedule_work(&ev->work);
};
@@ -2075,21 +2493,21 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
switch (event) {
case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
- mptscsih_send_sas_event(ioc,
+ mptsas_send_sas_event(ioc,
(EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
break;
case MPI_EVENT_INTEGRATED_RAID:
- mptscsih_send_raid_event(ioc,
+ mptsas_send_raid_event(ioc,
(EVENT_DATA_RAID *)reply->Data);
break;
case MPI_EVENT_PERSISTENT_TABLE_FULL:
- INIT_WORK(&ioc->mptscsih_persistTask,
- mptscsih_sas_persist_clear_table,
+ INIT_WORK(&ioc->sas_persist_task,
+ mptsas_persist_clear_table,
(void *)ioc);
- schedule_work(&ioc->mptscsih_persistTask);
+ schedule_work(&ioc->sas_persist_task);
break;
case MPI_EVENT_SAS_DISCOVERY:
- mptscsih_send_discovery(ioc,
+ mptsas_send_discovery_event(ioc,
(EVENT_DATA_SAS_DISCOVERY *)reply->Data);
break;
default:
@@ -2279,7 +2697,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
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) {
@@ -2287,12 +2704,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
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;
@@ -2308,7 +2719,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
-out_mptsas_probe:
+ out_mptsas_probe:
mptscsih_remove(pdev);
return error;
@@ -2318,6 +2729,7 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
struct mptsas_portinfo *p, *n;
+ int i;
ioc->sas_discovery_ignore_events=1;
sas_remove_host(ioc->sh);
@@ -2325,8 +2737,9 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)
mutex_lock(&ioc->sas_topology_mutex);
list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
list_del(&p->list);
- if (p->phy_info)
- kfree(p->phy_info);
+ for (i = 0 ; i < p->num_phys ; i++)
+ mptsas_port_delete(p->phy_info[i].port_details);
+ kfree(p->phy_info);
kfree(p);
}
mutex_unlock(&ioc->sas_topology_mutex);
@@ -2335,17 +2748,15 @@ static void __devexit mptsas_remove(struct pci_dev *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_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
PCI_ANY_ID, PCI_ANY_ID },
{0} /* Terminating entry */
};
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 8242b16e3168..30524dc54b16 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -66,6 +66,7 @@
#include "mptbase.h"
#include "mptscsih.h"
+#include "lsi/mpi_log_sas.h"
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#define my_NAME "Fusion MPT SCSI Host driver"
@@ -127,7 +128,7 @@ static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
-static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
+static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
@@ -497,6 +498,34 @@ nextSGEset:
return SUCCESS;
} /* mptscsih_AddSGE() */
+static void
+mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
+ U32 SlotStatus)
+{
+ MPT_FRAME_HDR *mf;
+ SEPRequest_t *SEPMsg;
+
+ if (ioc->bus_type == FC)
+ return;
+
+ if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
+ dfailprintk((MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
+ ioc->name,__FUNCTION__));
+ return;
+ }
+
+ SEPMsg = (SEPRequest_t *)mf;
+ SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
+ SEPMsg->Bus = vtarget->bus_id;
+ SEPMsg->TargetID = vtarget->target_id;
+ SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
+ SEPMsg->SlotStatus = SlotStatus;
+ devtverboseprintk((MYIOC_s_WARN_FMT
+ "Sending SEP cmd=%x id=%d bus=%d\n",
+ ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus));
+ mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptscsih_io_done - Main SCSI IO callback routine registered to
@@ -520,6 +549,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
SCSIIORequest_t *pScsiReq;
SCSIIOReply_t *pScsiReply;
u16 req_idx, req_idx_MR;
+ VirtDevice *vdev;
+ VirtTarget *vtarget;
hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
@@ -538,6 +569,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
}
sc = hd->ScsiLookup[req_idx];
+ hd->ScsiLookup[req_idx] = NULL;
if (sc == NULL) {
MPIHeader_t *hdr = (MPIHeader_t *)mf;
@@ -553,6 +585,12 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
return 1;
}
+ if ((unsigned char *)mf != sc->host_scribble) {
+ mptscsih_freeChainBuffers(ioc, req_idx);
+ return 1;
+ }
+
+ sc->host_scribble = NULL;
sc->result = DID_OK << 16; /* Set default reply as OK */
pScsiReq = (SCSIIORequest_t *) mf;
pScsiReply = (SCSIIOReply_t *) mr;
@@ -640,10 +678,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
hd->sel_timeout[pScsiReq->TargetID]++;
+
+ vdev = sc->device->hostdata;
+ if (!vdev)
+ break;
+ vtarget = vdev->vtarget;
+ if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
+ mptscsih_issue_sep_command(ioc, vtarget,
+ MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
+ vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
+ }
break;
- case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
+ if ( ioc->bus_type == SAS ) {
+ u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
+ if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
+ u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
+ log_info &=SAS_LOGINFO_MASK;
+ if (log_info == SAS_LOGINFO_NEXUS_LOSS) {
+ sc->result = (DID_BUS_BUSY << 16);
+ break;
+ }
+ }
+ }
+
+ /*
+ * Allow non-SAS & non-NEXUS_LOSS to drop into below code
+ */
+
+ case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
/* Linux handles an unsolicited DID_RESET better
* than an unsolicited DID_ABORT.
@@ -658,7 +722,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
sc->result=DID_SOFT_ERROR << 16;
else /* Sufficient data transfer occurred */
sc->result = (DID_OK << 16) | scsi_status;
- dreplyprintk((KERN_NOTICE
+ dreplyprintk((KERN_NOTICE
"RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
break;
@@ -784,8 +848,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
sc->request_bufflen, sc->sc_data_direction);
}
- hd->ScsiLookup[req_idx] = NULL;
-
sc->scsi_done(sc); /* Issue the command callback */
/* Free Chain buffers */
@@ -827,9 +889,17 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
mf, SCpnt));
+ /* Free Chain buffers */
+ mptscsih_freeChainBuffers(ioc, ii);
+
+ /* Free Message frames */
+ mpt_free_msg_frame(ioc, mf);
+
+ if ((unsigned char *)mf != SCpnt->host_scribble)
+ continue;
+
/* Set status, free OS resources (SG DMA buffers)
* Do OS callback
- * Free driver resources (chain, msg buffers)
*/
if (SCpnt->use_sg) {
pci_unmap_sg(ioc->pcidev,
@@ -845,12 +915,6 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
SCpnt->result = DID_RESET << 16;
SCpnt->host_scribble = NULL;
- /* Free Chain buffers */
- mptscsih_freeChainBuffers(ioc, ii);
-
- /* Free Message frames */
- mpt_free_msg_frame(ioc, mf);
-
SCpnt->scsi_done(SCpnt); /* Issue the command callback */
}
}
@@ -887,10 +951,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
if ((sc = hd->ScsiLookup[ii]) != NULL) {
mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
-
+ if (mf == NULL)
+ continue;
dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
-
if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
continue;
@@ -899,6 +963,8 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
hd->ScsiLookup[ii] = NULL;
mptscsih_freeChainBuffers(hd->ioc, ii);
mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
+ if ((unsigned char *)mf != sc->host_scribble)
+ continue;
if (sc->use_sg) {
pci_unmap_sg(hd->ioc->pcidev,
(struct scatterlist *) sc->request_buffer,
@@ -1341,8 +1407,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
goto fail;
}
+ SCpnt->host_scribble = (unsigned char *)mf;
hd->ScsiLookup[my_idx] = SCpnt;
- SCpnt->host_scribble = NULL;
mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
@@ -1529,6 +1595,12 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
}
+ /*
+ * Check IOCStatus from TM reply message
+ */
+ if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS)
+ rc = FAILED;
+
dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
return rc;
@@ -1654,6 +1726,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
int scpnt_idx;
int retval;
VirtDevice *vdev;
+ ulong sn = SCpnt->serial_number;
/* If we can't locate our host adapter structure, return FAILED status.
*/
@@ -1707,6 +1780,11 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
+ if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
+ SCpnt->serial_number == sn) {
+ retval = FAILED;
+ }
+
printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
hd->ioc->name,
((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
@@ -2023,6 +2101,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
+ hd->tm_iocstatus = iocstatus;
dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
/* Error? (anything non-zero?) */
@@ -2401,6 +2480,13 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
ioc->eventContext++;
+ if (hd->ioc->pcidev->vendor ==
+ PCI_VENDOR_ID_IBM) {
+ mptscsih_issue_sep_command(hd->ioc,
+ vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
+ vdev->vtarget->tflags |=
+ MPT_TARGET_FLAGS_LED_ON;
+ }
}
}
} else {
@@ -2409,7 +2495,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
}
}
-static u32
+static int
SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
{
MPT_SCSI_HOST *hd;
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 3201de053943..e4cc3dd5fc9f 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -83,10 +83,6 @@ static int mpt_saf_te = MPTSCSIH_SAF_TE;
module_param(mpt_saf_te, int, 0);
MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)");
-static int mpt_pq_filter = 0;
-module_param(mpt_pq_filter, int, 0);
-MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
-
static void mptspi_write_offset(struct scsi_target *, int);
static void mptspi_write_width(struct scsi_target *, int);
static int mptspi_write_spi_device_pg1(struct scsi_target *,
@@ -775,9 +771,9 @@ static struct spi_function_template mptspi_transport_functions = {
*/
static struct pci_device_id mptspi_pci_table[] = {
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1030,
PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035,
+ { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1035,
PCI_ANY_ID, PCI_ANY_ID },
{0} /* Terminating entry */
};
@@ -1047,14 +1043,12 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hd->timer.function = mptscsih_timer_expired;
ioc->spi_data.Saf_Te = mpt_saf_te;
- hd->mpt_pq_filter = mpt_pq_filter;
hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
ddvprintk((MYIOC_s_INFO_FMT
- "saf_te %x mpt_pq_filter %x\n",
+ "saf_te %x\n",
ioc->name,
- mpt_saf_te,
- mpt_pq_filter));
+ mpt_saf_te));
ioc->spi_data.noQas = 0;
init_waitqueue_head(&hd->scandv_waitq);