diff options
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r-- | drivers/scsi/mpt2sas/Kconfig | 2 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2.h | 12 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h | 29 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_init.h | 8 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_ioc.h | 74 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_raid.h | 8 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_sas.h | 2 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_tool.h | 44 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpi/mpi2_type.h | 2 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 328 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 28 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_config.c | 2 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.c | 2 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.h | 2 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_debug.h | 2 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 197 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_transport.c | 2 |
17 files changed, 551 insertions, 193 deletions
diff --git a/drivers/scsi/mpt2sas/Kconfig b/drivers/scsi/mpt2sas/Kconfig index 39f08dd2055..657b45ca04c 100644 --- a/drivers/scsi/mpt2sas/Kconfig +++ b/drivers/scsi/mpt2sas/Kconfig @@ -2,7 +2,7 @@ # Kernel configuration file for the MPT2SAS # # This code is based on drivers/scsi/mpt2sas/Kconfig -# Copyright (C) 2007-2012 LSI Corporation +# Copyright (C) 2007-2014 LSI Corporation # (mailto:DL-MPTFusionLinux@lsi.com) # This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h index 7b14a015c90..088eefa67da 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2013 LSI Corporation. + * Copyright (c) 2000-2014 LSI Corporation. * * * Name: mpi2.h @@ -8,7 +8,7 @@ * scatter/gather formats. * Creation Date: June 21, 2006 * - * mpi2.h Version: 02.00.28 + * mpi2.h Version: 02.00.32 * * Version History * --------------- @@ -78,6 +78,11 @@ * 07-10-12 02.00.26 Bumped MPI2_HEADER_VERSION_UNIT. * 07-26-12 02.00.27 Bumped MPI2_HEADER_VERSION_UNIT. * 11-27-12 02.00.28 Bumped MPI2_HEADER_VERSION_UNIT. + * 12-20-12 02.00.29 Bumped MPI2_HEADER_VERSION_UNIT. + * Added MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET. + * 04-09-13 02.00.30 Bumped MPI2_HEADER_VERSION_UNIT. + * 04-17-13 02.00.31 Bumped MPI2_HEADER_VERSION_UNIT. + * 08-19-13 02.00.32 Bumped MPI2_HEADER_VERSION_UNIT. * -------------------------------------------------------------------------- */ @@ -103,7 +108,7 @@ #define MPI2_VERSION_02_00 (0x0200) /* versioning for this MPI header set */ -#define MPI2_HEADER_VERSION_UNIT (0x1C) +#define MPI2_HEADER_VERSION_UNIT (0x20) #define MPI2_HEADER_VERSION_DEV (0x00) #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) @@ -263,6 +268,7 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS #define MPI2_REPLY_POST_HOST_INDEX_MASK (0x00FFFFFF) #define MPI2_RPHI_MSIX_INDEX_MASK (0xFF000000) #define MPI2_RPHI_MSIX_INDEX_SHIFT (24) +#define MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET (0x0000030C) /* MPI v2.5 only */ /* * Defines for the HCBSize and address diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h index 88cb7f828bb..510ef0dc8d7 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2013 LSI Corporation. + * Copyright (c) 2000-2014 LSI Corporation. * * * Name: mpi2_cnfg.h * Title: MPI Configuration messages and pages * Creation Date: November 10, 2006 * - * mpi2_cnfg.h Version: 02.00.23 + * mpi2_cnfg.h Version: 02.00.26 * * Version History * --------------- @@ -150,7 +150,13 @@ * Added UEFIVersion field to BIOS Page 1 and defined new * BiosOptions bits. * 11-27-12 02.00.23 Added MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER. - * Added MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID. + * Added MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID. + * 12-20-12 02.00.24 Marked MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION as + * obsolete for MPI v2.5 and later. + * Added some defines for 12G SAS speeds. + * 04-09-13 02.00.25 Added MPI2_IOUNITPAGE1_ATA_SECURITY_FREEZE_LOCK. + * Fixed MPI2_IOUNITPAGE5_DMA_CAP_MASK_MAX_REQUESTS to + * match the specification. * -------------------------------------------------------------------------- */ @@ -773,6 +779,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1 #define MPI2_IOUNITPAGE1_PAGEVERSION (0x04) /* IO Unit Page 1 Flags defines */ +#define MPI2_IOUNITPAGE1_ATA_SECURITY_FREEZE_LOCK (0x00004000) #define MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY (0x00000800) #define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE (0x00000600) #define MPI2_IOUNITPAGE1_SATA_WRITE_CACHE_SHIFT (9) @@ -844,7 +851,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_5 { #define MPI2_IOUNITPAGE5_PAGEVERSION (0x00) /* defines for IO Unit Page 5 DmaEngineCapabilities field */ -#define MPI2_IOUNITPAGE5_DMA_CAP_MASK_MAX_REQUESTS (0xFF00) +#define MPI2_IOUNITPAGE5_DMA_CAP_MASK_MAX_REQUESTS (0xFFFF0000) #define MPI2_IOUNITPAGE5_DMA_CAP_SHIFT_MAX_REQUESTS (16) #define MPI2_IOUNITPAGE5_DMA_CAP_EEDP (0x0008) @@ -885,13 +892,17 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 { U16 IOCTemperature; /* 0x10 */ U8 IOCTemperatureUnits; /* 0x12 */ U8 IOCSpeed; /* 0x13 */ - U16 BoardTemperature; /* 0x14 */ - U8 BoardTemperatureUnits; /* 0x16 */ - U8 Reserved3; /* 0x17 */ + U16 BoardTemperature; /* 0x14 */ + U8 BoardTemperatureUnits; /* 0x16 */ + U8 Reserved3; /* 0x17 */ + U32 Reserved4; /* 0x18 */ + U32 Reserved5; /* 0x1C */ + U32 Reserved6; /* 0x20 */ + U32 Reserved7; /* 0x24 */ } MPI2_CONFIG_PAGE_IO_UNIT_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_7, Mpi2IOUnitPage7_t, MPI2_POINTER pMpi2IOUnitPage7_t; -#define MPI2_IOUNITPAGE7_PAGEVERSION (0x02) +#define MPI2_IOUNITPAGE7_PAGEVERSION (0x04) /* defines for IO Unit Page 7 PCIeWidth field */ #define MPI2_IOUNITPAGE7_PCIE_WIDTH_X1 (0x01) @@ -1801,6 +1812,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 #define MPI2_SAS_PRATE_MAX_RATE_1_5 (0x80) #define MPI2_SAS_PRATE_MAX_RATE_3_0 (0x90) #define MPI2_SAS_PRATE_MAX_RATE_6_0 (0xA0) +#define MPI25_SAS_PRATE_MAX_RATE_12_0 (0xB0) #define MPI2_SAS_PRATE_MIN_RATE_MASK (0x0F) #define MPI2_SAS_PRATE_MIN_RATE_NOT_PROGRAMMABLE (0x00) #define MPI2_SAS_PRATE_MIN_RATE_1_5 (0x08) @@ -1813,6 +1825,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 #define MPI2_SAS_HWRATE_MAX_RATE_1_5 (0x80) #define MPI2_SAS_HWRATE_MAX_RATE_3_0 (0x90) #define MPI2_SAS_HWRATE_MAX_RATE_6_0 (0xA0) +#define MPI25_SAS_HWRATE_MAX_RATE_12_0 (0xB0) #define MPI2_SAS_HWRATE_MIN_RATE_MASK (0x0F) #define MPI2_SAS_HWRATE_MIN_RATE_1_5 (0x08) #define MPI2_SAS_HWRATE_MIN_RATE_3_0 (0x09) diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h index 9d284dae655..eea1a16b13e 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_init.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_init.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2013 LSI Corporation. + * Copyright (c) 2000-2014 LSI Corporation. * * * Name: mpi2_init.h * Title: MPI SCSI initiator mode messages and structures * Creation Date: June 23, 2006 * - * mpi2_init.h Version: 02.00.14 + * mpi2_init.h Version: 02.00.15 * * Version History * --------------- @@ -37,6 +37,8 @@ * 02-06-12 02.00.13 Added alternate defines for Task Priority / Command * Priority to match SAM-4. * 07-10-12 02.00.14 Added MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION. + * 04-09-13 02.00.15 Added SCSIStatusQualifier field to MPI2_SCSI_IO_REPLY, + * replacing the Reserved4 field. * -------------------------------------------------------------------------- */ @@ -234,7 +236,7 @@ typedef struct _MPI2_SCSI_IO_REPLY U32 SenseCount; /* 0x18 */ U32 ResponseInfo; /* 0x1C */ U16 TaskTag; /* 0x20 */ - U16 Reserved4; /* 0x22 */ + U16 SCSIStatusQualifier; /* 0x22 */ U32 BidirectionalTransferCount; /* 0x24 */ U32 Reserved5; /* 0x28 */ U32 Reserved6; /* 0x2C */ diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h index d159c5f24aa..2c3b0f28576 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2013 LSI Corporation. + * Copyright (c) 2000-2014 LSI Corporation. * * * Name: mpi2_ioc.h * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages * Creation Date: October 11, 2006 * - * mpi2_ioc.h Version: 02.00.22 + * mpi2_ioc.h Version: 02.00.23 * * Version History * --------------- @@ -121,6 +121,11 @@ * 07-26-12 02.00.22 Added MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE. * Added ElapsedSeconds field to * MPI2_EVENT_DATA_IR_OPERATION_STATUS. + * 08-19-13 02.00.23 For IOCInit, added MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE + * and MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY. + * Added MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE. + * Added MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY. + * Added Encrypted Hash Extended Image. * -------------------------------------------------------------------------- */ @@ -177,6 +182,9 @@ typedef struct _MPI2_IOC_INIT_REQUEST #define MPI2_WHOINIT_HOST_DRIVER (0x04) #define MPI2_WHOINIT_MANUFACTURER (0x05) +/* MsgFlags */ +#define MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE (0x01) + /* MsgVersion */ #define MPI2_IOCINIT_MSGVERSION_MAJOR_MASK (0xFF00) #define MPI2_IOCINIT_MSGVERSION_MAJOR_SHIFT (8) @@ -189,9 +197,17 @@ typedef struct _MPI2_IOC_INIT_REQUEST #define MPI2_IOCINIT_HDRVERSION_DEV_MASK (0x00FF) #define MPI2_IOCINIT_HDRVERSION_DEV_SHIFT (0) -/* minimum depth for the Reply Descriptor Post Queue */ +/* minimum depth for a Reply Descriptor Post Queue */ #define MPI2_RDPQ_DEPTH_MIN (16) +/* Reply Descriptor Post Queue Array Entry */ +typedef struct _MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY { + U64 RDPQBaseAddress; /* 0x00 */ + U32 Reserved1; /* 0x08 */ + U32 Reserved2; /* 0x0C */ +} MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY, +MPI2_POINTER PTR_MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY, +Mpi2IOCInitRDPQArrayEntry, MPI2_POINTER pMpi2IOCInitRDPQArrayEntry; /* IOCInit Reply message */ typedef struct _MPI2_IOC_INIT_REPLY @@ -307,6 +323,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY /* ProductID field uses MPI2_FW_HEADER_PID_ */ /* IOCCapabilities */ +#define MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE (0x00040000) #define MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY (0x00010000) #define MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX (0x00008000) #define MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR (0x00004000) @@ -1153,6 +1170,7 @@ typedef struct _MPI2_FW_DOWNLOAD_REQUEST #define MPI2_FW_DOWNLOAD_ITYPE_MEGARAID (0x09) #define MPI2_FW_DOWNLOAD_ITYPE_COMPLETE (0x0A) #define MPI2_FW_DOWNLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B) +#define MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY (0x0C) #define MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC (0xF0) /* FWDownload TransactionContext Element */ @@ -1379,14 +1397,15 @@ typedef struct _MPI2_EXT_IMAGE_HEADER #define MPI2_EXT_IMAGE_HEADER_SIZE (0x40) /* defines for the ImageType field */ -#define MPI2_EXT_IMAGE_TYPE_UNSPECIFIED (0x00) -#define MPI2_EXT_IMAGE_TYPE_FW (0x01) -#define MPI2_EXT_IMAGE_TYPE_NVDATA (0x03) -#define MPI2_EXT_IMAGE_TYPE_BOOTLOADER (0x04) -#define MPI2_EXT_IMAGE_TYPE_INITIALIZATION (0x05) -#define MPI2_EXT_IMAGE_TYPE_FLASH_LAYOUT (0x06) -#define MPI2_EXT_IMAGE_TYPE_SUPPORTED_DEVICES (0x07) -#define MPI2_EXT_IMAGE_TYPE_MEGARAID (0x08) +#define MPI2_EXT_IMAGE_TYPE_UNSPECIFIED (0x00) +#define MPI2_EXT_IMAGE_TYPE_FW (0x01) +#define MPI2_EXT_IMAGE_TYPE_NVDATA (0x03) +#define MPI2_EXT_IMAGE_TYPE_BOOTLOADER (0x04) +#define MPI2_EXT_IMAGE_TYPE_INITIALIZATION (0x05) +#define MPI2_EXT_IMAGE_TYPE_FLASH_LAYOUT (0x06) +#define MPI2_EXT_IMAGE_TYPE_SUPPORTED_DEVICES (0x07) +#define MPI2_EXT_IMAGE_TYPE_MEGARAID (0x08) +#define MPI2_EXT_IMAGE_TYPE_ENCRYPTED_HASH (0x09) #define MPI2_EXT_IMAGE_TYPE_MIN_PRODUCT_SPECIFIC (0x80) #define MPI2_EXT_IMAGE_TYPE_MAX_PRODUCT_SPECIFIC (0xFF) #define MPI2_EXT_IMAGE_TYPE_MAX \ @@ -1555,6 +1574,39 @@ typedef struct _MPI2_INIT_IMAGE_FOOTER #define MPI2_INIT_IMAGE_RESETVECTOR_OFFSET (0x14) +/* Encrypted Hash Extended Image Data */ + +typedef struct _MPI25_ENCRYPTED_HASH_ENTRY { + U8 HashImageType; /* 0x00 */ + U8 HashAlgorithm; /* 0x01 */ + U8 EncryptionAlgorithm; /* 0x02 */ + U8 Reserved1; /* 0x03 */ + U32 Reserved2; /* 0x04 */ + U32 EncryptedHash[1]; /* 0x08 */ +} MPI25_ENCRYPTED_HASH_ENTRY, MPI2_POINTER PTR_MPI25_ENCRYPTED_HASH_ENTRY, +Mpi25EncryptedHashEntry_t, MPI2_POINTER pMpi25EncryptedHashEntry_t; + +/* values for HashImageType */ +#define MPI25_HASH_IMAGE_TYPE_UNUSED (0x00) +#define MPI25_HASH_IMAGE_TYPE_FIRMWARE (0x01) + +/* values for HashAlgorithm */ +#define MPI25_HASH_ALGORITHM_UNUSED (0x00) +#define MPI25_HASH_ALGORITHM_SHA256 (0x01) + +/* values for EncryptionAlgorithm */ +#define MPI25_ENCRYPTION_ALG_UNUSED (0x00) +#define MPI25_ENCRYPTION_ALG_RSA256 (0x01) + +typedef struct _MPI25_ENCRYPTED_HASH_DATA { + U8 ImageVersion; /* 0x00 */ + U8 NumHash; /* 0x01 */ + U16 Reserved1; /* 0x02 */ + U32 Reserved2; /* 0x04 */ + MPI25_ENCRYPTED_HASH_ENTRY EncryptedHashEntry[1]; /* 0x08 */ +} MPI25_ENCRYPTED_HASH_DATA, MPI2_POINTER PTR_MPI25_ENCRYPTED_HASH_DATA, +Mpi25EncryptedHashData_t, MPI2_POINTER pMpi25EncryptedHashData_t; + /**************************************************************************** * PowerManagementControl message ****************************************************************************/ diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h index 0d202a2c6db..7efa58ff0d3 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2013 LSI Corporation. + * Copyright (c) 2000-2014 LSI Corporation. * * * Name: mpi2_raid.h * Title: MPI Integrated RAID messages and structures * Creation Date: April 26, 2007 * - * mpi2_raid.h Version: 02.00.09 + * mpi2_raid.h Version: 02.00.10 * * Version History * --------------- @@ -29,6 +29,7 @@ * 02-06-12 02.00.08 Added MPI2_RAID_ACTION_PHYSDISK_HIDDEN. * 07-26-12 02.00.09 Added ElapsedSeconds field to MPI2_RAID_VOL_INDICATOR. * Added MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID define. + * 04-17-13 02.00.10 Added MPI25_RAID_ACTION_ADATA_ALLOW_PI. * -------------------------------------------------------------------------- */ @@ -45,6 +46,9 @@ * RAID Action messages ****************************************************************************/ +/* ActionDataWord defines for use with MPI2_RAID_ACTION_CREATE_VOLUME action */ +#define MPI25_RAID_ACTION_ADATA_ALLOW_PI (0x80000000) + /* ActionDataWord defines for use with MPI2_RAID_ACTION_DELETE_VOLUME action */ #define MPI2_RAID_ACTION_ADATA_KEEP_LBA0 (0x00000000) #define MPI2_RAID_ACTION_ADATA_ZERO_LBA0 (0x00000001) diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_sas.h b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h index 50b39ccd526..45b6fa10b80 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_sas.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2013 LSI Corporation. + * Copyright (c) 2000-2014 LSI Corporation. * * * Name: mpi2_sas.h diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h index 11b2ac4e7c6..9be03ed4618 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2013 LSI Corporation. + * Copyright (c) 2000-2014 LSI Corporation. * * * Name: mpi2_tool.h * Title: MPI diagnostic tool structures and definitions * Creation Date: March 26, 2007 * - * mpi2_tool.h Version: 02.00.10 + * mpi2_tool.h Version: 02.00.11 * * Version History * --------------- @@ -29,6 +29,7 @@ * MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST. * 07-26-12 02.00.10 Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that * it uses MPI Chain SGE as well as MPI Simple SGE. + * 08-19-13 02.00.11 Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info. * -------------------------------------------------------------------------- */ @@ -48,6 +49,7 @@ #define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03) #define MPI2_TOOLBOX_BEACON_TOOL (0x05) #define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL (0x06) +#define MPI2_TOOLBOX_TEXT_DISPLAY_TOOL (0x07) /**************************************************************************** @@ -321,6 +323,44 @@ typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY { MPI2_POINTER pMpi2ToolboxDiagnosticCliReply_t; +/**************************************************************************** +* Toolbox Console Text Display Tool +****************************************************************************/ + +/* Toolbox Console Text Display Tool request message */ +typedef struct _MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST { + U8 Tool; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U8 ChainOffset; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 Reserved2; /* 0x04 */ + U8 Reserved3; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved4; /* 0x0A */ + U8 Console; /* 0x0C */ + U8 Flags; /* 0x0D */ + U16 Reserved6; /* 0x0E */ + U8 TextToDisplay[4]; /* 0x10 */ +} MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST, +MPI2_POINTER PTR_MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST, +Mpi2ToolboxTextDisplayRequest_t, +MPI2_POINTER pMpi2ToolboxTextDisplayRequest_t; + +/* defines for the Console field */ +#define MPI2_TOOLBOX_CONSOLE_TYPE_MASK (0xF0) +#define MPI2_TOOLBOX_CONSOLE_TYPE_DEFAULT (0x00) +#define MPI2_TOOLBOX_CONSOLE_TYPE_UART (0x10) +#define MPI2_TOOLBOX_CONSOLE_TYPE_ETHERNET (0x20) + +#define MPI2_TOOLBOX_CONSOLE_NUMBER_MASK (0x0F) + +/* defines for the Flags field */ +#define MPI2_TOOLBOX_CONSOLE_FLAG_TIMESTAMP (0x01) + + + /***************************************************************************** * * Diagnostic Buffer Messages diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_type.h b/drivers/scsi/mpt2sas/mpi/mpi2_type.h index 0b128b68a5e..6b0dcdd02f6 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_type.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_type.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2013 LSI Corporation. + * Copyright (c) 2000-2014 LSI Corporation. * * * Name: mpi2_type.h diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 2f262be890c..58e45216d1e 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -3,7 +3,7 @@ * for access to MPT (Message Passing Technology) firmware. * * This code is based on drivers/scsi/mpt2sas/mpt2_base.c - * Copyright (C) 2007-2013 LSI Corporation + * Copyright (C) 2007-2014 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or @@ -80,6 +80,10 @@ static int msix_disable = -1; module_param(msix_disable, int, 0); MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); +static int max_msix_vectors = -1; +module_param(max_msix_vectors, int, 0); +MODULE_PARM_DESC(max_msix_vectors, " max msix vectors "); + static int mpt2sas_fwfault_debug; MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " "and halt firmware - (default=0)"); @@ -88,6 +92,12 @@ static int disable_discovery = -1; module_param(disable_discovery, int, 0); MODULE_PARM_DESC(disable_discovery, " disable discovery "); +static int +_base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag); + +static int +_base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag); + /** * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. * @@ -1175,17 +1185,22 @@ static int _base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev) { struct sysinfo s; - char *desc = NULL; + u64 consistent_dma_mask; + + if (ioc->dma_mask) + consistent_dma_mask = DMA_BIT_MASK(64); + else + consistent_dma_mask = DMA_BIT_MASK(32); if (sizeof(dma_addr_t) > 4) { const uint64_t required_mask = dma_get_required_mask(&pdev->dev); - if ((required_mask > DMA_BIT_MASK(32)) && !pci_set_dma_mask(pdev, - DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(pdev, - DMA_BIT_MASK(64))) { + if ((required_mask > DMA_BIT_MASK(32)) && + !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && + !pci_set_consistent_dma_mask(pdev, consistent_dma_mask)) { ioc->base_add_sg_single = &_base_add_sg_single_64; ioc->sge_size = sizeof(Mpi2SGESimple64_t); - desc = "64"; + ioc->dma_mask = 64; goto out; } } @@ -1194,18 +1209,29 @@ _base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev) && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { ioc->base_add_sg_single = &_base_add_sg_single_32; ioc->sge_size = sizeof(Mpi2SGESimple32_t); - desc = "32"; + ioc->dma_mask = 32; } else return -ENODEV; out: si_meminfo(&s); - printk(MPT2SAS_INFO_FMT "%s BIT PCI BUS DMA ADDRESSING SUPPORTED, " - "total mem (%ld kB)\n", ioc->name, desc, convert_to_kb(s.totalram)); + printk(MPT2SAS_INFO_FMT + "%d BIT PCI BUS DMA ADDRESSING SUPPORTED, total mem (%ld kB)\n", + ioc->name, ioc->dma_mask, convert_to_kb(s.totalram)); return 0; } +static int +_base_change_consistent_dma_mask(struct MPT2SAS_ADAPTER *ioc, + struct pci_dev *pdev) +{ + if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { + if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) + return -ENODEV; + } + return 0; +} /** * _base_check_enable_msix - checks MSIX capabable. * @ioc: per adapter object @@ -1402,6 +1428,20 @@ _base_enable_msix(struct MPT2SAS_ADAPTER *ioc) ioc->reply_queue_count = min_t(int, ioc->cpu_count, ioc->msix_vector_count); + if (!ioc->rdpq_array_enable && max_msix_vectors == -1) + max_msix_vectors = 8; + + if (max_msix_vectors > 0) { + ioc->reply_queue_count = min_t(int, max_msix_vectors, + ioc->reply_queue_count); + ioc->msix_vector_count = ioc->reply_queue_count; + } else if (max_msix_vectors == 0) + goto try_ioapic; + + printk(MPT2SAS_INFO_FMT + "MSI-X vectors supported: %d, no of cores: %d, max_msix_vectors: %d\n", + ioc->name, ioc->msix_vector_count, ioc->cpu_count, max_msix_vectors); + entries = kcalloc(ioc->reply_queue_count, sizeof(struct msix_entry), GFP_KERNEL); if (!entries) { @@ -1414,10 +1454,10 @@ _base_enable_msix(struct MPT2SAS_ADAPTER *ioc) for (i = 0, a = entries; i < ioc->reply_queue_count; i++, a++) a->entry = i; - r = pci_enable_msix(ioc->pdev, entries, ioc->reply_queue_count); + r = pci_enable_msix_exact(ioc->pdev, entries, ioc->reply_queue_count); if (r) { - dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "pci_enable_msix " - "failed (r=%d) !!!\n", ioc->name, r)); + dfailprintk(ioc, printk(MPT2SAS_INFO_FMT + "pci_enable_msix_exact failed (r=%d) !!!\n", ioc->name, r)); kfree(entries); goto try_ioapic; } @@ -1439,6 +1479,7 @@ _base_enable_msix(struct MPT2SAS_ADAPTER *ioc) /* failback to io_apic interrupt routing */ try_ioapic: + ioc->reply_queue_count = 1; r = _base_request_irq(ioc, 0, ioc->pdev->irq); return r; @@ -1520,6 +1561,16 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) } _base_mask_interrupts(ioc); + + r = _base_get_ioc_facts(ioc, CAN_SLEEP); + if (r) + goto out_fail; + + if (!ioc->rdpq_array_enable_assigned) { + ioc->rdpq_array_enable = ioc->rdpq_array_capable; + ioc->rdpq_array_enable_assigned = 1; + } + r = _base_enable_msix(ioc); if (r) goto out_fail; @@ -2317,7 +2368,8 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc) static void _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) { - int i; + int i = 0; + struct reply_post_struct *rps; dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__)); @@ -2358,15 +2410,25 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) ioc->reply_free = NULL; } - if (ioc->reply_post_free) { - pci_pool_free(ioc->reply_post_free_dma_pool, - ioc->reply_post_free, ioc->reply_post_free_dma); + if (ioc->reply_post) { + do { + rps = &ioc->reply_post[i]; + if (rps->reply_post_free) { + pci_pool_free( + ioc->reply_post_free_dma_pool, + rps->reply_post_free, + rps->reply_post_free_dma); + dexitprintk(ioc, printk(MPT2SAS_INFO_FMT + "reply_post_free_pool(0x%p): free\n", + ioc->name, rps->reply_post_free)); + rps->reply_post_free = NULL; + } + } while (ioc->rdpq_array_enable && + (++i < ioc->reply_queue_count)); + if (ioc->reply_post_free_dma_pool) pci_pool_destroy(ioc->reply_post_free_dma_pool); - dexitprintk(ioc, printk(MPT2SAS_INFO_FMT - "reply_post_free_pool(0x%p): free\n", ioc->name, - ioc->reply_post_free)); - ioc->reply_post_free = NULL; + kfree(ioc->reply_post); } if (ioc->config_page) { @@ -2509,6 +2571,65 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) ioc->max_sges_in_chain_message, ioc->shost->sg_tablesize, ioc->chains_needed_per_io)); + /* reply post queue, 16 byte align */ + reply_post_free_sz = ioc->reply_post_queue_depth * + sizeof(Mpi2DefaultReplyDescriptor_t); + + sz = reply_post_free_sz; + if (_base_is_controller_msix_enabled(ioc) && !ioc->rdpq_array_enable) + sz *= ioc->reply_queue_count; + + ioc->reply_post = kcalloc((ioc->rdpq_array_enable) ? + (ioc->reply_queue_count):1, + sizeof(struct reply_post_struct), GFP_KERNEL); + + if (!ioc->reply_post) { + printk(MPT2SAS_ERR_FMT "reply_post_free pool: kcalloc failed\n", + ioc->name); + goto out; + } + ioc->reply_post_free_dma_pool = pci_pool_create("reply_post_free pool", + ioc->pdev, sz, 16, 0); + if (!ioc->reply_post_free_dma_pool) { + printk(MPT2SAS_ERR_FMT + "reply_post_free pool: pci_pool_create failed\n", + ioc->name); + goto out; + } + i = 0; + do { + ioc->reply_post[i].reply_post_free = + pci_pool_alloc(ioc->reply_post_free_dma_pool, + GFP_KERNEL, + &ioc->reply_post[i].reply_post_free_dma); + if (!ioc->reply_post[i].reply_post_free) { + printk(MPT2SAS_ERR_FMT + "reply_post_free pool: pci_pool_alloc failed\n", + ioc->name); + goto out; + } + memset(ioc->reply_post[i].reply_post_free, 0, sz); + dinitprintk(ioc, printk(MPT2SAS_INFO_FMT + "reply post free pool (0x%p): depth(%d)," + "element_size(%d), pool_size(%d kB)\n", ioc->name, + ioc->reply_post[i].reply_post_free, + ioc->reply_post_queue_depth, 8, sz/1024)); + dinitprintk(ioc, printk(MPT2SAS_INFO_FMT + "reply_post_free_dma = (0x%llx)\n", ioc->name, + (unsigned long long) + ioc->reply_post[i].reply_post_free_dma)); + total_sz += sz; + } while (ioc->rdpq_array_enable && (++i < ioc->reply_queue_count)); + + if (ioc->dma_mask == 64) { + if (_base_change_consistent_dma_mask(ioc, ioc->pdev) != 0) { + printk(MPT2SAS_WARN_FMT + "no suitable consistent DMA mask for %s\n", + ioc->name, pci_name(ioc->pdev)); + goto out; + } + } + ioc->scsiio_depth = ioc->hba_queue_depth - ioc->hi_priority_depth - ioc->internal_depth; @@ -2720,37 +2841,6 @@ chain_done: "(0x%llx)\n", ioc->name, (unsigned long long)ioc->reply_free_dma)); total_sz += sz; - /* reply post queue, 16 byte align */ - reply_post_free_sz = ioc->reply_post_queue_depth * - sizeof(Mpi2DefaultReplyDescriptor_t); - if (_base_is_controller_msix_enabled(ioc)) - sz = reply_post_free_sz * ioc->reply_queue_count; - else - sz = reply_post_free_sz; - ioc->reply_post_free_dma_pool = pci_pool_create("reply_post_free pool", - ioc->pdev, sz, 16, 0); - if (!ioc->reply_post_free_dma_pool) { - printk(MPT2SAS_ERR_FMT "reply_post_free pool: pci_pool_create " - "failed\n", ioc->name); - goto out; - } - ioc->reply_post_free = pci_pool_alloc(ioc->reply_post_free_dma_pool , - GFP_KERNEL, &ioc->reply_post_free_dma); - if (!ioc->reply_post_free) { - printk(MPT2SAS_ERR_FMT "reply_post_free pool: pci_pool_alloc " - "failed\n", ioc->name); - goto out; - } - memset(ioc->reply_post_free, 0, sz); - dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply post free pool" - "(0x%p): depth(%d), element_size(%d), pool_size(%d kB)\n", - ioc->name, ioc->reply_post_free, ioc->reply_post_queue_depth, 8, - sz/1024)); - dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply_post_free_dma = " - "(0x%llx)\n", ioc->name, (unsigned long long) - ioc->reply_post_free_dma)); - total_sz += sz; - ioc->config_page_sz = 512; ioc->config_page = pci_alloc_consistent(ioc->pdev, ioc->config_page_sz, &ioc->config_page_dma); @@ -3374,6 +3464,64 @@ _base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag) } /** + * _base_wait_for_iocstate - Wait until the card is in READY or OPERATIONAL + * @ioc: per adapter object + * @timeout: + * @sleep_flag: CAN_SLEEP or NO_SLEEP + * + * Returns 0 for success, non-zero for failure. + */ +static int +_base_wait_for_iocstate(struct MPT2SAS_ADAPTER *ioc, int timeout, + int sleep_flag) +{ + u32 ioc_state, doorbell; + int rc; + + dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, + __func__)); + + if (ioc->pci_error_recovery) + return 0; + + doorbell = mpt2sas_base_get_iocstate(ioc, 0); + ioc_state = doorbell & MPI2_IOC_STATE_MASK; + dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: ioc_state(0x%08x)\n", + ioc->name, __func__, ioc_state)); + + switch (ioc_state) { + case MPI2_IOC_STATE_READY: + case MPI2_IOC_STATE_OPERATIONAL: + return 0; + } + + if (doorbell & MPI2_DOORBELL_USED) { + dhsprintk(ioc, printk(MPT2SAS_INFO_FMT + "unexpected doorbell activ!e\n", ioc->name)); + goto issue_diag_reset; + } + + if (ioc_state == MPI2_IOC_STATE_FAULT) { + mpt2sas_base_fault_info(ioc, doorbell & + MPI2_DOORBELL_DATA_MASK); + goto issue_diag_reset; + } + + ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, + timeout, sleep_flag); + if (ioc_state) { + printk(MPT2SAS_ERR_FMT + "%s: failed going to ready state (ioc_state=0x%x)\n", + ioc->name, __func__, ioc_state); + return -EFAULT; + } + + issue_diag_reset: + rc = _base_diag_reset(ioc, sleep_flag); + return rc; +} + +/** * _base_get_ioc_facts - obtain ioc facts reply and save in ioc * @ioc: per adapter object * @sleep_flag: CAN_SLEEP or NO_SLEEP @@ -3391,6 +3539,13 @@ _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__)); + r = _base_wait_for_iocstate(ioc, 10, sleep_flag); + if (r) { + printk(MPT2SAS_ERR_FMT "%s: failed getting to correct state\n", + ioc->name, __func__); + return r; + } + mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t); mpi_request_sz = sizeof(Mpi2IOCFactsRequest_t); memset(&mpi_request, 0, mpi_request_sz); @@ -3422,6 +3577,9 @@ _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) facts->IOCCapabilities = le32_to_cpu(mpi_reply.IOCCapabilities); if ((facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID)) ioc->ir_firmware = 1; + if ((facts->IOCCapabilities & + MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE)) + ioc->rdpq_array_capable = 1; facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word); facts->IOCRequestFrameSize = le16_to_cpu(mpi_reply.IOCRequestFrameSize); @@ -3457,9 +3615,12 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) { Mpi2IOCInitRequest_t mpi_request; Mpi2IOCInitReply_t mpi_reply; - int r; + int i, r = 0; struct timeval current_time; u16 ioc_status; + u32 reply_post_free_array_sz = 0; + Mpi2IOCInitRDPQArrayEntry *reply_post_free_array = NULL; + dma_addr_t reply_post_free_array_dma; dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__)); @@ -3488,9 +3649,31 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) cpu_to_le64((u64)ioc->request_dma); mpi_request.ReplyFreeQueueAddress = cpu_to_le64((u64)ioc->reply_free_dma); - mpi_request.ReplyDescriptorPostQueueAddress = - cpu_to_le64((u64)ioc->reply_post_free_dma); + if (ioc->rdpq_array_enable) { + reply_post_free_array_sz = ioc->reply_queue_count * + sizeof(Mpi2IOCInitRDPQArrayEntry); + reply_post_free_array = pci_alloc_consistent(ioc->pdev, + reply_post_free_array_sz, &reply_post_free_array_dma); + if (!reply_post_free_array) { + printk(MPT2SAS_ERR_FMT + "reply_post_free_array: pci_alloc_consistent failed\n", + ioc->name); + r = -ENOMEM; + goto out; + } + memset(reply_post_free_array, 0, reply_post_free_array_sz); + for (i = 0; i < ioc->reply_queue_count; i++) + reply_post_free_array[i].RDPQBaseAddress = + cpu_to_le64( + (u64)ioc->reply_post[i].reply_post_free_dma); + mpi_request.MsgFlags = MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE; + mpi_request.ReplyDescriptorPostQueueAddress = + cpu_to_le64((u64)reply_post_free_array_dma); + } else { + mpi_request.ReplyDescriptorPostQueueAddress = + cpu_to_le64((u64)ioc->reply_post[0].reply_post_free_dma); + } /* This time stamp specifies number of milliseconds * since epoch ~ midnight January 1, 1970. @@ -3518,7 +3701,7 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) if (r != 0) { printk(MPT2SAS_ERR_FMT "%s: handshake failed (r=%d)\n", ioc->name, __func__, r); - return r; + goto out; } ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; @@ -3528,7 +3711,12 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) r = -EIO; } - return 0; +out: + if (reply_post_free_array) + pci_free_consistent(ioc->pdev, reply_post_free_array_sz, + reply_post_free_array, + reply_post_free_array_dma); + return r; } /** @@ -4061,7 +4249,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) u8 hide_flag; struct adapter_reply_queue *reply_q; long reply_post_free; - u32 reply_post_free_sz; + u32 reply_post_free_sz, index = 0; dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__)); @@ -4132,19 +4320,27 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) _base_assign_reply_queues(ioc); /* initialize Reply Post Free Queue */ - reply_post_free = (long)ioc->reply_post_free; reply_post_free_sz = ioc->reply_post_queue_depth * sizeof(Mpi2DefaultReplyDescriptor_t); + reply_post_free = (long)ioc->reply_post[index].reply_post_free; list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { reply_q->reply_post_host_index = 0; reply_q->reply_post_free = (Mpi2ReplyDescriptorsUnion_t *) reply_post_free; for (i = 0; i < ioc->reply_post_queue_depth; i++) reply_q->reply_post_free[i].Words = - cpu_to_le64(ULLONG_MAX); + cpu_to_le64(ULLONG_MAX); if (!_base_is_controller_msix_enabled(ioc)) goto skip_init_reply_post_free_queue; - reply_post_free += reply_post_free_sz; + /* + * If RDPQ is enabled, switch to the next allocation. + * Otherwise advance within the contiguous region. + */ + if (ioc->rdpq_array_enable) + reply_post_free = (long) + ioc->reply_post[++index].reply_post_free; + else + reply_post_free += reply_post_free_sz; } skip_init_reply_post_free_queue: @@ -4272,6 +4468,8 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) } } + ioc->rdpq_array_enable_assigned = 0; + ioc->dma_mask = 0; r = mpt2sas_base_map_resources(ioc); if (r) goto out_free_resources; @@ -4633,6 +4831,16 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, r = -EFAULT; goto out; } + + r = _base_get_ioc_facts(ioc, CAN_SLEEP); + if (r) + goto out; + + if (ioc->rdpq_array_enable && !ioc->rdpq_array_capable) + panic("%s: Issue occurred with flashing controller firmware." + "Please reboot the system and ensure that the correct" + " firmware version is running\n", ioc->name); + r = _base_make_ioc_operational(ioc, sleep_flag); if (!r) _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 0ac5815a7f9..239f169b067 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h @@ -3,7 +3,7 @@ * for access to MPT (Message Passing Technology) firmware. * * This code is based on drivers/scsi/mpt2sas/mpt2_base.h - * Copyright (C) 2007-2013 LSI Corporation + * Copyright (C) 2007-2014 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or @@ -69,8 +69,8 @@ #define MPT2SAS_DRIVER_NAME "mpt2sas" #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" -#define MPT2SAS_DRIVER_VERSION "16.100.00.00" -#define MPT2SAS_MAJOR_VERSION 16 +#define MPT2SAS_DRIVER_VERSION "18.100.00.00" +#define MPT2SAS_MAJOR_VERSION 18 #define MPT2SAS_MINOR_VERSION 100 #define MPT2SAS_BUILD_VERSION 00 #define MPT2SAS_RELEASE_VERSION 00 @@ -355,6 +355,7 @@ struct _internal_cmd { * @slot: number number * @phy: phy identifier provided in sas device page 0 * @responding: used in _scsih_sas_device_mark_responding + * @pfa_led_on: flag for PFA LED status */ struct _sas_device { struct list_head list; @@ -373,6 +374,7 @@ struct _sas_device { u16 slot; u8 phy; u8 responding; + u8 pfa_led_on; }; /** @@ -634,6 +636,11 @@ struct mpt2sas_port_facts { u16 MaxPostedCmdBuffers; }; +struct reply_post_struct { + Mpi2ReplyDescriptorsUnion_t *reply_post_free; + dma_addr_t reply_post_free_dma; +}; + /** * enum mutex_type - task management mutex type * @TM_MUTEX_OFF: mutex is not required becuase calling function is acquiring it @@ -661,6 +668,7 @@ typedef void (*MPT2SAS_FLUSH_RUNNING_CMDS)(struct MPT2SAS_ADAPTER *ioc); * @ir_firmware: IR firmware present * @bars: bitmask of BAR's that must be configured * @mask_interrupts: ignore interrupt + * @dma_mask: used to set the consistent dma mask * @fault_reset_work_q_name: fw fault work queue * @fault_reset_work_q: "" * @fault_reset_work: "" @@ -777,8 +785,11 @@ typedef void (*MPT2SAS_FLUSH_RUNNING_CMDS)(struct MPT2SAS_ADAPTER *ioc); * @reply_free_dma_pool: * @reply_free_host_index: tail index in pool to insert free replys * @reply_post_queue_depth: reply post queue depth - * @reply_post_free: pool for reply post (64bit descriptor) - * @reply_post_free_dma: + * @reply_post_struct: struct for reply_post_free physical & virt address + * @rdpq_array_capable: FW supports multiple reply queue addresses in ioc_init + * @rdpq_array_enable: rdpq_array support is enabled in the driver + * @rdpq_array_enable_assigned: this ensures that rdpq_array_enable flag + * is assigned only ones * @reply_queue_count: number of reply queue's * @reply_queue_list: link list contaning the reply queue info * @reply_post_host_index: head index in the pool where FW completes IO @@ -800,6 +811,7 @@ struct MPT2SAS_ADAPTER { u8 ir_firmware; int bars; u8 mask_interrupts; + int dma_mask; /* fw fault handler */ char fault_reset_work_q_name[20]; @@ -970,8 +982,10 @@ struct MPT2SAS_ADAPTER { /* reply post queue */ u16 reply_post_queue_depth; - Mpi2ReplyDescriptorsUnion_t *reply_post_free; - dma_addr_t reply_post_free_dma; + struct reply_post_struct *reply_post; + u8 rdpq_array_capable; + u8 rdpq_array_enable; + u8 rdpq_array_enable_assigned; struct dma_pool *reply_post_free_dma_pool; u8 reply_queue_count; struct list_head reply_queue_list; diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index 0c47425c73f..c72a2fff5db 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c @@ -2,7 +2,7 @@ * This module provides common API for accessing firmware configuration pages * * This code is based on drivers/scsi/mpt2sas/mpt2_base.c - * Copyright (C) 2007-2013 LSI Corporation + * Copyright (C) 2007-2014 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index 62df8f9d427..ca4e563c01d 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c @@ -3,7 +3,7 @@ * controllers * * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.c - * Copyright (C) 2007-2013 LSI Corporation + * Copyright (C) 2007-2014 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.h b/drivers/scsi/mpt2sas/mpt2sas_ctl.h index 8b2ac1869dc..fa0567c9605 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.h +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.h @@ -3,7 +3,7 @@ * controllers * * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.h - * Copyright (C) 2007-2013 LSI Corporation + * Copyright (C) 2007-2014 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt2sas/mpt2sas_debug.h b/drivers/scsi/mpt2sas/mpt2sas_debug.h index a9021cbd662..cc57ef31d0f 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_debug.h +++ b/drivers/scsi/mpt2sas/mpt2sas_debug.h @@ -2,7 +2,7 @@ * Logging Support for MPT (Message Passing Technology) based controllers * * This code is based on drivers/scsi/mpt2sas/mpt2_debug.c - * Copyright (C) 2007-2013 LSI Corporation + * Copyright (C) 2007-2014 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index dd461015813..c80ed048264 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -2,7 +2,7 @@ * Scsi Host Layer for MPT (Message Passing Technology) based controllers * * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c - * Copyright (C) 2007-2013 LSI Corporation + * Copyright (C) 2007-2014 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or @@ -55,6 +55,8 @@ #include <linux/raid_class.h> #include <linux/slab.h> +#include <asm/unaligned.h> + #include "mpt2sas_base.h" MODULE_AUTHOR(MPT2SAS_AUTHOR); @@ -145,7 +147,7 @@ struct sense_info { }; -#define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC) +#define MPT2SAS_TURN_ON_PFA_LED (0xFFFC) #define MPT2SAS_PORT_ENABLE_COMPLETE (0xFFFD) #define MPT2SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF) /** @@ -3858,85 +3860,46 @@ _scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, u16 smid) { - u32 v_lba, p_lba, stripe_off, stripe_unit, column, io_size; + sector_t v_lba, p_lba, stripe_off, column, io_size; u32 stripe_sz, stripe_exp; - u8 num_pds, *cdb_ptr, i; - u8 cdb0 = scmd->cmnd[0]; - u64 v_llba; + u8 num_pds, cmd = scmd->cmnd[0]; - /* - * Try Direct I/O to RAID memeber disks - */ - if (cdb0 == READ_16 || cdb0 == READ_10 || - cdb0 == WRITE_16 || cdb0 == WRITE_10) { - cdb_ptr = mpi_request->CDB.CDB32; - - if ((cdb0 < READ_16) || !(cdb_ptr[2] | cdb_ptr[3] | cdb_ptr[4] - | cdb_ptr[5])) { - io_size = scsi_bufflen(scmd) >> - raid_device->block_exponent; - i = (cdb0 < READ_16) ? 2 : 6; - /* get virtual lba */ - v_lba = be32_to_cpu(*(__be32 *)(&cdb_ptr[i])); - - if (((u64)v_lba + (u64)io_size - 1) <= - (u32)raid_device->max_lba) { - stripe_sz = raid_device->stripe_sz; - stripe_exp = raid_device->stripe_exponent; - stripe_off = v_lba & (stripe_sz - 1); - - /* Check whether IO falls within a stripe */ - if ((stripe_off + io_size) <= stripe_sz) { - num_pds = raid_device->num_pds; - p_lba = v_lba >> stripe_exp; - stripe_unit = p_lba / num_pds; - column = p_lba % num_pds; - p_lba = (stripe_unit << stripe_exp) + - stripe_off; - mpi_request->DevHandle = - cpu_to_le16(raid_device-> - pd_handle[column]); - (*(__be32 *)(&cdb_ptr[i])) = - cpu_to_be32(p_lba); - /* - * WD: To indicate this I/O is directI/O - */ - _scsih_scsi_direct_io_set(ioc, smid, 1); - } - } - } else { - io_size = scsi_bufflen(scmd) >> - raid_device->block_exponent; - /* get virtual lba */ - v_llba = be64_to_cpu(*(__be64 *)(&cdb_ptr[2])); - - if ((v_llba + (u64)io_size - 1) <= - raid_device->max_lba) { - stripe_sz = raid_device->stripe_sz; - stripe_exp = raid_device->stripe_exponent; - stripe_off = (u32) (v_llba & (stripe_sz - 1)); - - /* Check whether IO falls within a stripe */ - if ((stripe_off + io_size) <= stripe_sz) { - num_pds = raid_device->num_pds; - p_lba = (u32)(v_llba >> stripe_exp); - stripe_unit = p_lba / num_pds; - column = p_lba % num_pds; - p_lba = (stripe_unit << stripe_exp) + - stripe_off; - mpi_request->DevHandle = - cpu_to_le16(raid_device-> - pd_handle[column]); - (*(__be64 *)(&cdb_ptr[2])) = - cpu_to_be64((u64)p_lba); - /* - * WD: To indicate this I/O is directI/O - */ - _scsih_scsi_direct_io_set(ioc, smid, 1); - } - } - } - } + if (cmd != READ_10 && cmd != WRITE_10 && + cmd != READ_16 && cmd != WRITE_16) + return; + + if (cmd == READ_10 || cmd == WRITE_10) + v_lba = get_unaligned_be32(&mpi_request->CDB.CDB32[2]); + else + v_lba = get_unaligned_be64(&mpi_request->CDB.CDB32[2]); + + io_size = scsi_bufflen(scmd) >> raid_device->block_exponent; + + if (v_lba + io_size - 1 > raid_device->max_lba) + return; + + stripe_sz = raid_device->stripe_sz; + stripe_exp = raid_device->stripe_exponent; + stripe_off = v_lba & (stripe_sz - 1); + + /* Return unless IO falls within a stripe */ + if (stripe_off + io_size > stripe_sz) + return; + + num_pds = raid_device->num_pds; + p_lba = v_lba >> stripe_exp; + column = sector_div(p_lba, num_pds); + p_lba = (p_lba << stripe_exp) + stripe_off; + + mpi_request->DevHandle = cpu_to_le16(raid_device->pd_handle[column]); + + if (cmd == READ_10 || cmd == WRITE_10) + put_unaligned_be32(lower_32_bits(p_lba), + &mpi_request->CDB.CDB32[2]); + else + put_unaligned_be64(p_lba, &mpi_request->CDB.CDB32[2]); + + _scsih_scsi_direct_io_set(ioc, smid, 1); } /** @@ -4308,7 +4271,7 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, #endif /** - * _scsih_turn_on_fault_led - illuminate Fault LED + * _scsih_turn_on_pfa_led - illuminate PFA LED * @ioc: per adapter object * @handle: device handle * Context: process @@ -4316,10 +4279,15 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, * Return nothing. */ static void -_scsih_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) +_scsih_turn_on_pfa_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) { Mpi2SepReply_t mpi_reply; Mpi2SepRequest_t mpi_request; + struct _sas_device *sas_device; + + sas_device = _scsih_sas_device_find_by_handle(ioc, handle); + if (!sas_device) + return; memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; @@ -4334,6 +4302,47 @@ _scsih_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) __FILE__, __LINE__, __func__); return; } + sas_device->pfa_led_on = 1; + + + if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { + dewtprintk(ioc, printk(MPT2SAS_INFO_FMT + "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n", + ioc->name, le16_to_cpu(mpi_reply.IOCStatus), + le32_to_cpu(mpi_reply.IOCLogInfo))); + return; + } +} + +/** + * _scsih_turn_off_pfa_led - turn off PFA LED + * @ioc: per adapter object + * @sas_device: sas device whose PFA LED has to turned off + * Context: process + * + * Return nothing. + */ +static void +_scsih_turn_off_pfa_led(struct MPT2SAS_ADAPTER *ioc, + struct _sas_device *sas_device) +{ + Mpi2SepReply_t mpi_reply; + Mpi2SepRequest_t mpi_request; + + memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); + mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; + mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS; + mpi_request.SlotStatus = 0; + mpi_request.Slot = cpu_to_le16(sas_device->slot); + mpi_request.DevHandle = 0; + mpi_request.EnclosureHandle = cpu_to_le16(sas_device->enclosure_handle); + mpi_request.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS; + if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply, + &mpi_request)) != 0) { + printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, + __FILE__, __LINE__, __func__); + return; + } if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "enclosure_processor: " @@ -4345,7 +4354,7 @@ _scsih_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) } /** - * _scsih_send_event_to_turn_on_fault_led - fire delayed event + * _scsih_send_event_to_turn_on_pfa_led - fire delayed event * @ioc: per adapter object * @handle: device handle * Context: interrupt. @@ -4353,14 +4362,14 @@ _scsih_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) * Return nothing. */ static void -_scsih_send_event_to_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) +_scsih_send_event_to_turn_on_pfa_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) { struct fw_event_work *fw_event; fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); if (!fw_event) return; - fw_event->event = MPT2SAS_TURN_ON_FAULT_LED; + fw_event->event = MPT2SAS_TURN_ON_PFA_LED; fw_event->device_handle = handle; fw_event->ioc = ioc; _scsih_fw_event_add(ioc, fw_event); @@ -4404,7 +4413,7 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) spin_unlock_irqrestore(&ioc->sas_device_lock, flags); if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) - _scsih_send_event_to_turn_on_fault_led(ioc, handle); + _scsih_send_event_to_turn_on_pfa_led(ioc, handle); /* insert into event log */ sz = offsetof(Mpi2EventNotificationReply_t, EventData) + @@ -5325,6 +5334,12 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, { struct MPT2SAS_TARGET *sas_target_priv_data; + if ((ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) && + (sas_device->pfa_led_on)) { + _scsih_turn_off_pfa_led(ioc, sas_device); + sas_device->pfa_led_on = 0; + } + dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: " "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, sas_device->handle, (unsigned long long) @@ -7441,8 +7456,8 @@ _firmware_event_work(struct work_struct *work) dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "port enable: complete " "from worker thread\n", ioc->name)); break; - case MPT2SAS_TURN_ON_FAULT_LED: - _scsih_turn_on_fault_led(ioc, fw_event->device_handle); + case MPT2SAS_TURN_ON_PFA_LED: + _scsih_turn_on_pfa_led(ioc, fw_event->device_handle); break; case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: _scsih_sas_topology_change_event(ioc, fw_event); @@ -8132,6 +8147,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct MPT2SAS_ADAPTER *ioc; struct Scsi_Host *shost; + int rv; shost = scsi_host_alloc(&scsih_driver_template, sizeof(struct MPT2SAS_ADAPTER)); @@ -8227,6 +8243,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (!ioc->firmware_event_thread) { printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); + rv = -ENODEV; goto out_thread_fail; } @@ -8234,6 +8251,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) if ((mpt2sas_base_attach(ioc))) { printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); + rv = -ENODEV; goto out_attach_fail; } @@ -8251,7 +8269,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) } else ioc->hide_drives = 0; - if ((scsi_add_host(shost, &pdev->dev))) { + rv = scsi_add_host(shost, &pdev->dev); + if (rv) { printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); goto out_add_shost_fail; @@ -8268,7 +8287,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) out_thread_fail: list_del(&ioc->list); scsi_host_put(shost); - return -ENODEV; + return rv; } #ifdef CONFIG_PM diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c index 410f4a3e888..0d1d06488a2 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_transport.c +++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c @@ -2,7 +2,7 @@ * SAS Transport Layer for MPT (Message Passing Technology) based controllers * * This code is based on drivers/scsi/mpt2sas/mpt2_transport.c - * Copyright (C) 2007-2013 LSI Corporation + * Copyright (C) 2007-2014 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or |