linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/13] mpt3sas driver NVMe support:
@ 2017-07-14 13:22 Suganath Prabu S
  2017-07-14 13:22 ` [PATCH v2 01/13] mpt3sas: Update MPI Header Suganath Prabu S
                   ` (14 more replies)
  0 siblings, 15 replies; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

Ventura Series controller are Tri-mode. The controller and
firmware are capable of supporting NVMe devices and
PCIe switches to be connected with the controller. This
patch set adds driver level support for NVMe devices and
PCIe switches.

Suganath Prabu S (13):
  mpt3sas: Update MPI Header
  mpt3sas: Add nvme device support in slave alloc, target alloc and
    probe
  mpt3sas: SGL to PRP Translation for I/Os to NVMe  devices
  mpt3sas: Added support for nvme encapsulated request message.
  mpt3sas: API 's to support NVMe drive addition to SML
  mpt3sas: API's to remove nvme drive from sml
  mpt3sas: Handle NVMe PCIe device related events generated            
       from firmware.
  mpt3sas: Set NVMe device queue depth as 128
  mpt3sas: scan and add nvme device after controller reset
  mpt3as: Add-Task-management-debug-info-for-NVMe-drives.
  mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log
    info
  mpt3sas: Fix nvme drives checking for tlr.
  mpt3sas: Update mpt3sas driver version.

 drivers/scsi/mpt3sas/mpi/mpi2.h          |   43 +-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h     |  647 ++++++++++-
 drivers/scsi/mpt3sas/mpi/mpi2_init.h     |   11 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h      |  331 ++++++-
 drivers/scsi/mpt3sas/mpi/mpi2_pci.h      |  142 +++
 drivers/scsi/mpt3sas/mpi/mpi2_tool.h     |   14 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c      |  710 +++++++++++-
 drivers/scsi/mpt3sas/mpt3sas_base.h      |  171 +++-
 drivers/scsi/mpt3sas/mpt3sas_config.c    |  100 ++
 drivers/scsi/mpt3sas/mpt3sas_ctl.c       |  158 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c     | 1874 ++++++++++++++++++++++++++++--
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |    2 +-
 12 files changed, 4063 insertions(+), 140 deletions(-)
 create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h

Thanks,
Suganath Prabu S

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v2 01/13] mpt3sas: Update MPI Header
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
@ 2017-07-14 13:22 ` Suganath Prabu S
  2017-08-03  6:24   ` Hannes Reinecke
  2017-07-14 13:22 ` [PATCH v2 02/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe Suganath Prabu S
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

Update MPI Files for NVMe support

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpi/mpi2.h      |   43 +++-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  647 +++++++++++++++++++++++++++++++++-
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |   11 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |  331 +++++++++++++++++-
 drivers/scsi/mpt3sas/mpi/mpi2_pci.h  |  142 ++++++++
 drivers/scsi/mpt3sas/mpi/mpi2_tool.h |   14 +-
 6 files changed, 1177 insertions(+), 11 deletions(-)
 create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h
index a9a659f..bc59058 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2.h
@@ -8,7 +8,7 @@
  *                 scatter/gather formats.
  * Creation Date:  June 21, 2006
  *
- * mpi2.h Version:  02.00.42
+ * mpi2.h Version:  02.00.48
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *       prefix are for use only on MPI v2.5 products, and must not be used
@@ -103,6 +103,16 @@
  * 08-25-15  02.00.40  Bumped MPI2_HEADER_VERSION_UNIT.
  * 12-15-15  02.00.41  Bumped MPI_HEADER_VERSION_UNIT
  * 01-01-16  02.00.42  Bumped MPI_HEADER_VERSION_UNIT
+ * 04-05-16  02.00.43  Modified  MPI26_DIAG_BOOT_DEVICE_SELECT defines
+ *                     to be unique within first 32 characters.
+ *                     Removed AHCI support.
+ *                     Removed SOP support.
+ *                     Bumped MPI2_HEADER_VERSION_UNIT.
+ * 04-10-16  02.00.44  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 07-06-16  02.00.45  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 09-02-16  02.00.46  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 11-23-16  02.00.47  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 02-03-17  02.00.48  Bumped MPI2_HEADER_VERSION_UNIT.
  * --------------------------------------------------------------------------
  */
 
@@ -142,7 +152,7 @@
 #define MPI2_VERSION_02_06		    (0x0206)
 
 /*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT            (0x2A)
+#define MPI2_HEADER_VERSION_UNIT            (0x30)
 #define MPI2_HEADER_VERSION_DEV             (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK       (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT      (8)
@@ -249,6 +259,12 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS {
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT    (0x00000000)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW       (0x00000800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH      (0x00000000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW       (0x00000800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH      (0x00001000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW       (0x00001800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG           (0x00000400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET            (0x00000200)
 #define MPI2_DIAG_HCB_MODE                      (0x00000100)
@@ -367,6 +383,7 @@ typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR {
 #define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE            (0x08)
 #define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR        (0x0A)
 #define MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO      (0x0C)
+#define MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED      (0x10)
 
 #define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER         (0x01)
 
@@ -425,6 +442,13 @@ typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
 	Mpi25FastPathSCSIIORequestDescriptor_t,
 	*pMpi25FastPathSCSIIORequestDescriptor_t;
 
+/*PCIe Encapsulated Request Descriptor */
+typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
+	MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+	*PTR_MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+	Mpi26PCIeEncapsulatedRequestDescriptor_t,
+	*pMpi26PCIeEncapsulatedRequestDescriptor_t;
+
 /*union of Request Descriptors */
 typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
 	MPI2_DEFAULT_REQUEST_DESCRIPTOR Default;
@@ -433,6 +457,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
 	MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget;
 	MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator;
 	MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR FastPathSCSIIO;
+	MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR PCIeEncapsulated;
 	U64 Words;
 } MPI2_REQUEST_DESCRIPTOR_UNION,
 	*PTR_MPI2_REQUEST_DESCRIPTOR_UNION,
@@ -450,6 +475,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
  *      Atomic SCSI Target Request Descriptor
  *      Atomic RAID Accelerator Request Descriptor
  *      Atomic Fast Path SCSI IO Request Descriptor
+ *      Atomic PCIe Encapsulated Request Descriptor
  */
 
 /*Atomic Request Descriptor */
@@ -487,6 +513,7 @@ typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR {
 #define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER       (0x03)
 #define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS    (0x05)
 #define MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS  (0x06)
+#define MPI26_RPY_DESCRIPT_FLAGS_PCIE_ENCAPSULATED_SUCCESS  (0x08)
 #define MPI2_RPY_DESCRIPT_FLAGS_UNUSED                      (0x0F)
 
 /*values for marking a reply descriptor as unused */
@@ -565,6 +592,13 @@ typedef MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR
 	Mpi25FastPathSCSIIOSuccessReplyDescriptor_t,
 	*pMpi25FastPathSCSIIOSuccessReplyDescriptor_t;
 
+/*PCIe Encapsulated Success Reply Descriptor */
+typedef MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR
+	MPI26_PCIE_ENCAPSULATED_SUCCESS_REPLY_DESCRIPTOR,
+	*PTR_MPI26_PCIE_ENCAPSULATED_SUCCESS_REPLY_DESCRIPTOR,
+	Mpi26PCIeEncapsulatedSuccessReplyDescriptor_t,
+	*pMpi26PCIeEncapsulatedSuccessReplyDescriptor_t;
+
 /*union of Reply Descriptors */
 typedef union _MPI2_REPLY_DESCRIPTORS_UNION {
 	MPI2_DEFAULT_REPLY_DESCRIPTOR Default;
@@ -574,6 +608,8 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION {
 	MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer;
 	MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR RAIDAcceleratorSuccess;
 	MPI25_FP_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR FastPathSCSIIOSuccess;
+	MPI26_PCIE_ENCAPSULATED_SUCCESS_REPLY_DESCRIPTOR
+						PCIeEncapsulatedSuccess;
 	U64 Words;
 } MPI2_REPLY_DESCRIPTORS_UNION,
 	*PTR_MPI2_REPLY_DESCRIPTORS_UNION,
@@ -616,6 +652,7 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION {
 #define MPI2_FUNCTION_HOST_BASED_DISCOVERY_ACTION   (0x2F)
 #define MPI2_FUNCTION_PWR_MGMT_CONTROL              (0x30)
 #define MPI2_FUNCTION_SEND_HOST_MESSAGE             (0x31)
+#define MPI2_FUNCTION_NVME_ENCAPSULATED             (0x33)
 #define MPI2_FUNCTION_MIN_PRODUCT_SPECIFIC          (0xF0)
 #define MPI2_FUNCTION_MAX_PRODUCT_SPECIFIC          (0xFF)
 
@@ -1162,6 +1199,8 @@ typedef union _MPI25_SGE_IO_UNION {
 
 #define MPI26_IEEE_SGE_FLAGS_NSF_MASK           (0x1C)
 #define MPI26_IEEE_SGE_FLAGS_NSF_MPI_IEEE       (0x00)
+#define MPI26_IEEE_SGE_FLAGS_NSF_NVME_PRP       (0x08)
+#define MPI26_IEEE_SGE_FLAGS_NSF_NVME_SGL       (0x10)
 
 /*Data Location Address Space */
 
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
index fa61baf..3bb6833 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
@@ -6,7 +6,7 @@
  *         Title:  MPI Configuration messages and pages
  * Creation Date:  November 10, 2006
  *
- *   mpi2_cnfg.h Version:  02.00.35
+ *   mpi2_cnfg.h Version:  02.00.40
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *       prefix are for use only on MPI v2.5 products, and must not be used
@@ -189,6 +189,35 @@
  *                     MPI2_CONFIG_PAGE_BIOS_1.
  * 08-25-15  02.00.34  Bumped Header Version.
  * 12-18-15  02.00.35  Added SATADeviceWaitTime to SAS IO Unit Page 4.
+ * 01-21-16  02.00.36  Added/modified MPI2_MFGPAGE_DEVID_SAS defines.
+ *                     Added Link field to PCIe Link Pages
+ *                     Added EnclosureLevel and ConnectorName to PCIe
+ *                     Device Page 0.
+ *                     Added define for PCIE IoUnit page 1 max rate shift.
+ *                     Added comment for reserved ExtPageTypes.
+ *                     Added SAS 4 22.5 gbs speed support.
+ *                     Added PCIe 4 16.0 GT/sec speec support.
+ *                     Removed AHCI support.
+ *                     Removed SOP support.
+ *                     Added NegotiatedLinkRate and NegotiatedPortWidth to
+ *                     PCIe device page 0.
+ * 04-10-16  02.00.37  Fixed MPI2_MFGPAGE_DEVID_SAS3616/3708 defines
+ * 07-01-16  02.00.38  Added Manufacturing page 7 Connector types.
+ *                     Changed declaration of ConnectorName in PCIe DevicePage0
+ *                     to match SAS DevicePage 0.
+ *                     Added SATADeviceWaitTime to IO Unit Page 11.
+ *                     Added MPI26_MFGPAGE_DEVID_SAS4008
+ *                     Added x16 PCIe width to IO Unit Page 7
+ *                     Added LINKFLAGS to control SRIS in PCIe IO Unit page 1
+ *                     phy data.
+ *                     Added InitStatus to PCIe IO Unit Page 1 header.
+ * 09-01-16  02.00.39  Added MPI26_CONFIG_PAGE_ENCLOSURE_0 and related defines.
+ *                     Added MPI26_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE and
+ *                     MPI26_ENCLOS_PGAD_FORM_HANDLE page address formats.
+ * 02-02-17  02.00.40  Added MPI2_MANPAGE7_SLOT_UNKNOWN.
+ *                     Added ChassisSlot field to SAS Enclosure Page 0.
+ *                     Added ChassisSlot Valid bit (bit 5) to the Flags field
+ *                     in SAS Enclosure Page 0.
  * --------------------------------------------------------------------------
  */
 
@@ -272,6 +301,10 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION {
 #define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT            (0x18)
 #define MPI2_CONFIG_EXTPAGETYPE_ETHERNET            (0x19)
 #define MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING   (0x1A)
+#define MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT        (0x1B)
+#define MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH         (0x1C)
+#define MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE         (0x1D)
+#define MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK           (0x1E)
 
 
 /*****************************************************************************
@@ -339,6 +372,12 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION {
 
 #define MPI2_SAS_ENCLOS_PGAD_HANDLE_MASK            (0x0000FFFF)
 
+/*Enclosure PageAddress format */
+#define MPI26_ENCLOS_PGAD_FORM_MASK                 (0xF0000000)
+#define MPI26_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE      (0x00000000)
+#define MPI26_ENCLOS_PGAD_FORM_HANDLE               (0x10000000)
+
+#define MPI26_ENCLOS_PGAD_HANDLE_MASK               (0x0000FFFF)
 
 /*RAID Configuration PageAddress format */
 #define MPI2_RAID_PGAD_FORM_MASK                    (0xF0000000)
@@ -365,6 +404,33 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION {
 #define MPI2_ETHERNET_PGAD_IF_NUMBER_MASK           (0x000000FF)
 
 
+/*PCIe Switch PageAddress format */
+#define MPI26_PCIE_SWITCH_PGAD_FORM_MASK            (0xF0000000)
+#define MPI26_PCIE_SWITCH_PGAD_FORM_GET_NEXT_HNDL   (0x00000000)
+#define MPI26_PCIE_SWITCH_PGAD_FORM_HNDL_PORTNUM    (0x10000000)
+#define MPI26_PCIE_SWITCH_EXPAND_PGAD_FORM_HNDL     (0x20000000)
+
+#define MPI26_PCIE_SWITCH_PGAD_HANDLE_MASK          (0x0000FFFF)
+#define MPI26_PCIE_SWITCH_PGAD_PORTNUM_MASK         (0x00FF0000)
+#define MPI26_PCIE_SWITCH_PGAD_PORTNUM_SHIFT        (16)
+
+
+/*PCIe Device PageAddress format */
+#define MPI26_PCIE_DEVICE_PGAD_FORM_MASK            (0xF0000000)
+#define MPI26_PCIE_DEVICE_PGAD_FORM_GET_NEXT_HANDLE (0x00000000)
+#define MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE          (0x20000000)
+
+#define MPI26_PCIE_DEVICE_PGAD_HANDLE_MASK          (0x0000FFFF)
+
+/*PCIe Link PageAddress format */
+#define MPI26_PCIE_LINK_PGAD_FORM_MASK            (0xF0000000)
+#define MPI26_PCIE_LINK_PGAD_FORM_GET_NEXT_LINK   (0x00000000)
+#define MPI26_PCIE_LINK_PGAD_FORM_LINK_NUM        (0x10000000)
+
+#define MPI26_PCIE_DEVICE_PGAD_LINKNUM_MASK       (0x000000FF)
+
+
+
 /****************************************************************************
 *  Configuration messages
 ****************************************************************************/
@@ -484,6 +550,12 @@ typedef struct _MPI2_CONFIG_REPLY {
 #define MPI26_MFGPAGE_DEVID_SAS3508                 (0x00AD)
 #define MPI26_MFGPAGE_DEVID_SAS3508_1               (0x00AE)
 #define MPI26_MFGPAGE_DEVID_SAS3408                 (0x00AF)
+#define MPI26_MFGPAGE_DEVID_SAS3716                 (0x00D0)
+#define MPI26_MFGPAGE_DEVID_SAS3616                 (0x00D1)
+#define MPI26_MFGPAGE_DEVID_SAS3708                 (0x00D2)
+
+#define MPI26_MFGPAGE_DEVID_SAS4008                 (0x00A1)
+
 
 /*Manufacturing Page 0 */
 
@@ -726,6 +798,12 @@ typedef struct _MPI2_MANPAGE7_CONNECTOR_INFO {
 #define MPI2_MANPAGE7_PINOUT_SFF_8644_8X                (0x0B)
 #define MPI2_MANPAGE7_PINOUT_SFF_8644_16X               (0x0C)
 #define MPI2_MANPAGE7_PINOUT_SFF_8436                   (0x0D)
+#define MPI2_MANPAGE7_PINOUT_SFF_8088_A                 (0x0E)
+#define MPI2_MANPAGE7_PINOUT_SFF_8643_16i               (0x0F)
+#define MPI2_MANPAGE7_PINOUT_SFF_8654_4i                (0x10)
+#define MPI2_MANPAGE7_PINOUT_SFF_8654_8i                (0x11)
+#define MPI2_MANPAGE7_PINOUT_SFF_8611_4i                (0x12)
+#define MPI2_MANPAGE7_PINOUT_SFF_8611_8i                (0x13)
 
 /*defines for the Location field */
 #define MPI2_MANPAGE7_LOCATION_UNKNOWN                  (0x01)
@@ -736,6 +814,9 @@ typedef struct _MPI2_MANPAGE7_CONNECTOR_INFO {
 #define MPI2_MANPAGE7_LOCATION_NOT_PRESENT              (0x20)
 #define MPI2_MANPAGE7_LOCATION_NOT_CONNECTED            (0x80)
 
+/*defines for the Slot field */
+#define MPI2_MANPAGE7_SLOT_UNKNOWN                      (0xFFFF)
+
 /*
  *Host code (drivers, BIOS, utilities, etc.) should leave this define set to
  *one and check the value returned for NumPhys at runtime.
@@ -999,11 +1080,13 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
 #define MPI2_IOUNITPAGE7_PCIE_WIDTH_X2              (0x02)
 #define MPI2_IOUNITPAGE7_PCIE_WIDTH_X4              (0x04)
 #define MPI2_IOUNITPAGE7_PCIE_WIDTH_X8              (0x08)
+#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X16             (0x10)
 
 /*defines for IO Unit Page 7 PCIeSpeed field */
 #define MPI2_IOUNITPAGE7_PCIE_SPEED_2_5_GBPS        (0x00)
 #define MPI2_IOUNITPAGE7_PCIE_SPEED_5_0_GBPS        (0x01)
 #define MPI2_IOUNITPAGE7_PCIE_SPEED_8_0_GBPS        (0x02)
+#define MPI2_IOUNITPAGE7_PCIE_SPEED_16_0_GBPS       (0x03)
 
 /*defines for IO Unit Page 7 ProcessorState field */
 #define MPI2_IOUNITPAGE7_PSTATE_MASK_SECOND         (0x0000000F)
@@ -1970,6 +2053,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 {
 #define MPI2_SAS_NEG_LINK_RATE_3_0                      (0x09)
 #define MPI2_SAS_NEG_LINK_RATE_6_0                      (0x0A)
 #define MPI25_SAS_NEG_LINK_RATE_12_0                    (0x0B)
+#define MPI26_SAS_NEG_LINK_RATE_22_5                    (0x0C)
 
 
 /*values for AttachedPhyInfo fields */
@@ -2037,12 +2121,14 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 {
 #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 MPI26_SAS_PRATE_MAX_RATE_22_5                   (0xC0)
 #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)
 #define MPI2_SAS_PRATE_MIN_RATE_3_0                     (0x09)
 #define MPI2_SAS_PRATE_MIN_RATE_6_0                     (0x0A)
 #define MPI25_SAS_PRATE_MIN_RATE_12_0                   (0x0B)
+#define MPI26_SAS_PRATE_MIN_RATE_22_5                   (0x0C)
 
 
 /*values for SAS HwLinkRate fields */
@@ -2051,11 +2137,13 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 {
 #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 MPI26_SAS_HWRATE_MAX_RATE_22_5                  (0xC0)
 #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)
 #define MPI2_SAS_HWRATE_MIN_RATE_6_0                    (0x0A)
 #define MPI25_SAS_HWRATE_MIN_RATE_12_0                  (0x0B)
+#define MPI26_SAS_HWRATE_MIN_RATE_22_5                  (0x0C)
 
 
 
@@ -2240,11 +2328,13 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_1 {
 #define MPI2_SASIOUNIT1_MAX_RATE_3_0                                (0x90)
 #define MPI2_SASIOUNIT1_MAX_RATE_6_0                                (0xA0)
 #define MPI25_SASIOUNIT1_MAX_RATE_12_0                              (0xB0)
+#define MPI26_SASIOUNIT1_MAX_RATE_22_5                              (0xC0)
 #define MPI2_SASIOUNIT1_MIN_RATE_MASK                               (0x0F)
 #define MPI2_SASIOUNIT1_MIN_RATE_1_5                                (0x08)
 #define MPI2_SASIOUNIT1_MIN_RATE_3_0                                (0x09)
 #define MPI2_SASIOUNIT1_MIN_RATE_6_0                                (0x0A)
 #define MPI25_SASIOUNIT1_MIN_RATE_12_0                              (0x0B)
+#define MPI26_SASIOUNIT1_MIN_RATE_22_5                              (0x0C)
 
 /*see mpi2_sas.h for values for
  *SAS IO Unit Page 1 ControllerPhyDeviceInfo values */
@@ -3173,7 +3263,7 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0 {
 	U16
 		StartSlot;                  /*0x1A */
 	U8
-		Reserved2;                  /*0x1C */
+		ChassisSlot;                /*0x1C */
 	U8
 		EnclosureLevel;		    /*0x1D */
 	U16
@@ -3184,11 +3274,15 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0 {
 		Reserved4;                  /*0x24 */
 } MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0,
 	*PTR_MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0,
-	Mpi2SasEnclosurePage0_t, *pMpi2SasEnclosurePage0_t;
+	Mpi2SasEnclosurePage0_t, *pMpi2SasEnclosurePage0_t,
+	MPI26_CONFIG_PAGE_ENCLOSURE_0,
+	*PTR_MPI26_CONFIG_PAGE_ENCLOSURE_0,
+	Mpi26EnclosurePage0_t, *pMpi26EnclosurePage0_t;
 
 #define MPI2_SASENCLOSURE0_PAGEVERSION      (0x04)
 
 /*values for SAS Enclosure Page 0 Flags field */
+#define MPI2_SAS_ENCLS0_FLAGS_CHASSIS_SLOT_VALID    (0x0020)
 #define MPI2_SAS_ENCLS0_FLAGS_ENCL_LEVEL_VALID      (0x0010)
 #define MPI2_SAS_ENCLS0_FLAGS_MNG_MASK              (0x000F)
 #define MPI2_SAS_ENCLS0_FLAGS_MNG_UNKNOWN           (0x0000)
@@ -3198,6 +3292,18 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0 {
 #define MPI2_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE     (0x0004)
 #define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO          (0x0005)
 
+#define MPI26_ENCLOSURE0_PAGEVERSION        (0x04)
+
+/*Values for Enclosure Page 0 Flags field */
+#define MPI26_ENCLS0_FLAGS_CHASSIS_SLOT_VALID       (0x0020)
+#define MPI26_ENCLS0_FLAGS_ENCL_LEVEL_VALID         (0x0010)
+#define MPI26_ENCLS0_FLAGS_MNG_MASK                 (0x000F)
+#define MPI26_ENCLS0_FLAGS_MNG_UNKNOWN              (0x0000)
+#define MPI26_ENCLS0_FLAGS_MNG_IOC_SES              (0x0001)
+#define MPI26_ENCLS0_FLAGS_MNG_IOC_SGPIO            (0x0002)
+#define MPI26_ENCLS0_FLAGS_MNG_EXP_SGPIO            (0x0003)
+#define MPI26_ENCLS0_FLAGS_MNG_SES_ENCLOSURE        (0x0004)
+#define MPI26_ENCLS0_FLAGS_MNG_IOC_GPIO             (0x0005)
 
 /****************************************************************************
 *  Log Config Page
@@ -3497,4 +3603,539 @@ typedef struct _MPI2_CONFIG_PAGE_EXT_MAN_PS {
 
 /*PageVersion should be provided by product-specific code */
 
+
+
+/****************************************************************************
+*  values for fields used by several types of PCIe Config Pages
+****************************************************************************/
+
+/*values for NegotiatedLinkRates fields */
+#define MPI26_PCIE_NEG_LINK_RATE_MASK_PHYSICAL          (0x0F)
+/*link rates used for Negotiated Physical Link Rate */
+#define MPI26_PCIE_NEG_LINK_RATE_UNKNOWN                (0x00)
+#define MPI26_PCIE_NEG_LINK_RATE_PHY_DISABLED           (0x01)
+#define MPI26_PCIE_NEG_LINK_RATE_2_5                    (0x02)
+#define MPI26_PCIE_NEG_LINK_RATE_5_0                    (0x03)
+#define MPI26_PCIE_NEG_LINK_RATE_8_0                    (0x04)
+#define MPI26_PCIE_NEG_LINK_RATE_16_0                   (0x05)
+
+
+/****************************************************************************
+*  PCIe IO Unit Config Pages (MPI v2.6 and later)
+****************************************************************************/
+
+/*PCIe IO Unit Page 0 */
+
+typedef struct _MPI26_PCIE_IO_UNIT0_PHY_DATA {
+	U8
+		Link;                   /*0x00 */
+	U8
+		LinkFlags;              /*0x01 */
+	U8
+		PhyFlags;               /*0x02 */
+	U8
+		NegotiatedLinkRate;     /*0x03 */
+	U32
+		ControllerPhyDeviceInfo;/*0x04 */
+	U16
+		AttachedDevHandle;      /*0x08 */
+	U16
+		ControllerDevHandle;    /*0x0A */
+	U32
+		EnumerationStatus;      /*0x0C */
+	U32
+		Reserved1;              /*0x10 */
+} MPI26_PCIE_IO_UNIT0_PHY_DATA,
+	*PTR_MPI26_PCIE_IO_UNIT0_PHY_DATA,
+	Mpi26PCIeIOUnit0PhyData_t, *pMpi26PCIeIOUnit0PhyData_t;
+
+/*
+ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ *one and check the value returned for NumPhys at runtime.
+ */
+#ifndef MPI26_PCIE_IOUNIT0_PHY_MAX
+#define MPI26_PCIE_IOUNIT0_PHY_MAX      (1)
+#endif
+
+typedef struct _MPI26_CONFIG_PAGE_PIOUNIT_0 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER
+		Header;                                 /*0x00 */
+	U32
+		Reserved1;                              /*0x08 */
+	U8
+		NumPhys;                                /*0x0C */
+	U8
+		InitStatus;                             /*0x0D */
+	U16
+		Reserved3;                              /*0x0E */
+	MPI26_PCIE_IO_UNIT0_PHY_DATA
+		PhyData[MPI26_PCIE_IOUNIT0_PHY_MAX];    /*0x10 */
+} MPI26_CONFIG_PAGE_PIOUNIT_0,
+	*PTR_MPI26_CONFIG_PAGE_PIOUNIT_0,
+	Mpi26PCIeIOUnitPage0_t, *pMpi26PCIeIOUnitPage0_t;
+
+#define MPI26_PCIEIOUNITPAGE0_PAGEVERSION                   (0x00)
+
+/*values for PCIe IO Unit Page 0 LinkFlags */
+#define MPI26_PCIEIOUNIT0_LINKFLAGS_ENUMERATION_IN_PROGRESS (0x08)
+
+/*values for PCIe IO Unit Page 0 PhyFlags */
+#define MPI26_PCIEIOUNIT0_PHYFLAGS_PHY_DISABLED             (0x08)
+
+/*use MPI26_PCIE_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
+
+/*see mpi2_pci.h for values for PCIe IO Unit Page 0 ControllerPhyDeviceInfo
+ *values
+ */
+
+/*values for PCIe IO Unit Page 0 EnumerationStatus */
+#define MPI26_PCIEIOUNIT0_ES_MAX_SWITCHES_EXCEEDED          (0x40000000)
+#define MPI26_PCIEIOUNIT0_ES_MAX_DEVICES_EXCEEDED           (0x20000000)
+
+
+/*PCIe IO Unit Page 1 */
+
+typedef struct _MPI26_PCIE_IO_UNIT1_PHY_DATA {
+	U8
+		Link;                       /*0x00 */
+	U8
+		LinkFlags;                  /*0x01 */
+	U8
+		PhyFlags;                   /*0x02 */
+	U8
+		MaxMinLinkRate;             /*0x03 */
+	U32
+		ControllerPhyDeviceInfo;    /*0x04 */
+	U32
+		Reserved1;                  /*0x08 */
+} MPI26_PCIE_IO_UNIT1_PHY_DATA,
+	*PTR_MPI26_PCIE_IO_UNIT1_PHY_DATA,
+	Mpi26PCIeIOUnit1PhyData_t, *pMpi26PCIeIOUnit1PhyData_t;
+
+/*values for LinkFlags */
+#define MPI26_PCIEIOUNIT1_LINKFLAGS_DIS_SRIS    (0x00)
+#define MPI26_PCIEIOUNIT1_LINKFLAGS_EN_SRIS     (0x01)
+
+/*
+ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ *one and check the value returned for NumPhys at runtime.
+ */
+#ifndef MPI26_PCIE_IOUNIT1_PHY_MAX
+#define MPI26_PCIE_IOUNIT1_PHY_MAX      (1)
+#endif
+
+typedef struct _MPI26_CONFIG_PAGE_PIOUNIT_1 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER
+		Header;                             /*0x00 */
+	U16
+		ControlFlags;                       /*0x08 */
+	U16
+		Reserved;                           /*0x0A */
+	U16
+		AdditionalControlFlags;             /*0x0C */
+	U16
+		NVMeMaxQueueDepth;                  /*0x0E */
+	U8
+		NumPhys;                            /*0x10 */
+	U8
+		Reserved1;                          /*0x11 */
+	U16
+		Reserved2;                          /*0x12 */
+	MPI26_PCIE_IO_UNIT1_PHY_DATA
+		PhyData[MPI26_PCIE_IOUNIT1_PHY_MAX];/*0x14 */
+} MPI26_CONFIG_PAGE_PIOUNIT_1,
+	*PTR_MPI26_CONFIG_PAGE_PIOUNIT_1,
+	Mpi26PCIeIOUnitPage1_t, *pMpi26PCIeIOUnitPage1_t;
+
+#define MPI26_PCIEIOUNITPAGE1_PAGEVERSION   (0x00)
+
+/*values for PCIe IO Unit Page 1 PhyFlags */
+#define MPI26_PCIEIOUNIT1_PHYFLAGS_PHY_DISABLE                      (0x08)
+#define MPI26_PCIEIOUNIT1_PHYFLAGS_ENDPOINT_ONLY                    (0x01)
+
+/*values for PCIe IO Unit Page 1 MaxMinLinkRate */
+#define MPI26_PCIEIOUNIT1_MAX_RATE_MASK                             (0xF0)
+#define MPI26_PCIEIOUNIT1_MAX_RATE_SHIFT                            (4)
+#define MPI26_PCIEIOUNIT1_MAX_RATE_2_5                              (0x20)
+#define MPI26_PCIEIOUNIT1_MAX_RATE_5_0                              (0x30)
+#define MPI26_PCIEIOUNIT1_MAX_RATE_8_0                              (0x40)
+#define MPI26_PCIEIOUNIT1_MAX_RATE_16_0                             (0x50)
+
+/*see mpi2_pci.h for values for PCIe IO Unit Page 0 ControllerPhyDeviceInfo
+ *values
+ */
+
+
+/****************************************************************************
+*  PCIe Switch Config Pages (MPI v2.6 and later)
+****************************************************************************/
+
+/*PCIe Switch Page 0 */
+
+typedef struct _MPI26_CONFIG_PAGE_PSWITCH_0 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER
+		Header;                     /*0x00 */
+	U8
+		PhysicalPort;               /*0x08 */
+	U8
+		Reserved1;                  /*0x09 */
+	U16
+		Reserved2;                  /*0x0A */
+	U16
+		DevHandle;                  /*0x0C */
+	U16
+		ParentDevHandle;            /*0x0E */
+	U8
+		NumPorts;                   /*0x10 */
+	U8
+		PCIeLevel;                  /*0x11 */
+	U16
+		Reserved3;                  /*0x12 */
+	U32
+		Reserved4;                  /*0x14 */
+	U32
+		Reserved5;                  /*0x18 */
+	U32
+		Reserved6;                  /*0x1C */
+} MPI26_CONFIG_PAGE_PSWITCH_0, *PTR_MPI26_CONFIG_PAGE_PSWITCH_0,
+	Mpi26PCIeSwitchPage0_t, *pMpi26PCIeSwitchPage0_t;
+
+#define MPI26_PCIESWITCH0_PAGEVERSION       (0x00)
+
+
+/*PCIe Switch Page 1 */
+
+typedef struct _MPI26_CONFIG_PAGE_PSWITCH_1 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER
+		Header;                     /*0x00 */
+	U8
+		PhysicalPort;               /*0x08 */
+	U8
+		Reserved1;                  /*0x09 */
+	U16
+		Reserved2;                  /*0x0A */
+	U8
+		NumPorts;                   /*0x0C */
+	U8
+		PortNum;                    /*0x0D */
+	U16
+		AttachedDevHandle;          /*0x0E */
+	U16
+		SwitchDevHandle;            /*0x10 */
+	U8
+		NegotiatedPortWidth;        /*0x12 */
+	U8
+		NegotiatedLinkRate;         /*0x13 */
+	U32
+		Reserved4;                  /*0x14 */
+	U32
+		Reserved5;                  /*0x18 */
+} MPI26_CONFIG_PAGE_PSWITCH_1, *PTR_MPI26_CONFIG_PAGE_PSWITCH_1,
+	Mpi26PCIeSwitchPage1_t, *pMpi26PCIeSwitchPage1_t;
+
+#define MPI26_PCIESWITCH1_PAGEVERSION       (0x00)
+
+/*use MPI26_PCIE_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
+
+
+/****************************************************************************
+*  PCIe Device Config Pages (MPI v2.6 and later)
+****************************************************************************/
+
+/*PCIe Device Page 0 */
+
+typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_0 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER
+		Header;                 /*0x00 */
+	U16
+		Slot;                   /*0x08 */
+	U16
+		EnclosureHandle;        /*0x0A */
+	U64
+		WWID;                   /*0x0C */
+	U16
+		ParentDevHandle;        /*0x14 */
+	U8
+		PortNum;                /*0x16 */
+	U8
+		AccessStatus;           /*0x17 */
+	U16
+		DevHandle;              /*0x18 */
+	U8
+		PhysicalPort;           /*0x1A */
+	U8
+		Reserved1;              /*0x1B */
+	U32
+		DeviceInfo;             /*0x1C */
+	U32
+		Flags;                  /*0x20 */
+	U8
+		SupportedLinkRates;     /*0x24 */
+	U8
+		MaxPortWidth;           /*0x25 */
+	U8
+		NegotiatedPortWidth;    /*0x26 */
+	U8
+		NegotiatedLinkRate;     /*0x27 */
+	U8
+		EnclosureLevel;         /*0x28 */
+	U8
+		Reserved2;              /*0x29 */
+	U16
+		Reserved3;              /*0x2A */
+	U8
+		ConnectorName[4];       /*0x2C */
+	U32
+		Reserved4;              /*0x30 */
+	U32
+		Reserved5;              /*0x34 */
+} MPI26_CONFIG_PAGE_PCIEDEV_0, *PTR_MPI26_CONFIG_PAGE_PCIEDEV_0,
+	Mpi26PCIeDevicePage0_t, *pMpi26PCIeDevicePage0_t;
+
+#define MPI26_PCIEDEVICE0_PAGEVERSION       (0x01)
+
+/*values for PCIe Device Page 0 AccessStatus field */
+#define MPI26_PCIEDEV0_ASTATUS_NO_ERRORS                    (0x00)
+#define MPI26_PCIEDEV0_ASTATUS_NEEDS_INITIALIZATION         (0x04)
+#define MPI26_PCIEDEV0_ASTATUS_CAPABILITY_FAILED            (0x02)
+#define MPI26_PCIEDEV0_ASTATUS_DEVICE_BLOCKED               (0x07)
+#define MPI26_PCIEDEV0_ASTATUS_MEMORY_SPACE_ACCESS_FAILED   (0x08)
+#define MPI26_PCIEDEV0_ASTATUS_UNSUPPORTED_DEVICE           (0x09)
+#define MPI26_PCIEDEV0_ASTATUS_MSIX_REQUIRED                (0x0A)
+#define MPI26_PCIEDEV0_ASTATUS_UNKNOWN                      (0x10)
+
+#define MPI26_PCIEDEV0_ASTATUS_NVME_READY_TIMEOUT           (0x30)
+#define MPI26_PCIEDEV0_ASTATUS_NVME_DEVCFG_UNSUPPORTED      (0x31)
+#define MPI26_PCIEDEV0_ASTATUS_NVME_IDENTIFY_FAILED         (0x32)
+#define MPI26_PCIEDEV0_ASTATUS_NVME_QCONFIG_FAILED          (0x33)
+#define MPI26_PCIEDEV0_ASTATUS_NVME_QCREATION_FAILED        (0x34)
+#define MPI26_PCIEDEV0_ASTATUS_NVME_EVENTCFG_FAILED         (0x35)
+#define MPI26_PCIEDEV0_ASTATUS_NVME_GET_FEATURE_STAT_FAILED (0x36)
+#define MPI26_PCIEDEV0_ASTATUS_NVME_IDLE_TIMEOUT            (0x37)
+#define MPI26_PCIEDEV0_ASTATUS_NVME_FAILURE_STATUS          (0x38)
+
+#define MPI26_PCIEDEV0_ASTATUS_INIT_FAIL_MAX                (0x3F)
+
+/*see mpi2_pci.h for the MPI26_PCIE_DEVINFO_ defines used for the DeviceInfo
+ *field
+ */
+
+/*values for PCIe Device Page 0 Flags field */
+#define MPI26_PCIEDEV0_FLAGS_UNAUTHORIZED_DEVICE            (0x8000)
+#define MPI26_PCIEDEV0_FLAGS_ENABLED_FAST_PATH              (0x4000)
+#define MPI26_PCIEDEV0_FLAGS_FAST_PATH_CAPABLE              (0x2000)
+#define MPI26_PCIEDEV0_FLAGS_ASYNCHRONOUS_NOTIFICATION      (0x0400)
+#define MPI26_PCIEDEV0_FLAGS_ATA_SW_PRESERVATION            (0x0200)
+#define MPI26_PCIEDEV0_FLAGS_UNSUPPORTED_DEVICE             (0x0100)
+#define MPI26_PCIEDEV0_FLAGS_ATA_48BIT_LBA_SUPPORTED        (0x0080)
+#define MPI26_PCIEDEV0_FLAGS_ATA_SMART_SUPPORTED            (0x0040)
+#define MPI26_PCIEDEV0_FLAGS_ATA_NCQ_SUPPORTED              (0x0020)
+#define MPI26_PCIEDEV0_FLAGS_ATA_FUA_SUPPORTED              (0x0010)
+#define MPI26_PCIEDEV0_FLAGS_ENCL_LEVEL_VALID               (0x0002)
+#define MPI26_PCIEDEV0_FLAGS_DEVICE_PRESENT                 (0x0001)
+
+/* values for PCIe Device Page 0 SupportedLinkRates field */
+#define MPI26_PCIEDEV0_LINK_RATE_16_0_SUPPORTED             (0x08)
+#define MPI26_PCIEDEV0_LINK_RATE_8_0_SUPPORTED              (0x04)
+#define MPI26_PCIEDEV0_LINK_RATE_5_0_SUPPORTED              (0x02)
+#define MPI26_PCIEDEV0_LINK_RATE_2_5_SUPPORTED              (0x01)
+
+/*use MPI26_PCIE_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
+
+
+/*PCIe Device Page 2 */
+
+typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_2 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER
+		Header;                 /*0x00 */
+	U16
+		DevHandle;              /*0x08 */
+	U16
+		Reserved1;              /*0x0A */
+	U32
+		MaximumDataTransferSize;/*0x0C */
+	U32
+		Capabilities;           /*0x10 */
+	U32
+		Reserved2;              /*0x14 */
+} MPI26_CONFIG_PAGE_PCIEDEV_2, *PTR_MPI26_CONFIG_PAGE_PCIEDEV_2,
+	Mpi26PCIeDevicePage2_t, *pMpi26PCIeDevicePage2_t;
+
+#define MPI26_PCIEDEVICE2_PAGEVERSION       (0x00)
+
+/*defines for PCIe Device Page 2 Capabilities field */
+#define MPI26_PCIEDEV2_CAP_SGL_FORMAT                  (0x00000004)
+#define MPI26_PCIEDEV2_CAP_BIT_BUCKET_SUPPORT          (0x00000002)
+#define MPI26_PCIEDEV2_CAP_SGL_SUPPORT                 (0x00000001)
+
+
+/****************************************************************************
+*  PCIe Link Config Pages (MPI v2.6 and later)
+****************************************************************************/
+
+/*PCIe Link Page 1 */
+
+typedef struct _MPI26_CONFIG_PAGE_PCIELINK_1 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER
+		Header;                     /*0x00 */
+	U8
+		Link;                       /*0x08 */
+	U8
+		Reserved1;                  /*0x09 */
+	U16
+		Reserved2;                  /*0x0A */
+	U32
+		CorrectableErrorCount;      /*0x0C */
+	U16
+		NonFatalErrorCount;         /*0x10 */
+	U16
+		Reserved3;                  /*0x12 */
+	U16
+		FatalErrorCount;            /*0x14 */
+	U16
+		Reserved4;                  /*0x16 */
+} MPI26_CONFIG_PAGE_PCIELINK_1, *PTR_MPI26_CONFIG_PAGE_PCIELINK_1,
+	Mpi26PcieLinkPage1_t, *pMpi26PcieLinkPage1_t;
+
+#define MPI26_PCIELINK1_PAGEVERSION            (0x00)
+
+/*PCIe Link Page 2 */
+
+typedef struct _MPI26_PCIELINK2_LINK_EVENT {
+	U8
+		LinkEventCode;      /*0x00 */
+	U8
+		Reserved1;          /*0x01 */
+	U16
+		Reserved2;          /*0x02 */
+	U32
+		LinkEventInfo;      /*0x04 */
+} MPI26_PCIELINK2_LINK_EVENT, *PTR_MPI26_PCIELINK2_LINK_EVENT,
+	Mpi26PcieLink2LinkEvent_t, *pMpi26PcieLink2LinkEvent_t;
+
+/*use MPI26_PCIELINK3_EVTCODE_ for the LinkEventCode field */
+
+
+/*
+ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ *one and check the value returned for NumLinkEvents at runtime.
+ */
+#ifndef MPI26_PCIELINK2_LINK_EVENT_MAX
+#define MPI26_PCIELINK2_LINK_EVENT_MAX      (1)
+#endif
+
+typedef struct _MPI26_CONFIG_PAGE_PCIELINK_2 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER
+		Header;                     /*0x00 */
+	U8
+		Link;                       /*0x08 */
+	U8
+		Reserved1;                  /*0x09 */
+	U16
+		Reserved2;                  /*0x0A */
+	U8
+		NumLinkEvents;              /*0x0C */
+	U8
+		Reserved3;                  /*0x0D */
+	U16
+		Reserved4;                  /*0x0E */
+	MPI26_PCIELINK2_LINK_EVENT
+		LinkEvent[MPI26_PCIELINK2_LINK_EVENT_MAX]; /*0x10 */
+} MPI26_CONFIG_PAGE_PCIELINK_2, *PTR_MPI26_CONFIG_PAGE_PCIELINK_2,
+	Mpi26PcieLinkPage2_t, *pMpi26PcieLinkPage2_t;
+
+#define MPI26_PCIELINK2_PAGEVERSION            (0x00)
+
+/*PCIe Link Page 3 */
+
+typedef struct _MPI26_PCIELINK3_LINK_EVENT_CONFIG {
+	U8
+		LinkEventCode;      /*0x00 */
+	U8
+		Reserved1;          /*0x01 */
+	U16
+		Reserved2;          /*0x02 */
+	U8
+		CounterType;        /*0x04 */
+	U8
+		ThresholdWindow;    /*0x05 */
+	U8
+		TimeUnits;          /*0x06 */
+	U8
+		Reserved3;          /*0x07 */
+	U32
+		EventThreshold;     /*0x08 */
+	U16
+		ThresholdFlags;     /*0x0C */
+	U16
+		Reserved4;          /*0x0E */
+} MPI26_PCIELINK3_LINK_EVENT_CONFIG, *PTR_MPI26_PCIELINK3_LINK_EVENT_CONFIG,
+	Mpi26PcieLink3LinkEventConfig_t, *pMpi26PcieLink3LinkEventConfig_t;
+
+/*values for LinkEventCode field */
+#define MPI26_PCIELINK3_EVTCODE_NO_EVENT                              (0x00)
+#define MPI26_PCIELINK3_EVTCODE_CORRECTABLE_ERROR_RECEIVED            (0x01)
+#define MPI26_PCIELINK3_EVTCODE_NON_FATAL_ERROR_RECEIVED              (0x02)
+#define MPI26_PCIELINK3_EVTCODE_FATAL_ERROR_RECEIVED                  (0x03)
+#define MPI26_PCIELINK3_EVTCODE_DATA_LINK_ERROR_DETECTED              (0x04)
+#define MPI26_PCIELINK3_EVTCODE_TRANSACTION_LAYER_ERROR_DETECTED      (0x05)
+#define MPI26_PCIELINK3_EVTCODE_TLP_ECRC_ERROR_DETECTED               (0x06)
+#define MPI26_PCIELINK3_EVTCODE_POISONED_TLP                          (0x07)
+#define MPI26_PCIELINK3_EVTCODE_RECEIVED_NAK_DLLP                     (0x08)
+#define MPI26_PCIELINK3_EVTCODE_SENT_NAK_DLLP                         (0x09)
+#define MPI26_PCIELINK3_EVTCODE_LTSSM_RECOVERY_STATE                  (0x0A)
+#define MPI26_PCIELINK3_EVTCODE_LTSSM_RXL0S_STATE                     (0x0B)
+#define MPI26_PCIELINK3_EVTCODE_LTSSM_TXL0S_STATE                     (0x0C)
+#define MPI26_PCIELINK3_EVTCODE_LTSSM_L1_STATE                        (0x0D)
+#define MPI26_PCIELINK3_EVTCODE_LTSSM_DISABLED_STATE                  (0x0E)
+#define MPI26_PCIELINK3_EVTCODE_LTSSM_HOT_RESET_STATE                 (0x0F)
+#define MPI26_PCIELINK3_EVTCODE_SYSTEM_ERROR                          (0x10)
+#define MPI26_PCIELINK3_EVTCODE_DECODE_ERROR                          (0x11)
+#define MPI26_PCIELINK3_EVTCODE_DISPARITY_ERROR                       (0x12)
+
+/*values for the CounterType field */
+#define MPI26_PCIELINK3_COUNTER_TYPE_WRAPPING               (0x00)
+#define MPI26_PCIELINK3_COUNTER_TYPE_SATURATING             (0x01)
+#define MPI26_PCIELINK3_COUNTER_TYPE_PEAK_VALUE             (0x02)
+
+/*values for the TimeUnits field */
+#define MPI26_PCIELINK3_TM_UNITS_10_MICROSECONDS            (0x00)
+#define MPI26_PCIELINK3_TM_UNITS_100_MICROSECONDS           (0x01)
+#define MPI26_PCIELINK3_TM_UNITS_1_MILLISECOND              (0x02)
+#define MPI26_PCIELINK3_TM_UNITS_10_MILLISECONDS            (0x03)
+
+/*values for the ThresholdFlags field */
+#define MPI26_PCIELINK3_TFLAGS_EVENT_NOTIFY                 (0x0001)
+
+/*
+ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ *one and check the value returned for NumLinkEvents at runtime.
+ */
+#ifndef MPI26_PCIELINK3_LINK_EVENT_MAX
+#define MPI26_PCIELINK3_LINK_EVENT_MAX      (1)
+#endif
+
+typedef struct _MPI26_CONFIG_PAGE_PCIELINK_3 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER
+		Header;                     /*0x00 */
+	U8
+		Link;                       /*0x08 */
+	U8
+		Reserved1;                  /*0x09 */
+	U16
+		Reserved2;                  /*0x0A */
+	U8
+		NumLinkEvents;              /*0x0C */
+	U8
+		Reserved3;                  /*0x0D */
+	U16
+		Reserved4;                  /*0x0E */
+	MPI26_PCIELINK3_LINK_EVENT_CONFIG
+		LinkEventConfig[MPI26_PCIELINK3_LINK_EVENT_MAX]; /*0x10 */
+} MPI26_CONFIG_PAGE_PCIELINK_3, *PTR_MPI26_CONFIG_PAGE_PCIELINK_3,
+	Mpi26PcieLinkPage3_t, *pMpi26PcieLinkPage3_t;
+
+#define MPI26_PCIELINK3_PAGEVERSION            (0x00)
+
+
 #endif
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_init.h b/drivers/scsi/mpt3sas/mpi/mpi2_init.h
index bba56b6..7597c24 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_init.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_init.h
@@ -6,7 +6,7 @@
  *         Title:  MPI SCSI initiator mode messages and structures
  * Creation Date:  June 23, 2006
  *
- * mpi2_init.h Version:  02.00.20
+ * mpi2_init.h Version:  02.00.21
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *       prefix are for use only on MPI v2.5 products, and must not be used
@@ -54,6 +54,8 @@
  * 08-26-15  02.00.18  Added SCSITASKMGMT_MSGFLAGS for Target Reset.
  * 12-18-15  02.00.19  Added EEDPObservedValue added to SCSI IO Reply message.
  * 01-04-16  02.00.20  Modified EEDP reported values in SCSI IO Reply message.
+ * 01-21-16  02.00.21  Modified MPI26_SCSITASKMGMT_MSGFLAGS_PCIE* defines to
+ *                     be unique within first 32 characters.
  * --------------------------------------------------------------------------
  */
 
@@ -373,6 +375,11 @@ typedef struct _MPI2_SCSI_IO_REPLY {
 } MPI2_SCSI_IO_REPLY, *PTR_MPI2_SCSI_IO_REPLY,
 	Mpi2SCSIIOReply_t, *pMpi2SCSIIOReply_t;
 
+/*SCSI IO Reply MsgFlags bits */
+#define MPI26_SCSIIO_REPLY_MSGFLAGS_REFTAG_OBSERVED_VALID     (0x01)
+#define MPI26_SCSIIO_REPLY_MSGFLAGS_GUARD_OBSERVED_VALID      (0x02)
+#define MPI26_SCSIIO_REPLY_MSGFLAGS_APPTAG_OBSERVED_VALID     (0x04)
+
 /*SCSI IO Reply SCSIStatus values (SAM-4 status codes) */
 
 #define MPI2_SCSI_STATUS_GOOD                   (0x00)
@@ -446,11 +453,13 @@ typedef struct _MPI2_SCSI_TASK_MANAGE_REQUEST {
 /*MsgFlags bits */
 
 #define MPI2_SCSITASKMGMT_MSGFLAGS_MASK_TARGET_RESET    (0x18)
+#define MPI26_SCSITASKMGMT_MSGFLAGS_HOT_RESET_PCIE        (0x00)
 #define MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET           (0x00)
 #define MPI2_SCSITASKMGMT_MSGFLAGS_NEXUS_RESET_SRST     (0x08)
 #define MPI2_SCSITASKMGMT_MSGFLAGS_SAS_HARD_LINK_RESET  (0x10)
 
 #define MPI2_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU  (0x01)
+#define MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE (0x18)
 
 /*SCSI Task Management Reply Message */
 typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY {
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
index af4be40..816ade3 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
@@ -6,7 +6,7 @@
  *         Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  * Creation Date:  October 11, 2006
  *
- * mpi2_ioc.h Version:  02.00.27
+ * mpi2_ioc.h Version:  02.00.32
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *       prefix are for use only on MPI v2.5 products, and must not be used
@@ -140,7 +140,32 @@
  *                     Added MPI26_FW_HEADER_PID_FAMILY_3324_SAS and
  *                     MPI26_FW_HEADER_PID_FAMILY_3516_SAS.
  *                     Added MPI26_CTRL_OP_SHUTDOWN.
- * 08-25-15  02.00.27  Added IC ARCH Class based signature defines
+ * 08-25-15  02.00.27  Added IC ARCH Class based signature defines.
+ *                     Added MPI26_EVENT_PCIE_ENUM_ES_RESOURCES_EXHAUSTED event.
+ *                     Added ConigurationFlags field to IOCInit message to
+ *                     support NVMe SGL format control.
+ *                     Added PCIe SRIOV support.
+ * 02-17-16   02.00.28 Added SAS 4 22.5 gbs speed support.
+ *                     Added PCIe 4 16.0 GT/sec speec support.
+ *                     Removed AHCI support.
+ *                     Removed SOP support.
+ * 07-01-16   02.00.29 Added Archclass for 4008 product.
+ *                     Added IOCException MPI2_IOCFACTS_EXCEPT_PCIE_DISABLED
+ * 08-23-16   02.00.30 Added new defines for the ImageType field of FWDownload
+ *                     Request Message.
+ *                     Added new defines for the ImageType field of FWUpload
+ *                     Request Message.
+ *                     Added new values for the RegionType field in the Layout
+ *                     Data sections of the FLASH Layout Extended Image Data.
+ *                     Added new defines for the ReasonCode field of
+ *                     Active Cable Exception Event.
+ *                     Added MPI2_EVENT_ENCL_DEVICE_STATUS_CHANGE and
+ *                     MPI26_EVENT_DATA_ENCL_DEV_STATUS_CHANGE.
+ * 11-23-16   02.00.31 Added MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR and
+ *                     MPI25_EVENT_DATA_SAS_DEVICE_DISCOVERY_ERROR.
+ * 02-02-17   02.00.32 Added MPI2_FW_DOWNLOAD_ITYPE_CBB_BACKUP.
+ *                     Added MPI25_EVENT_DATA_ACTIVE_CABLE_EXCEPT and related
+ *                     defines for the ReasonCode field.
  * --------------------------------------------------------------------------
  */
 
@@ -212,6 +237,9 @@ typedef struct _MPI2_IOC_INIT_REQUEST {
 #define MPI2_IOCINIT_HDRVERSION_DEV_MASK        (0x00FF)
 #define MPI2_IOCINIT_HDRVERSION_DEV_SHIFT       (0)
 
+/*ConfigurationFlags */
+#define MPI26_IOCINIT_CFGFLAGS_NVME_SGL_FORMAT  (0x0001)
+
 /*minimum depth for a Reply Descriptor Post Queue */
 #define MPI2_RDPQ_DEPTH_MIN                     (16)
 
@@ -299,6 +327,10 @@ typedef struct _MPI2_IOC_FACTS_REPLY {
 	U16 MinDevHandle;	/*0x3C */
 	U8 CurrentHostPageSize;	/* 0x3E */
 	U8 Reserved4;		/* 0x3F */
+	U8 SGEModifierMask;	/*0x40 */
+	U8 SGEModifierValue;	/*0x41 */
+	U8 SGEModifierShift;	/*0x42 */
+	U8 Reserved5;		/*0x43 */
 } MPI2_IOC_FACTS_REPLY, *PTR_MPI2_IOC_FACTS_REPLY,
 	Mpi2IOCFactsReply_t, *pMpi2IOCFactsReply_t;
 
@@ -315,6 +347,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY {
 #define MPI2_IOCFACTS_HDRVERSION_DEV_SHIFT              (0)
 
 /*IOCExceptions */
+#define MPI2_IOCFACTS_EXCEPT_PCIE_DISABLED              (0x0400)
 #define MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE     (0x0200)
 #define MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX      (0x0100)
 
@@ -335,6 +368,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY {
 /*ProductID field uses MPI2_FW_HEADER_PID_ */
 
 /*IOCCapabilities */
+#define MPI26_IOCFACTS_CAPABILITY_PCIE_SRIOV            (0x00100000)
 #define MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ            (0x00080000)
 #define MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE     (0x00040000)
 #define MPI25_IOCFACTS_CAPABILITY_FAST_PATH_CAPABLE     (0x00020000)
@@ -353,6 +387,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY {
 #define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004)
 
 /*ProtocolFlags */
+#define MPI2_IOCFACTS_PROTOCOL_NVME_DEVICES             (0x0008)
 #define MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR           (0x0002)
 #define MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET              (0x0001)
 
@@ -402,6 +437,8 @@ typedef struct _MPI2_PORT_FACTS_REPLY {
 #define MPI2_PORTFACTS_PORTTYPE_ISCSI               (0x20)
 #define MPI2_PORTFACTS_PORTTYPE_SAS_PHYSICAL        (0x30)
 #define MPI2_PORTFACTS_PORTTYPE_SAS_VIRTUAL         (0x31)
+#define MPI2_PORTFACTS_PORTTYPE_TRI_MODE            (0x40)
+
 
 /****************************************************************************
 * PortEnable message
@@ -508,6 +545,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY {
 #define MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW          (0x0019)
 #define MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST         (0x001C)
 #define MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE    (0x001D)
+#define MPI2_EVENT_ENCL_DEVICE_STATUS_CHANGE        (0x001D)
 #define MPI2_EVENT_IR_VOLUME                        (0x001E)
 #define MPI2_EVENT_IR_PHYSICAL_DISK                 (0x001F)
 #define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST     (0x0020)
@@ -520,7 +558,12 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY {
 #define MPI2_EVENT_TEMP_THRESHOLD                   (0x0027)
 #define MPI2_EVENT_HOST_MESSAGE                     (0x0028)
 #define MPI2_EVENT_POWER_PERFORMANCE_CHANGE         (0x0029)
+#define MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE        (0x0030)
+#define MPI2_EVENT_PCIE_ENUMERATION                 (0x0031)
+#define MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST        (0x0032)
+#define MPI2_EVENT_PCIE_LINK_COUNTER                (0x0033)
 #define MPI2_EVENT_ACTIVE_CABLE_EXCEPTION           (0x0034)
+#define MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR       (0x0035)
 #define MPI2_EVENT_MIN_PRODUCT_SPECIFIC             (0x006E)
 #define MPI2_EVENT_MAX_PRODUCT_SPECIFIC             (0x007F)
 
@@ -617,11 +660,20 @@ typedef struct _MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT {
 	U8          ReasonCode;                         /* 0x04 */
 	U8          ReceptacleID;                       /* 0x05 */
 	U16         Reserved1;                          /* 0x06 */
-} MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
+} MPI25_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
+	*PTR_MPI25_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
+	Mpi25EventDataActiveCableExcept_t,
+	*pMpi25EventDataActiveCableExcept_t,
+	MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
 	*PTR_MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
 	Mpi26EventDataActiveCableExcept_t,
 	*pMpi26EventDataActiveCableExcept_t;
 
+/*MPI2.5 defines for the ReasonCode field */
+#define MPI25_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER     (0x00)
+#define MPI25_EVENT_ACTIVE_CABLE_PRESENT                (0x01)
+#define MPI25_EVENT_ACTIVE_CABLE_DEGRADED               (0x02)
+
 /* defines for ReasonCode field */
 #define MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER     (0x00)
 #define MPI26_EVENT_ACTIVE_CABLE_PRESENT                (0x01)
@@ -957,6 +1009,7 @@ typedef struct _MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST {
 #define MPI2_EVENT_SAS_TOPO_LR_RATE_3_0                     (0x09)
 #define MPI2_EVENT_SAS_TOPO_LR_RATE_6_0                     (0x0A)
 #define MPI25_EVENT_SAS_TOPO_LR_RATE_12_0                   (0x0B)
+#define MPI26_EVENT_SAS_TOPO_LR_RATE_22_5                   (0x0C)
 
 /*values for the PhyStatus field */
 #define MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT                (0x80)
@@ -982,12 +1035,43 @@ typedef struct _MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE {
 } MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE,
 	*PTR_MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE,
 	Mpi2EventDataSasEnclDevStatusChange_t,
-	*pMpi2EventDataSasEnclDevStatusChange_t;
+	*pMpi2EventDataSasEnclDevStatusChange_t,
+	MPI26_EVENT_DATA_ENCL_DEV_STATUS_CHANGE,
+	*PTR_MPI26_EVENT_DATA_ENCL_DEV_STATUS_CHANGE,
+	Mpi26EventDataEnclDevStatusChange_t,
+	*pMpi26EventDataEnclDevStatusChange_t;
 
 /*SAS Enclosure Device Status Change event ReasonCode values */
 #define MPI2_EVENT_SAS_ENCL_RC_ADDED                (0x01)
 #define MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING       (0x02)
 
+/*Enclosure Device Status Change event ReasonCode values */
+#define MPI26_EVENT_ENCL_RC_ADDED                   (0x01)
+#define MPI26_EVENT_ENCL_RC_NOT_RESPONDING          (0x02)
+
+
+typedef struct _MPI25_EVENT_DATA_SAS_DEVICE_DISCOVERY_ERROR {
+	U16
+		DevHandle;                  /*0x00 */
+	U8
+		ReasonCode;                 /*0x02 */
+	U8
+		PhysicalPort;               /*0x03 */
+	U32
+		Reserved1[2];               /*0x04 */
+	U64
+		SASAddress;                 /*0x0C */
+	U32
+		Reserved2[2];               /*0x14 */
+} MPI25_EVENT_DATA_SAS_DEVICE_DISCOVERY_ERROR,
+	*PTR_MPI25_EVENT_DATA_SAS_DEVICE_DISCOVERY_ERROR,
+	Mpi25EventDataSasDeviceDiscoveryError_t,
+	*pMpi25EventDataSasDeviceDiscoveryError_t;
+
+/*SAS Device Discovery Error Event data ReasonCode values */
+#define MPI25_EVENT_SAS_DISC_ERR_SMP_FAILED         (0x01)
+#define MPI25_EVENT_SAS_DISC_ERR_SMP_TIMEOUT        (0x02)
+
 /*SAS PHY Counter Event data */
 
 typedef struct _MPI2_EVENT_DATA_SAS_PHY_COUNTER {
@@ -1073,6 +1157,217 @@ typedef struct _MPI2_EVENT_DATA_HBD_PHY {
 /*values for the DescriptorType field */
 #define MPI2_EVENT_HBD_DT_SAS               (0x01)
 
+
+/*PCIe Device Status Change Event data (MPI v2.6 and later) */
+
+typedef struct _MPI26_EVENT_DATA_PCIE_DEVICE_STATUS_CHANGE {
+	U16
+		TaskTag;                        /*0x00 */
+	U8
+		ReasonCode;                     /*0x02 */
+	U8
+		PhysicalPort;                   /*0x03 */
+	U8
+		ASC;                            /*0x04 */
+	U8
+		ASCQ;                           /*0x05 */
+	U16
+		DevHandle;                      /*0x06 */
+	U32
+		Reserved2;                      /*0x08 */
+	U64
+		WWID;                           /*0x0C */
+	U8
+		LUN[8];                         /*0x14 */
+} MPI26_EVENT_DATA_PCIE_DEVICE_STATUS_CHANGE,
+	*PTR_MPI26_EVENT_DATA_PCIE_DEVICE_STATUS_CHANGE,
+	Mpi26EventDataPCIeDeviceStatusChange_t,
+	*pMpi26EventDataPCIeDeviceStatusChange_t;
+
+/*PCIe Device Status Change Event data ReasonCode values */
+#define MPI26_EVENT_PCIDEV_STAT_RC_SMART_DATA                           (0x05)
+#define MPI26_EVENT_PCIDEV_STAT_RC_UNSUPPORTED                          (0x07)
+#define MPI26_EVENT_PCIDEV_STAT_RC_INTERNAL_DEVICE_RESET                (0x08)
+#define MPI26_EVENT_PCIDEV_STAT_RC_TASK_ABORT_INTERNAL                  (0x09)
+#define MPI26_EVENT_PCIDEV_STAT_RC_ABORT_TASK_SET_INTERNAL              (0x0A)
+#define MPI26_EVENT_PCIDEV_STAT_RC_CLEAR_TASK_SET_INTERNAL              (0x0B)
+#define MPI26_EVENT_PCIDEV_STAT_RC_QUERY_TASK_INTERNAL                  (0x0C)
+#define MPI26_EVENT_PCIDEV_STAT_RC_ASYNC_NOTIFICATION                   (0x0D)
+#define MPI26_EVENT_PCIDEV_STAT_RC_CMP_INTERNAL_DEV_RESET               (0x0E)
+#define MPI26_EVENT_PCIDEV_STAT_RC_CMP_TASK_ABORT_INTERNAL              (0x0F)
+#define MPI26_EVENT_PCIDEV_STAT_RC_DEV_INIT_FAILURE                     (0x10)
+
+
+/*PCIe Enumeration Event data (MPI v2.6 and later) */
+
+typedef struct _MPI26_EVENT_DATA_PCIE_ENUMERATION {
+	U8
+		Flags;                      /*0x00 */
+	U8
+		ReasonCode;                 /*0x01 */
+	U8
+		PhysicalPort;               /*0x02 */
+	U8
+		Reserved1;                  /*0x03 */
+	U32
+		EnumerationStatus;          /*0x04 */
+} MPI26_EVENT_DATA_PCIE_ENUMERATION,
+	*PTR_MPI26_EVENT_DATA_PCIE_ENUMERATION,
+	Mpi26EventDataPCIeEnumeration_t,
+	*pMpi26EventDataPCIeEnumeration_t;
+
+/*PCIe Enumeration Event data Flags values */
+#define MPI26_EVENT_PCIE_ENUM_DEVICE_CHANGE                 (0x02)
+#define MPI26_EVENT_PCIE_ENUM_IN_PROGRESS                   (0x01)
+
+/*PCIe Enumeration Event data ReasonCode values */
+#define MPI26_EVENT_PCIE_ENUM_RC_STARTED                    (0x01)
+#define MPI26_EVENT_PCIE_ENUM_RC_COMPLETED                  (0x02)
+
+/*PCIe Enumeration Event data EnumerationStatus values */
+#define MPI26_EVENT_PCIE_ENUM_ES_MAX_SWITCHES_EXCEED            (0x40000000)
+#define MPI26_EVENT_PCIE_ENUM_ES_MAX_DEVICES_EXCEED             (0x20000000)
+#define MPI26_EVENT_PCIE_ENUM_ES_RESOURCES_EXHAUSTED            (0x10000000)
+
+
+/*PCIe Topology Change List Event data (MPI v2.6 and later) */
+
+/*
+ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ *one and check NumEntries at runtime.
+ */
+#ifndef MPI26_EVENT_PCIE_TOPO_PORT_COUNT
+#define MPI26_EVENT_PCIE_TOPO_PORT_COUNT        (1)
+#endif
+
+typedef struct _MPI26_EVENT_PCIE_TOPO_PORT_ENTRY {
+	U16
+		AttachedDevHandle;      /*0x00 */
+	U8
+		PortStatus;             /*0x02 */
+	U8
+		Reserved1;              /*0x03 */
+	U8
+		CurrentPortInfo;        /*0x04 */
+	U8
+		Reserved2;              /*0x05 */
+	U8
+		PreviousPortInfo;       /*0x06 */
+	U8
+		Reserved3;              /*0x07 */
+} MPI26_EVENT_PCIE_TOPO_PORT_ENTRY,
+	*PTR_MPI26_EVENT_PCIE_TOPO_PORT_ENTRY,
+	Mpi26EventPCIeTopoPortEntry_t,
+	*pMpi26EventPCIeTopoPortEntry_t;
+
+/*PCIe Topology Change List Event data PortStatus values */
+#define MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED                  (0x01)
+#define MPI26_EVENT_PCIE_TOPO_PS_NOT_RESPONDING             (0x02)
+#define MPI26_EVENT_PCIE_TOPO_PS_PORT_CHANGED               (0x03)
+#define MPI26_EVENT_PCIE_TOPO_PS_NO_CHANGE                  (0x04)
+#define MPI26_EVENT_PCIE_TOPO_PS_DELAY_NOT_RESPONDING       (0x05)
+
+/*PCIe Topology Change List Event data defines for CurrentPortInfo and
+ *PreviousPortInfo
+ */
+#define MPI26_EVENT_PCIE_TOPO_PI_LANE_MASK                  (0xF0)
+#define MPI26_EVENT_PCIE_TOPO_PI_LANES_UNKNOWN              (0x00)
+#define MPI26_EVENT_PCIE_TOPO_PI_1_LANE                     (0x10)
+#define MPI26_EVENT_PCIE_TOPO_PI_2_LANES                    (0x20)
+#define MPI26_EVENT_PCIE_TOPO_PI_4_LANES                    (0x30)
+#define MPI26_EVENT_PCIE_TOPO_PI_8_LANES                    (0x40)
+
+#define MPI26_EVENT_PCIE_TOPO_PI_RATE_MASK                  (0x0F)
+#define MPI26_EVENT_PCIE_TOPO_PI_RATE_UNKNOWN               (0x00)
+#define MPI26_EVENT_PCIE_TOPO_PI_RATE_DISABLED              (0x01)
+#define MPI26_EVENT_PCIE_TOPO_PI_RATE_2_5                   (0x02)
+#define MPI26_EVENT_PCIE_TOPO_PI_RATE_5_0                   (0x03)
+#define MPI26_EVENT_PCIE_TOPO_PI_RATE_8_0                   (0x04)
+#define MPI26_EVENT_PCIE_TOPO_PI_RATE_16_0                  (0x05)
+
+typedef struct _MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST {
+	U16
+		EnclosureHandle;        /*0x00 */
+	U16
+		SwitchDevHandle;        /*0x02 */
+	U8
+		NumPorts;               /*0x04 */
+	U8
+		Reserved1;              /*0x05 */
+	U16
+		Reserved2;              /*0x06 */
+	U8
+		NumEntries;             /*0x08 */
+	U8
+		StartPortNum;           /*0x09 */
+	U8
+		SwitchStatus;           /*0x0A */
+	U8
+		PhysicalPort;           /*0x0B */
+	MPI26_EVENT_PCIE_TOPO_PORT_ENTRY
+		PortEntry[MPI26_EVENT_PCIE_TOPO_PORT_COUNT]; /*0x0C */
+} MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST,
+	*PTR_MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST,
+	Mpi26EventDataPCIeTopologyChangeList_t,
+	*pMpi26EventDataPCIeTopologyChangeList_t;
+
+/*PCIe Topology Change List Event data SwitchStatus values */
+#define MPI26_EVENT_PCIE_TOPO_SS_NO_PCIE_SWITCH             (0x00)
+#define MPI26_EVENT_PCIE_TOPO_SS_ADDED                      (0x01)
+#define MPI26_EVENT_PCIE_TOPO_SS_NOT_RESPONDING             (0x02)
+#define MPI26_EVENT_PCIE_TOPO_SS_RESPONDING                 (0x03)
+#define MPI26_EVENT_PCIE_TOPO_SS_DELAY_NOT_RESPONDING       (0x04)
+
+/*PCIe Link Counter Event data (MPI v2.6 and later) */
+
+typedef struct _MPI26_EVENT_DATA_PCIE_LINK_COUNTER {
+	U64
+		TimeStamp;          /*0x00 */
+	U32
+		Reserved1;          /*0x08 */
+	U8
+		LinkEventCode;      /*0x0C */
+	U8
+		LinkNum;            /*0x0D */
+	U16
+		Reserved2;          /*0x0E */
+	U32
+		LinkEventInfo;      /*0x10 */
+	U8
+		CounterType;        /*0x14 */
+	U8
+		ThresholdWindow;    /*0x15 */
+	U8
+		TimeUnits;          /*0x16 */
+	U8
+		Reserved3;          /*0x17 */
+	U32
+		EventThreshold;     /*0x18 */
+	U16
+		ThresholdFlags;     /*0x1C */
+	U16
+		Reserved4;          /*0x1E */
+} MPI26_EVENT_DATA_PCIE_LINK_COUNTER,
+	*PTR_MPI26_EVENT_DATA_PCIE_LINK_COUNTER,
+	Mpi26EventDataPcieLinkCounter_t, *pMpi26EventDataPcieLinkCounter_t;
+
+
+/*use MPI26_PCIELINK3_EVTCODE_ values from mpi2_cnfg.h for the LinkEventCode
+ *field
+ */
+
+/*use MPI26_PCIELINK3_COUNTER_TYPE_ values from mpi2_cnfg.h for the CounterType
+ *field
+ */
+
+/*use MPI26_PCIELINK3_TIME_UNITS_ values from mpi2_cnfg.h for the TimeUnits
+ *field
+ */
+
+/*use MPI26_PCIELINK3_TFLAGS_ values from mpi2_cnfg.h for the ThresholdFlags
+ *field
+ */
+
 /****************************************************************************
 * EventAck message
 ****************************************************************************/
@@ -1190,6 +1485,14 @@ typedef struct _MPI2_FW_DOWNLOAD_REQUEST {
 #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_CBB_BACKUP           (0x0D)
+#define MPI2_FW_DOWNLOAD_ITYPE_SBR                  (0x0E)
+#define MPI2_FW_DOWNLOAD_ITYPE_SBR_BACKUP           (0x0F)
+#define MPI2_FW_DOWNLOAD_ITYPE_HIIM                 (0x10)
+#define MPI2_FW_DOWNLOAD_ITYPE_HIIA                 (0x11)
+#define MPI2_FW_DOWNLOAD_ITYPE_CTLR                 (0x12)
+#define MPI2_FW_DOWNLOAD_ITYPE_IMR_FIRMWARE         (0x13)
+#define MPI2_FW_DOWNLOAD_ITYPE_MR_NVDATA            (0x14)
 #define MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC (0xF0)
 
 /*MPI v2.0 FWDownload TransactionContext Element */
@@ -1276,6 +1579,14 @@ typedef struct _MPI2_FW_UPLOAD_REQUEST {
 #define MPI2_FW_UPLOAD_ITYPE_COMPLETE           (0x0A)
 #define MPI2_FW_UPLOAD_ITYPE_COMMON_BOOT_BLOCK  (0x0B)
 #define MPI2_FW_UPLOAD_ITYPE_CBB_BACKUP         (0x0D)
+#define MPI2_FW_UPLOAD_ITYPE_SBR                (0x0E)
+#define MPI2_FW_UPLOAD_ITYPE_SBR_BACKUP         (0x0F)
+#define MPI2_FW_UPLOAD_ITYPE_HIIM               (0x10)
+#define MPI2_FW_UPLOAD_ITYPE_HIIA               (0x11)
+#define MPI2_FW_UPLOAD_ITYPE_CTLR               (0x12)
+#define MPI2_FW_UPLOAD_ITYPE_IMR_FIRMWARE       (0x13)
+#define MPI2_FW_UPLOAD_ITYPE_MR_NVDATA          (0x14)
+
 
 /*MPI v2.0 FWUpload TransactionContext Element */
 typedef struct _MPI2_FW_UPLOAD_TCSGE {
@@ -1394,10 +1705,13 @@ typedef struct _MPI2_FW_IMAGE_HEADER {
 #define MPI26_FW_HEADER_SIGNATURE0_ARC_1        (0x00)
 #define MPI26_FW_HEADER_SIGNATURE0_ARC_2        (0x01)
 /* legacy (0x5AEAA55A) */
+#define MPI26_FW_HEADER_SIGNATURE0_ARC_3        (0x02)
 #define MPI26_FW_HEADER_SIGNATURE0 \
 	(MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_0)
 #define MPI26_FW_HEADER_SIGNATURE0_3516 \
 	(MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_1)
+#define MPI26_FW_HEADER_SIGNATURE0_4008 \
+	(MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_3)
 
 /*Signature1 field */
 #define MPI2_FW_HEADER_SIGNATURE1_OFFSET        (0x08)
@@ -1541,6 +1855,13 @@ typedef struct _MPI2_FLASH_LAYOUT_DATA {
 #define MPI2_FLASH_REGION_COMMON_BOOT_BLOCK     (0x0A)
 #define MPI2_FLASH_REGION_INIT (MPI2_FLASH_REGION_COMMON_BOOT_BLOCK)
 #define MPI2_FLASH_REGION_CBB_BACKUP            (0x0D)
+#define MPI2_FLASH_REGION_SBR                   (0x0E)
+#define MPI2_FLASH_REGION_SBR_BACKUP            (0x0F)
+#define MPI2_FLASH_REGION_HIIM                  (0x10)
+#define MPI2_FLASH_REGION_HIIA                  (0x11)
+#define MPI2_FLASH_REGION_CTLR                  (0x12)
+#define MPI2_FLASH_REGION_IMR_FIRMWARE          (0x13)
+#define MPI2_FLASH_REGION_MR_NVDATA             (0x14)
 
 /*ImageRevision */
 #define MPI2_FLASH_LAYOUT_IMAGE_REVISION        (0x00)
@@ -1825,6 +2146,8 @@ typedef struct _MPI26_IOUNIT_CONTROL_REQUEST {
 #define MPI26_CTRL_OP_DEV_ENABLE_PERSIST_CONNECTION     (0x17)
 #define MPI26_CTRL_OP_DEV_DISABLE_PERSIST_CONNECTION    (0x18)
 #define MPI26_CTRL_OP_DEV_CLOSE_PERSIST_CONNECTION      (0x19)
+#define MPI26_CTRL_OP_ENABLE_NVME_SGL_FORMAT            (0x1A)
+#define MPI26_CTRL_OP_DISABLE_NVME_SGL_FORMAT           (0x1B)
 #define MPI26_CTRL_OP_PRODUCT_SPECIFIC_MIN              (0x80)
 
 /* values for the PrimFlags field */
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_pci.h b/drivers/scsi/mpt3sas/mpi/mpi2_pci.h
new file mode 100644
index 0000000..52ea213
--- /dev/null
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_pci.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2012-2015 Avago Technologies.  All rights reserved.
+ *
+ *
+ *          Name:  mpi2_pci.h
+ *         Title:  MPI PCIe Attached Devices structures and definitions.
+ * Creation Date:  October 9, 2012
+ *
+ * mpi2_pci.h Version:  02.00.02
+ *
+ * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
+ *       prefix are for use only on MPI v2.5 products, and must not be used
+ *       with MPI v2.0 products. Unless otherwise noted, names beginning with
+ *       MPI2 or Mpi2 are for use with both MPI v2.0 and MPI v2.5 products.
+ *
+ * Version History
+ * ---------------
+ *
+ * Date      Version   Description
+ * --------  --------  ------------------------------------------------------
+ * 03-16-15  02.00.00  Initial version.
+ * 02-17-16  02.00.01  Removed AHCI support.
+ *                     Removed SOP support.
+ * 07-01-16  02.00.02  Added MPI26_NVME_FLAGS_FORCE_ADMIN_ERR_RESP to
+ *                     NVME Encapsulated Request.
+ * --------------------------------------------------------------------------
+ */
+
+#ifndef MPI2_PCI_H
+#define MPI2_PCI_H
+
+
+/*
+ *Values for the PCIe DeviceInfo field used in PCIe Device Status Change Event
+ *data and PCIe Configuration pages.
+ */
+#define MPI26_PCIE_DEVINFO_DIRECT_ATTACH        (0x00000010)
+
+#define MPI26_PCIE_DEVINFO_MASK_DEVICE_TYPE     (0x0000000F)
+#define MPI26_PCIE_DEVINFO_NO_DEVICE            (0x00000000)
+#define MPI26_PCIE_DEVINFO_PCI_SWITCH           (0x00000001)
+#define MPI26_PCIE_DEVINFO_NVME                 (0x00000003)
+
+
+/****************************************************************************
+*  NVMe Encapsulated message
+****************************************************************************/
+
+/*NVME Encapsulated Request Message */
+typedef struct _MPI26_NVME_ENCAPSULATED_REQUEST {
+	U16
+		DevHandle;                      /*0x00 */
+	U8
+		ChainOffset;                    /*0x02 */
+	U8
+		Function;                       /*0x03 */
+	U16
+		EncapsulatedCommandLength;      /*0x04 */
+	U8
+		Reserved1;                      /*0x06 */
+	U8
+		MsgFlags;                       /*0x07 */
+	U8
+		VP_ID;                          /*0x08 */
+	U8
+		VF_ID;                          /*0x09 */
+	U16
+		Reserved2;                      /*0x0A */
+	U32
+		Reserved3;                      /*0x0C */
+	U64
+		ErrorResponseBaseAddress;       /*0x10 */
+	U16
+		ErrorResponseAllocationLength;  /*0x18 */
+	U16
+		Flags;                          /*0x1A */
+	U32
+		DataLength;                     /*0x1C */
+	U8
+		NVMe_Command[4];                /*0x20 */
+
+} MPI26_NVME_ENCAPSULATED_REQUEST, *PTR_MPI26_NVME_ENCAPSULATED_REQUEST,
+	Mpi26NVMeEncapsulatedRequest_t, *pMpi26NVMeEncapsulatedRequest_t;
+
+/*defines for the Flags field */
+#define MPI26_NVME_FLAGS_FORCE_ADMIN_ERR_RESP       (0x0020)
+/*Submission Queue Type*/
+#define MPI26_NVME_FLAGS_SUBMISSIONQ_MASK           (0x0010)
+#define MPI26_NVME_FLAGS_SUBMISSIONQ_IO             (0x0000)
+#define MPI26_NVME_FLAGS_SUBMISSIONQ_ADMIN          (0x0010)
+/*Error Response Address Space */
+#define MPI26_NVME_FLAGS_MASK_ERROR_RSP_ADDR        (0x000C)
+#define MPI26_NVME_FLAGS_SYSTEM_RSP_ADDR            (0x0000)
+#define MPI26_NVME_FLAGS_IOCPLB_RSP_ADDR            (0x0008)
+#define MPI26_NVME_FLAGS_IOCPLBNTA_RSP_ADDR         (0x000C)
+/*Data Direction*/
+#define MPI26_NVME_FLAGS_DATADIRECTION_MASK         (0x0003)
+#define MPI26_NVME_FLAGS_NODATATRANSFER             (0x0000)
+#define MPI26_NVME_FLAGS_WRITE                      (0x0001)
+#define MPI26_NVME_FLAGS_READ                       (0x0002)
+#define MPI26_NVME_FLAGS_BIDIRECTIONAL              (0x0003)
+
+
+/*NVMe Encapuslated Reply Message */
+typedef struct _MPI26_NVME_ENCAPSULATED_ERROR_REPLY {
+	U16
+		DevHandle;                      /*0x00 */
+	U8
+		MsgLength;                      /*0x02 */
+	U8
+		Function;                       /*0x03 */
+	U16
+		EncapsulatedCommandLength;      /*0x04 */
+	U8
+		Reserved1;                      /*0x06 */
+	U8
+		MsgFlags;                       /*0x07 */
+	U8
+		VP_ID;                          /*0x08 */
+	U8
+		VF_ID;                          /*0x09 */
+	U16
+		Reserved2;                      /*0x0A */
+	U16
+		Reserved3;                      /*0x0C */
+	U16
+		IOCStatus;                      /*0x0E */
+	U32
+		IOCLogInfo;                     /*0x10 */
+	U16
+		ErrorResponseCount;             /*0x14 */
+	U16
+		Reserved4;                      /*0x16 */
+} MPI26_NVME_ENCAPSULATED_ERROR_REPLY,
+	*PTR_MPI26_NVME_ENCAPSULATED_ERROR_REPLY,
+	Mpi26NVMeEncapsulatedErrorReply_t,
+	*pMpi26NVMeEncapsulatedErrorReply_t;
+
+
+#endif
+
+
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_tool.h b/drivers/scsi/mpt3sas/mpi/mpi2_tool.h
index 5f9289a..4286c91 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_tool.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_tool.h
@@ -6,7 +6,7 @@
  *         Title:  MPI diagnostic tool structures and definitions
  * Creation Date:  March 26, 2007
  *
- *   mpi2_tool.h Version:  02.00.13
+ *   mpi2_tool.h Version:  02.00.14
  *
  * Version History
  * ---------------
@@ -35,6 +35,8 @@
  * 08-19-13  02.00.11  Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info.
  * 01-08-14  02.00.12  Added MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC.
  * 11-18-14  02.00.13  Updated copyright information.
+ * 08-25-16  02.00.14  Added new values for the Flags field of Toolbox Clean
+ *                     Tool Request Message.
  * --------------------------------------------------------------------------
  */
 
@@ -105,6 +107,16 @@ typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST {
 #define MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC   (0x04000000)
 #define MPI2_TOOLBOX_CLEAN_MEGARAID                 (0x02000000)
 #define MPI2_TOOLBOX_CLEAN_INITIALIZATION           (0x01000000)
+#define MPI2_TOOLBOX_CLEAN_SBR                      (0x00800000)
+#define MPI2_TOOLBOX_CLEAN_SBR_BACKUP               (0x00400000)
+#define MPI2_TOOLBOX_CLEAN_HIIM                     (0x00200000)
+#define MPI2_TOOLBOX_CLEAN_HIIA                     (0x00100000)
+#define MPI2_TOOLBOX_CLEAN_CTLR                     (0x00080000)
+#define MPI2_TOOLBOX_CLEAN_IMR_FIRMWARE             (0x00040000)
+#define MPI2_TOOLBOX_CLEAN_MR_NVDATA                (0x00020000)
+#define MPI2_TOOLBOX_CLEAN_RESERVED_5_16            (0x0001FFE0)
+#define MPI2_TOOLBOX_CLEAN_ALL_BUT_MPB              (0x00000010)
+#define MPI2_TOOLBOX_CLEAN_ENTIRE_FLASH             (0x00000008)
 #define MPI2_TOOLBOX_CLEAN_FLASH                    (0x00000004)
 #define MPI2_TOOLBOX_CLEAN_SEEPROM                  (0x00000002)
 #define MPI2_TOOLBOX_CLEAN_NVSRAM                   (0x00000001)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 02/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
  2017-07-14 13:22 ` [PATCH v2 01/13] mpt3sas: Update MPI Header Suganath Prabu S
@ 2017-07-14 13:22 ` Suganath Prabu S
  2017-08-03  6:27   ` Hannes Reinecke
  2017-07-14 13:22 ` [PATCH v2 03/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe devices Suganath Prabu S
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

1) Added support for probing pcie device and adding NVMe drives to
SML and driver's internal list pcie_device_list.

2) Added support for determing NVMe as boot device.

3) Added nvme device support for call back functions scan_finished
target_alloc,slave_alloc,target destroy and slave destroy.

 a) During scan, pcie devices are probed and added to SML to drivers
internal list.

 b) target_alloc & slave alloc API's allocates resources for
(MPT3SAS_TARGET & MPT3SAS_DEVICE) private datas and holds
information like handle, target_id etc.

 c) slave_destroy & target_destroy are called when driver unregisters
or removes device. Also frees allocated resources and info.

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  110 ++++++++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  431 +++++++++++++++++++++++++++++++---
 2 files changed, 507 insertions(+), 34 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 099ab4c..c522057 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -159,6 +159,7 @@
 #define MPT_TARGET_FLAGS_VOLUME		0x02
 #define MPT_TARGET_FLAGS_DELETED	0x04
 #define MPT_TARGET_FASTPATH_IO		0x08
+#define MPT_TARGET_FLAGS_PCIE_DEVICE	0x10
 
 #define SAS2_PCI_DEVICE_B0_REVISION	(0x01)
 #define SAS3_PCI_DEVICE_C0_REVISION	(0x02)
@@ -357,7 +358,8 @@ struct Mpi2ManufacturingPage11_t {
  * @flags: MPT_TARGET_FLAGS_XXX flags
  * @deleted: target flaged for deletion
  * @tm_busy: target is busy with TM request.
- * @sdev: The sas_device associated with this target
+ * @sas_dev: The sas_device associated with this target
+ * @pcie_dev: The pcie device associated with this target
  */
 struct MPT3SAS_TARGET {
 	struct scsi_target *starget;
@@ -368,7 +370,8 @@ struct MPT3SAS_TARGET {
 	u32	flags;
 	u8	deleted;
 	u8	tm_busy;
-	struct _sas_device *sdev;
+	struct _sas_device *sas_dev;
+	struct _pcie_device *pcie_dev;
 };
 
 
@@ -508,6 +511,89 @@ static inline void sas_device_put(struct _sas_device *s)
 	kref_put(&s->refcount, sas_device_free);
 }
 
+/*
+ * struct _pcie_device - attached PCIe device information
+ * @list: pcie device list
+ * @starget: starget object
+ * @wwid: device WWID
+ * @handle: device handle
+ * @device_info: bitfield provides detailed info about the device
+ * @id: target id
+ * @channel: target channel
+ * @slot: slot number
+ * @port_num: port number
+ * @responding: used in _scsih_pcie_device_mark_responding
+ * @fast_path: fast path feature enable bit
+ * @nvme_mdts: MaximumDataTransferSize from PCIe Device Page 2 for
+ *		NVMe device only
+ * @enclosure_handle: enclosure handle
+ * @enclosure_logical_id: enclosure logical identifier
+ * @enclosure_level: The level of device's enclosure from the controller
+ * @connector_name: ASCII value of the Connector's name
+ * @serial_number: pointer of serial number string allocated runtime
+ * @refcount: reference count for deletion
+ */
+struct _pcie_device {
+	struct list_head list;
+	struct scsi_target *starget;
+	u64	wwid;
+	u16	handle;
+	u32	device_info;
+	int	id;
+	int	channel;
+	u16	slot;
+	u8	port_num;
+	u8	responding;
+	u8	fast_path;
+	u32	nvme_mdts;
+	u16	enclosure_handle;
+	u64	enclosure_logical_id;
+	u8	enclosure_level;
+	u8	connector_name[4];
+	u8	*serial_number;
+	struct kref refcount;
+};
+/**
+ * pcie_device_get - Increment the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will increment the
+ * reference count of the pcie device for which this function called.
+ *
+ */
+static inline void pcie_device_get(struct _pcie_device *p)
+{
+	kref_get(&p->refcount);
+}
+
+/**
+ * pcie_device_free - Release the pcie device object
+ * @r - kref object
+ *
+ * Free's the pcie device object. It will be called when reference count
+ * reaches to zero.
+ */
+static inline void pcie_device_free(struct kref *r)
+{
+	kfree(container_of(r, struct _pcie_device, refcount));
+}
+
+/**
+ * pcie_device_put - Decrement the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will decrement the
+ * reference count of the pcie device for which this function called.
+ *
+ * When refernce count reaches to Zero, this will call pcie_device_free to the
+ * pcie_device object.
+ */
+static inline void pcie_device_put(struct _pcie_device *p)
+{
+	kref_put(&p->refcount, pcie_device_free);
+}
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -556,12 +642,13 @@ struct _raid_device {
 
 /**
  * struct _boot_device - boot device info
- * @is_raid: flag to indicate whether this is volume
- * @device: holds pointer for either struct _sas_device or
- *     struct _raid_device
+ *
+ * @channel: sas, raid, or pcie channel
+ * @device: holds pointer for struct _sas_device, struct _raid_device or
+ *     struct _pcie_device
  */
 struct _boot_device {
-	u8 is_raid;
+	int channel;
 	void *device;
 };
 
@@ -825,6 +912,8 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
  * @bars: bitmask of BAR's that must be configured
  * @mask_interrupts: ignore interrupt
  * @dma_mask: used to set the consistent dma mask
+ * @pci_access_mutex: Mutex to synchronize ioctl,sysfs show path and
+ *			pci resource handling
  * @fault_reset_work_q_name: fw fault work queue
  * @fault_reset_work_q: ""
  * @fault_reset_work: ""
@@ -888,9 +977,13 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
  * @sas_device_list: sas device object list
  * @sas_device_init_list: sas device object list (used only at init time)
  * @sas_device_lock:
+ * @pcie_device_list: pcie device object list
+ * @pcie_device_init_list: pcie device object list (used only at init time)
+ * @pcie_device_lock:
  * @io_missing_delay: time for IO completed by fw when PDR enabled
  * @device_missing_delay: time for device missing by fw when PDR enabled
  * @sas_id : used for setting volume target IDs
+ * @pcie_target_id: used for setting pcie target IDs
  * @blocking_handles: bitmask used to identify which devices need blocking
  * @pd_handles : bitmask for PD handles
  * @pd_handles_sz : size of pd_handle bitmask
@@ -1086,11 +1179,16 @@ struct MPT3SAS_ADAPTER {
 	struct list_head sas_device_list;
 	struct list_head sas_device_init_list;
 	spinlock_t	sas_device_lock;
+	struct list_head pcie_device_list;
+	struct list_head pcie_device_init_list;
+	spinlock_t      pcie_device_lock;
+
 	struct list_head raid_device_list;
 	spinlock_t	raid_device_lock;
 	u8		io_missing_delay;
 	u16		device_missing_delay;
 	int		sas_id;
+	int		pcie_target_id;
 
 	void		*blocking_handles;
 	void		*pd_handles;
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index a5d8726..1568bff 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -60,6 +60,9 @@
 #include "mpt3sas_base.h"
 
 #define RAID_CHANNEL 1
+
+#define PCIE_CHANNEL 2
+
 /* forward proto's */
 static void _scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc,
 	struct _sas_node *sas_expander);
@@ -439,21 +442,22 @@ _scsih_get_sas_address(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 /**
  * _scsih_determine_boot_device - determine boot device.
  * @ioc: per adapter object
- * @device: either sas_device or raid_device object
- * @is_raid: [flag] 1 = raid object, 0 = sas object
+ * @device: sas_device or pcie_device object
+ * @channel: SAS or PCIe channel
  *
  * Determines whether this device should be first reported device to
  * to scsi-ml or sas transport, this purpose is for persistent boot device.
  * There are primary, alternate, and current entries in bios page 2. The order
  * priority is primary, alternate, then current.  This routine saves
- * the corresponding device object and is_raid flag in the ioc object.
+ * the corresponding device object.
  * The saved data to be used later in _scsih_probe_boot_devices().
  */
 static void
-_scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc,
-	void *device, u8 is_raid)
+_scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc, void *device,
+	u32 channel)
 {
 	struct _sas_device *sas_device;
+	struct _pcie_device *pcie_device;
 	struct _raid_device *raid_device;
 	u64 sas_address;
 	u64 device_name;
@@ -468,18 +472,24 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc,
 	if (!ioc->bios_pg3.BiosVersion)
 		return;
 
-	if (!is_raid) {
-		sas_device = device;
-		sas_address = sas_device->sas_address;
-		device_name = sas_device->device_name;
-		enclosure_logical_id = sas_device->enclosure_logical_id;
-		slot = sas_device->slot;
-	} else {
+	if (channel == RAID_CHANNEL) {
 		raid_device = device;
 		sas_address = raid_device->wwid;
 		device_name = 0;
 		enclosure_logical_id = 0;
 		slot = 0;
+	} else if (channel == PCIE_CHANNEL) {
+		pcie_device = device;
+		sas_address = pcie_device->wwid;
+		device_name = 0;
+		enclosure_logical_id = 0;
+		slot = 0;
+	} else {
+		sas_device = device;
+		sas_address = sas_device->sas_address;
+		device_name = sas_device->device_name;
+		enclosure_logical_id = sas_device->enclosure_logical_id;
+		slot = sas_device->slot;
 	}
 
 	if (!ioc->req_boot_device.device) {
@@ -493,7 +503,7 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc,
 			    ioc->name, __func__,
 			    (unsigned long long)sas_address));
 			ioc->req_boot_device.device = device;
-			ioc->req_boot_device.is_raid = is_raid;
+			ioc->req_boot_device.channel = channel;
 		}
 	}
 
@@ -508,7 +518,7 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc,
 			    ioc->name, __func__,
 			    (unsigned long long)sas_address));
 			ioc->req_alt_boot_device.device = device;
-			ioc->req_alt_boot_device.is_raid = is_raid;
+			ioc->req_alt_boot_device.channel = channel;
 		}
 	}
 
@@ -523,7 +533,7 @@ _scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc,
 			    ioc->name, __func__,
 			    (unsigned long long)sas_address));
 			ioc->current_boot_device.device = device;
-			ioc->current_boot_device.is_raid = is_raid;
+			ioc->current_boot_device.channel = channel;
 		}
 	}
 }
@@ -536,7 +546,7 @@ __mpt3sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc,
 
 	assert_spin_locked(&ioc->sas_device_lock);
 
-	ret = tgt_priv->sdev;
+	ret = tgt_priv->sas_dev;
 	if (ret)
 		sas_device_get(ret);
 
@@ -557,6 +567,44 @@ mpt3sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc,
 	return ret;
 }
 
+static struct _pcie_device *
+__mpt3sas_get_pdev_from_target(struct MPT3SAS_ADAPTER *ioc,
+	struct MPT3SAS_TARGET *tgt_priv)
+{
+	struct _pcie_device *ret;
+
+	assert_spin_locked(&ioc->pcie_device_lock);
+
+	ret = tgt_priv->pcie_dev;
+	if (ret)
+		pcie_device_get(ret);
+
+	return ret;
+}
+
+/**
+ * mpt3sas_get_pdev_from_target - pcie device search
+ * @ioc: per adapter object
+ * @tgt_priv: starget private object
+ *
+ * Context: This function will acquire ioc->pcie_device_lock and will release
+ * before returning the pcie_device object.
+ *
+ * This searches for pcie_device from target, then return pcie_device object.
+ */
+struct _pcie_device *
+mpt3sas_get_pdev_from_target(struct MPT3SAS_ADAPTER *ioc,
+	struct MPT3SAS_TARGET *tgt_priv)
+{
+	struct _pcie_device *ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	ret = __mpt3sas_get_pdev_from_target(ioc, tgt_priv);
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
+	return ret;
+}
 
 struct _sas_device *
 __mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc,
@@ -851,6 +899,146 @@ _scsih_sas_device_init_add(struct MPT3SAS_ADAPTER *ioc,
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 }
 
+
+struct _pcie_device *
+__mpt3sas_get_pdev_by_wwid(struct MPT3SAS_ADAPTER *ioc, u64 wwid)
+{
+	struct _pcie_device *pcie_device;
+
+	assert_spin_locked(&ioc->pcie_device_lock);
+
+	list_for_each_entry(pcie_device, &ioc->pcie_device_list, list)
+		if (pcie_device->wwid == wwid)
+			goto found_device;
+
+	list_for_each_entry(pcie_device, &ioc->pcie_device_init_list, list)
+		if (pcie_device->wwid == wwid)
+			goto found_device;
+
+	return NULL;
+
+found_device:
+	pcie_device_get(pcie_device);
+	return pcie_device;
+}
+
+
+/**
+ * mpt3sas_get_pdev_by_wwid - pcie device search
+ * @ioc: per adapter object
+ * @wwid: wwid
+ *
+ * Context: This function will acquire ioc->pcie_device_lock and will release
+ * before returning the pcie_device object.
+ *
+ * This searches for pcie_device based on wwid, then return pcie_device object.
+ */
+struct _pcie_device *
+mpt3sas_get_pdev_by_wwid(struct MPT3SAS_ADAPTER *ioc, u64 wwid)
+{
+	struct _pcie_device *pcie_device;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	pcie_device = __mpt3sas_get_pdev_by_wwid(ioc, wwid);
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
+	return pcie_device;
+}
+
+
+struct _pcie_device *
+__mpt3sas_get_pdev_by_idchannel(struct MPT3SAS_ADAPTER *ioc, int id,
+	int channel)
+{
+	struct _pcie_device *pcie_device;
+
+	assert_spin_locked(&ioc->pcie_device_lock);
+
+	list_for_each_entry(pcie_device, &ioc->pcie_device_list, list)
+		if (pcie_device->id == id && pcie_device->channel == channel)
+			goto found_device;
+
+	list_for_each_entry(pcie_device, &ioc->pcie_device_init_list, list)
+		if (pcie_device->id == id && pcie_device->channel == channel)
+			goto found_device;
+
+	return NULL;
+
+found_device:
+	pcie_device_get(pcie_device);
+	return pcie_device;
+}
+
+
+/**
+ * mpt3sas_get_pdev_by_idchannel - pcie device search
+ * @ioc: per adapter object
+ * @id: Target ID
+ * @channel: Channel ID
+ *
+ * Context: This function will acquire ioc->pcie_device_lock and will release
+ * before returning the pcie_device object.
+ *
+ * This searches for pcie_device based on id and channel, then return
+ * pcie_device object.
+ */
+struct _pcie_device *
+mpt3sas_get_pdev_by_idchannel(struct MPT3SAS_ADAPTER *ioc, int id, int channel)
+{
+	struct _pcie_device *pcie_device;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	pcie_device = __mpt3sas_get_pdev_by_idchannel(ioc, id, channel);
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
+	return pcie_device;
+}
+/**
+ * _scsih_pcie_device_remove - remove pcie_device from list.
+ * @ioc: per adapter object
+ * @pcie_device: the pcie_device object
+ * Context: This function will acquire ioc->pcie_device_lock.
+ *
+ * If pcie_device is on the list, remove it and decrement its reference count.
+ */
+static void
+_scsih_pcie_device_remove(struct MPT3SAS_ADAPTER *ioc,
+	struct _pcie_device *pcie_device)
+{
+	unsigned long flags;
+	int was_on_pcie_device_list = 0;
+
+	if (!pcie_device)
+		return;
+	pr_info(MPT3SAS_FMT
+		"removing handle(0x%04x), wwid(0x%016llx)\n",
+		ioc->name, pcie_device->handle,
+		(unsigned long long) pcie_device->wwid);
+	if (pcie_device->enclosure_handle != 0)
+		pr_info(MPT3SAS_FMT
+			"removing enclosure logical id(0x%016llx), slot(%d)\n",
+			ioc->name,
+			(unsigned long long)pcie_device->enclosure_logical_id,
+		pcie_device->slot);
+	if (pcie_device->connector_name[0] != '\0')
+		pr_info(MPT3SAS_FMT
+			"removing enclosure level(0x%04x), connector name( %s)\n",
+			ioc->name, pcie_device->enclosure_level,
+			pcie_device->connector_name);
+
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	if (!list_empty(&pcie_device->list)) {
+		list_del_init(&pcie_device->list);
+		was_on_pcie_device_list = 1;
+	}
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+	if (was_on_pcie_device_list) {
+		kfree(pcie_device->serial_number);
+		pcie_device_put(pcie_device);
+	}
+}
 /**
  * _scsih_raid_device_find_by_id - raid device search
  * @ioc: per adapter object
@@ -1278,6 +1466,7 @@ scsih_target_alloc(struct scsi_target *starget)
 	struct MPT3SAS_TARGET *sas_target_priv_data;
 	struct _sas_device *sas_device;
 	struct _raid_device *raid_device;
+	struct _pcie_device *pcie_device;
 	unsigned long flags;
 	struct sas_rphy *rphy;
 
@@ -1307,6 +1496,28 @@ scsih_target_alloc(struct scsi_target *starget)
 		return 0;
 	}
 
+	/* PCIe devices */
+	if (starget->channel == PCIE_CHANNEL) {
+		spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+		pcie_device = __mpt3sas_get_pdev_by_idchannel(ioc, starget->id,
+			starget->channel);
+		if (pcie_device) {
+			sas_target_priv_data->handle = pcie_device->handle;
+			sas_target_priv_data->sas_address = pcie_device->wwid;
+			sas_target_priv_data->pcie_dev = pcie_device;
+			pcie_device->starget = starget;
+			pcie_device->id = starget->id;
+			pcie_device->channel = starget->channel;
+			sas_target_priv_data->flags |=
+				MPT_TARGET_FLAGS_PCIE_DEVICE;
+			if (pcie_device->fast_path)
+				sas_target_priv_data->flags |=
+					MPT_TARGET_FASTPATH_IO;
+		}
+		spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+		return 0;
+	}
+
 	/* sas/sata devices */
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	rphy = dev_to_rphy(starget->dev.parent);
@@ -1316,7 +1527,7 @@ scsih_target_alloc(struct scsi_target *starget)
 	if (sas_device) {
 		sas_target_priv_data->handle = sas_device->handle;
 		sas_target_priv_data->sas_address = sas_device->sas_address;
-		sas_target_priv_data->sdev = sas_device;
+		sas_target_priv_data->sas_dev = sas_device;
 		sas_device->starget = starget;
 		sas_device->id = starget->id;
 		sas_device->channel = starget->channel;
@@ -1324,7 +1535,8 @@ scsih_target_alloc(struct scsi_target *starget)
 			sas_target_priv_data->flags |=
 			    MPT_TARGET_FLAGS_RAID_COMPONENT;
 		if (sas_device->fast_path)
-			sas_target_priv_data->flags |= MPT_TARGET_FASTPATH_IO;
+			sas_target_priv_data->flags |=
+					MPT_TARGET_FASTPATH_IO;
 	}
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
@@ -1345,7 +1557,9 @@ scsih_target_destroy(struct scsi_target *starget)
 	struct MPT3SAS_TARGET *sas_target_priv_data;
 	struct _sas_device *sas_device;
 	struct _raid_device *raid_device;
+	struct _pcie_device *pcie_device;
 	unsigned long flags;
+	struct sas_rphy *rphy;
 
 	sas_target_priv_data = starget->hostdata;
 	if (!sas_target_priv_data)
@@ -1363,7 +1577,29 @@ scsih_target_destroy(struct scsi_target *starget)
 		goto out;
 	}
 
+	if (starget->channel == PCIE_CHANNEL) {
+		spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+		pcie_device = __mpt3sas_get_pdev_from_target(ioc,
+							sas_target_priv_data);
+		if (pcie_device && (pcie_device->starget == starget) &&
+			(pcie_device->id == starget->id) &&
+			(pcie_device->channel == starget->channel))
+			pcie_device->starget = NULL;
+
+		if (pcie_device) {
+			/*
+			 * Corresponding get() is in _scsih_target_alloc()
+			 */
+			sas_target_priv_data->pcie_dev = NULL;
+			pcie_device_put(pcie_device);
+			pcie_device_put(pcie_device);
+		}
+		spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+		goto out;
+	}
+
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
+	rphy = dev_to_rphy(starget->dev.parent);
 	sas_device = __mpt3sas_get_sdev_from_target(ioc, sas_target_priv_data);
 	if (sas_device && (sas_device->starget == starget) &&
 	    (sas_device->id == starget->id) &&
@@ -1374,7 +1610,7 @@ scsih_target_destroy(struct scsi_target *starget)
 		/*
 		 * Corresponding get() is in _scsih_target_alloc()
 		 */
-		sas_target_priv_data->sdev = NULL;
+		sas_target_priv_data->sas_dev = NULL;
 		sas_device_put(sas_device);
 
 		sas_device_put(sas_device);
@@ -1403,6 +1639,7 @@ scsih_slave_alloc(struct scsi_device *sdev)
 	struct scsi_target *starget;
 	struct _raid_device *raid_device;
 	struct _sas_device *sas_device;
+	struct _pcie_device *pcie_device;
 	unsigned long flags;
 
 	sas_device_priv_data = kzalloc(sizeof(*sas_device_priv_data),
@@ -1431,8 +1668,22 @@ scsih_slave_alloc(struct scsi_device *sdev)
 			raid_device->sdev = sdev; /* raid is single lun */
 		spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
 	}
+	if (starget->channel == PCIE_CHANNEL) {
+		spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+		pcie_device = __mpt3sas_get_pdev_by_wwid(ioc,
+				sas_target_priv_data->sas_address);
+		if (pcie_device && (pcie_device->starget == NULL)) {
+			sdev_printk(KERN_INFO, sdev,
+			    "%s : pcie_device->starget set to starget @ %d\n",
+			    __func__, __LINE__);
+			pcie_device->starget = starget;
+		}
+
+		if (pcie_device)
+			pcie_device_put(pcie_device);
+		spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
 
-	if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
+	} else  if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
 		sas_device = __mpt3sas_get_sdev_by_addr(ioc,
 					sas_target_priv_data->sas_address);
@@ -1466,6 +1717,7 @@ scsih_slave_destroy(struct scsi_device *sdev)
 	struct Scsi_Host *shost;
 	struct MPT3SAS_ADAPTER *ioc;
 	struct _sas_device *sas_device;
+	struct _pcie_device *pcie_device;
 	unsigned long flags;
 
 	if (!sdev->hostdata)
@@ -1478,7 +1730,19 @@ scsih_slave_destroy(struct scsi_device *sdev)
 	shost = dev_to_shost(&starget->dev);
 	ioc = shost_priv(shost);
 
-	if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
+	if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+		spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+		pcie_device = __mpt3sas_get_pdev_from_target(ioc,
+				sas_target_priv_data);
+		if (pcie_device && !sas_target_priv_data->num_luns)
+			pcie_device->starget = NULL;
+
+		if (pcie_device)
+			pcie_device_put(pcie_device);
+
+		spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
+	} else if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
 		sas_device = __mpt3sas_get_sdev_from_target(ioc,
 				sas_target_priv_data);
@@ -1581,6 +1845,7 @@ scsih_get_resync(struct device *dev)
 
 	percent_complete = 0;
 	handle = 0;
+
 	if (ioc->is_warpdrive)
 		goto out;
 
@@ -8330,42 +8595,52 @@ scsih_shutdown(struct pci_dev *pdev)
 static void
 _scsih_probe_boot_devices(struct MPT3SAS_ADAPTER *ioc)
 {
-	u8 is_raid;
+	u32 channel;
 	void *device;
 	struct _sas_device *sas_device;
 	struct _raid_device *raid_device;
+	struct _pcie_device *pcie_device;
 	u16 handle;
 	u64 sas_address_parent;
 	u64 sas_address;
 	unsigned long flags;
 	int rc;
+	int tid;
 
 	 /* no Bios, return immediately */
 	if (!ioc->bios_pg3.BiosVersion)
 		return;
 
 	device = NULL;
-	is_raid = 0;
 	if (ioc->req_boot_device.device) {
 		device =  ioc->req_boot_device.device;
-		is_raid = ioc->req_boot_device.is_raid;
+		channel = ioc->req_boot_device.channel;
 	} else if (ioc->req_alt_boot_device.device) {
 		device =  ioc->req_alt_boot_device.device;
-		is_raid = ioc->req_alt_boot_device.is_raid;
+		channel = ioc->req_alt_boot_device.channel;
 	} else if (ioc->current_boot_device.device) {
 		device =  ioc->current_boot_device.device;
-		is_raid = ioc->current_boot_device.is_raid;
+		channel = ioc->current_boot_device.channel;
 	}
 
 	if (!device)
 		return;
 
-	if (is_raid) {
+	if (channel == RAID_CHANNEL) {
 		raid_device = device;
 		rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
 		    raid_device->id, 0);
 		if (rc)
 			_scsih_raid_device_remove(ioc, raid_device);
+	} else if (channel == PCIE_CHANNEL) {
+		spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+		pcie_device = device;
+		tid = pcie_device->id;
+		list_move_tail(&pcie_device->list, &ioc->pcie_device_list);
+		spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+		rc = scsi_add_device(ioc->shost, PCIE_CHANNEL, tid, 0);
+		if (rc)
+			_scsih_pcie_device_remove(ioc, pcie_device);
 	} else {
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
 		sas_device = device;
@@ -8498,6 +8773,101 @@ _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * get_next_pcie_device - Get the next pcie device
+ * @ioc: per adapter object
+ *
+ * Get the next pcie device from pcie_device_init_list list.
+ *
+ * Returns pcie device structure if pcie_device_init_list list is not empty
+ * otherwise returns NULL
+ */
+static struct _pcie_device *get_next_pcie_device(struct MPT3SAS_ADAPTER *ioc)
+{
+	struct _pcie_device *pcie_device = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	if (!list_empty(&ioc->pcie_device_init_list)) {
+		pcie_device = list_first_entry(&ioc->pcie_device_init_list,
+				struct _pcie_device, list);
+		pcie_device_get(pcie_device);
+	}
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
+	return pcie_device;
+}
+
+/**
+ * pcie_device_make_active - Add pcie device to pcie_device_list list
+ * @ioc: per adapter object
+ * @pcie_device: pcie device object
+ *
+ * Add the pcie device which has registered with SCSI Transport Later to
+ * pcie_device_list list
+ */
+static void pcie_device_make_active(struct MPT3SAS_ADAPTER *ioc,
+		struct _pcie_device *pcie_device)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+
+	if (!list_empty(&pcie_device->list)) {
+		list_del_init(&pcie_device->list);
+		pcie_device_put(pcie_device);
+	}
+	pcie_device_get(pcie_device);
+	list_add_tail(&pcie_device->list, &ioc->pcie_device_list);
+
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+}
+
+/**
+ * _scsih_probe_pcie - reporting PCIe devices to scsi-ml
+ * @ioc: per adapter object
+ *
+ * Called during initial loading of the driver.
+ */
+static void
+_scsih_probe_pcie(struct MPT3SAS_ADAPTER *ioc)
+{
+	struct _pcie_device *pcie_device;
+	int rc;
+
+	/* PCIe Device List */
+	while ((pcie_device = get_next_pcie_device(ioc))) {
+		if (pcie_device->starget) {
+			pcie_device_put(pcie_device);
+			continue;
+		}
+		rc = scsi_add_device(ioc->shost, PCIE_CHANNEL,
+			pcie_device->id, 0);
+		if (rc) {
+			_scsih_pcie_device_remove(ioc, pcie_device);
+			pcie_device_put(pcie_device);
+			continue;
+		} else if (!pcie_device->starget) {
+			/* CQ 206770:
+			 * When asyn scanning is enabled, its not possible to
+			 * remove devices while scanning is turned on due to an
+			 * oops in scsi_sysfs_add_sdev()->add_device()->
+			 * sysfs_addrm_start()
+			 */
+			if (!ioc->is_driver_loading) {
+			/* TODO-- Need to find out whether this condition will
+			 * occur or not
+			 */
+				_scsih_pcie_device_remove(ioc, pcie_device);
+				pcie_device_put(pcie_device);
+				continue;
+			}
+		}
+		pcie_device_make_active(ioc, pcie_device);
+		pcie_device_put(pcie_device);
+	}
+}
+
+/**
  * _scsih_probe_devices - probing for devices
  * @ioc: per adapter object
  *
@@ -8525,8 +8895,10 @@ _scsih_probe_devices(struct MPT3SAS_ADAPTER *ioc)
 			_scsih_probe_sas(ioc);
 			_scsih_probe_raid(ioc);
 		}
-	} else
+	} else {
 		_scsih_probe_sas(ioc);
+		_scsih_probe_pcie(ioc);
+	}
 }
 
 /**
@@ -8867,11 +9239,14 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	spin_lock_init(&ioc->sas_node_lock);
 	spin_lock_init(&ioc->fw_event_lock);
 	spin_lock_init(&ioc->raid_device_lock);
+	spin_lock_init(&ioc->pcie_device_lock);
 	spin_lock_init(&ioc->diag_trigger_lock);
 
 	INIT_LIST_HEAD(&ioc->sas_device_list);
 	INIT_LIST_HEAD(&ioc->sas_device_init_list);
 	INIT_LIST_HEAD(&ioc->sas_expander_list);
+	INIT_LIST_HEAD(&ioc->pcie_device_list);
+	INIT_LIST_HEAD(&ioc->pcie_device_init_list);
 	INIT_LIST_HEAD(&ioc->fw_event_list);
 	INIT_LIST_HEAD(&ioc->raid_device_list);
 	INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 03/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe  devices
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
  2017-07-14 13:22 ` [PATCH v2 01/13] mpt3sas: Update MPI Header Suganath Prabu S
  2017-07-14 13:22 ` [PATCH v2 02/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe Suganath Prabu S
@ 2017-07-14 13:22 ` Suganath Prabu S
  2017-07-27 13:26   ` Martin K. Petersen
  2017-07-14 13:22 ` [PATCH v2 04/13] mpt3sas: Added support for nvme encapsulated request message Suganath Prabu S
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

* Added support for translating the SGLs associated with incoming
commands either to IEE SGL or NVMe PRPs for NVMe devices.

* The hardware translation of IEEE SGL to NVMe PRPs has limitation
and if a command cannot be translated by hardware then it will go
to firmware and the firmware needs to translate it. And this will
have a performance reduction. To avoid that driver proactively
checks whether the translation will be done in hardware or not,
if not then driver try to translate inside the driver.

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c      |  624 +++++++++++++++++++++++++++++-
 drivers/scsi/mpt3sas/mpt3sas_base.h      |   44 ++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c       |    1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c     |   14 +-
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |    2 +-
 5 files changed, 669 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 18039bb..a90c386 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -59,6 +59,7 @@
 #include <linux/time.h>
 #include <linux/ktime.h>
 #include <linux/kthread.h>
+#include <asm/page.h>        /* To get host page size per arch */
 #include <linux/aer.h>
 
 
@@ -1347,6 +1348,503 @@ _base_build_sg(struct MPT3SAS_ADAPTER *ioc, void *psge,
 /* IEEE format sgls */
 
 /**
+ * _base_build_nvme_prp - This function is called for NVMe end devices to build
+ * a native SGL (NVMe PRP). The native SGL is built starting in the first PRP
+ * entry of the NVMe message (PRP1).  If the data buffer is small enough to be
+ * described entirely using PRP1, then PRP2 is not used.  If needed, PRP2 is
+ * used to describe a larger data buffer.  If the data buffer is too large to
+ * describe using the two PRP entriess inside the NVMe message, then PRP1
+ * describes the first data memory segment, and PRP2 contains a pointer to a PRP
+ * list located elsewhere in memory to describe the remaining data memory
+ * segments.  The PRP list will be contiguous.
+
+ * The native SGL for NVMe devices is a Physical Region Page (PRP).  A PRP
+ * consists of a list of PRP entries to describe a number of noncontigous
+ * physical memory segments as a single memory buffer, just as a SGL does.  Note
+ * however, that this function is only used by the IOCTL call, so the memory
+ * given will be guaranteed to be contiguous.  There is no need to translate
+ * non-contiguous SGL into a PRP in this case.  All PRPs will describe
+ * contiguous space that is one page size each.
+ *
+ * Each NVMe message contains two PRP entries.  The first (PRP1) either contains
+ * a PRP list pointer or a PRP element, depending upon the command.  PRP2
+ * contains the second PRP element if the memory being described fits within 2
+ * PRP entries, or a PRP list pointer if the PRP spans more than two entries.
+ *
+ * A PRP list pointer contains the address of a PRP list, structured as a linear
+ * array of PRP entries.  Each PRP entry in this list describes a segment of
+ * physical memory.
+ *
+ * Each 64-bit PRP entry comprises an address and an offset field.  The address
+ * always points at the beginning of a 4KB physical memory page, and the offset
+ * describes where within that 4KB page the memory segment begins.  Only the
+ * first element in a PRP list may contain a non-zero offest, implying that all
+ * memory segments following the first begin at the start of a 4KB page.
+ *
+ * Each PRP element normally describes 4KB of physical memory, with exceptions
+ * for the first and last elements in the list.  If the memory being described
+ * by the list begins at a non-zero offset within the first 4KB page, then the
+ * first PRP element will contain a non-zero offset indicating where the region
+ * begins within the 4KB page.  The last memory segment may end before the end
+ * of the 4KB segment, depending upon the overall size of the memory being
+ * described by the PRP list.
+ *
+ * Since PRP entries lack any indication of size, the overall data buffer length
+ * is used to determine where the end of the data memory buffer is located, and
+ * how many PRP entries are required to describe it.
+ *
+ * @ioc: per adapter object
+ * @smid: system request message index for getting asscociated SGL
+ * @nvme_encap_request: the NVMe request msg frame pointer
+ * @data_out_dma: physical address for WRITES
+ * @data_out_sz: data xfer size for WRITES
+ * @data_in_dma: physical address for READS
+ * @data_in_sz: data xfer size for READS
+ *
+ * Returns nothing.
+ */
+static void
+_base_build_nvme_prp(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+	Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request,
+	dma_addr_t data_out_dma, size_t data_out_sz, dma_addr_t data_in_dma,
+	size_t data_in_sz)
+{
+	int		prp_size = NVME_PRP_SIZE;
+	u64		*prp_entry, *prp1_entry, *prp2_entry, *prp_entry_phys;
+	u64		*prp_page, *prp_page_phys;
+	u32		offset, entry_len;
+	u32		page_mask_result, page_mask;
+	dma_addr_t	paddr;
+	size_t		length;
+
+	/*
+	 * Not all commands require a data transfer. If no data, just return
+	 * without constructing any PRP.
+	 */
+	if (!data_in_sz && !data_out_sz)
+		return;
+	/*
+	 * Set pointers to PRP1 and PRP2, which are in the NVMe command.
+	 * PRP1 is located at a 24 byte offset from the start of the NVMe
+	 * command.  Then set the current PRP entry pointer to PRP1.
+	 */
+	prp1_entry = (u64 *)(nvme_encap_request->NVMe_Command +
+	    NVME_CMD_PRP1_OFFSET);
+	prp2_entry = (u64 *)(nvme_encap_request->NVMe_Command +
+	    NVME_CMD_PRP2_OFFSET);
+	prp_entry = prp1_entry;
+	/*
+	 * For the PRP entries, use the specially allocated buffer of
+	 * contiguous memory.
+	 */
+	prp_page = (u64 *)mpt3sas_base_get_pcie_sgl(ioc, smid);
+	prp_page_phys = (u64 *)mpt3sas_base_get_pcie_sgl_dma(ioc, smid);
+
+	/*
+	 * Check if we are within 1 entry of a page boundary we don't
+	 * want our first entry to be a PRP List entry.
+	 */
+	page_mask = ioc->page_size - 1;
+	page_mask_result = (uintptr_t)((u8 *)prp_page + prp_size) & page_mask;
+	if (!page_mask_result) {
+		/* Bump up to next page boundary. */
+		prp_page = (u64 *)((u8 *)prp_page + prp_size);
+		prp_page_phys = (u64 *)((u8 *)prp_page_phys + prp_size);
+	}
+
+	/*
+	 * Set PRP physical pointer, which initially points to the current PRP
+	 * DMA memory page.
+	 */
+	prp_entry_phys = prp_page_phys;
+
+	/* Get physical address and length of the data buffer. */
+	if (data_in_sz) {
+		paddr = data_in_dma;
+		length = data_in_sz;
+	} else {
+		paddr = data_out_dma;
+		length = data_out_sz;
+	}
+
+	/* Loop while the length is not zero. */
+	while (length) {
+		/*
+		 * Check if we need to put a list pointer here if we are at
+		 * page boundary - prp_size (8 bytes).
+		 */
+		page_mask_result =
+		    (uintptr_t)((u8 *)prp_entry_phys + prp_size) & page_mask;
+		if (!page_mask_result) {
+			/*
+			 * This is the last entry in a PRP List, so we need to
+			 * put a PRP list pointer here.  What this does is:
+			 *   - bump the current memory pointer to the next
+			 *     address, which will be the next full page.
+			 *   - set the PRP Entry to point to that page.  This
+			 *     is now the PRP List pointer.
+			 *   - bump the PRP Entry pointer the start of the
+			 *     next page.  Since all of this PRP memory is
+			 *     contiguous, no need to get a new page - it's
+			 *     just the next address.
+			 */
+			prp_entry_phys++;
+			*prp_entry = cpu_to_le64((uintptr_t)prp_entry_phys);
+			prp_entry++;
+		}
+
+		/* Need to handle if entry will be part of a page. */
+		offset = (u32)paddr & page_mask;
+		entry_len = ioc->page_size - offset;
+
+		if (prp_entry == prp1_entry) {
+			/*
+			 * Must fill in the first PRP pointer (PRP1) before
+			 * moving on.
+			 */
+			*prp1_entry = cpu_to_le64((u64)paddr);
+
+			/*
+			 * Now point to the second PRP entry within the
+			 * command (PRP2).
+			 */
+			prp_entry = prp2_entry;
+		} else if (prp_entry == prp2_entry) {
+			/*
+			 * Should the PRP2 entry be a PRP List pointer or just
+			 * a regular PRP pointer?  If there is more than one
+			 * more page of data, must use a PRP List pointer.
+			 */
+			if (length > ioc->page_size) {
+				/*
+				 * PRP2 will contain a PRP List pointer because
+				 * more PRP's are needed with this command. The
+				 * list will start at the beginning of the
+				 * contiguous buffer.
+				 */
+				*prp2_entry =
+				    cpu_to_le64((uintptr_t)prp_entry_phys);
+
+				/*
+				 * The next PRP Entry will be the start of the
+				 * first PRP List.
+				 */
+				prp_entry = prp_page;
+			} else {
+				/*
+				 * After this, the PRP Entries are complete.
+				 * This command uses 2 PRP's and no PRP list.
+				 */
+				*prp2_entry = cpu_to_le64((u64)paddr);
+			}
+		} else {
+			/*
+			 * Put entry in list and bump the addresses.
+			 *
+			 * After PRP1 and PRP2 are filled in, this will fill in
+			 * all remaining PRP entries in a PRP List, one per
+			 * each time through the loop.
+			 */
+			*prp_entry = cpu_to_le64((u64)paddr);
+			prp_entry++;
+			prp_entry_phys++;
+		}
+
+		/*
+		 * Bump the phys address of the command's data buffer by the
+		 * entry_len.
+		 */
+		paddr += entry_len;
+
+		/* Decrement length accounting for last partial page. */
+		if (entry_len > length)
+			length = 0;
+		else
+			length -= entry_len;
+	}
+}
+
+/**
+ * _base_check_pcie_native_sgl - This function is called for PCIe end devices to
+ * determine if the driver needs to build a native SGL.  If so, that native
+ * SGL is built in the special contiguous buffers allocated especially for
+ * PCIe SGL creation.  If the driver will not build a native SGL, return
+ * TRUE and a normal IEEE SGL will be built.  Currently this routine
+ * supports NVMe.
+ * @ioc: per adapter object
+ * @mpi_request: mf request pointer
+ * @smid: system request message index
+ * @scmd: scsi command
+ * @pcie_device: points to the PCIe device's info
+ *
+ * Returns 0 if native SGL was built, 1 if no SGL was built
+ */
+static int
+_base_check_pcie_native_sgl(struct MPT3SAS_ADAPTER *ioc,
+	Mpi25SCSIIORequest_t *mpi_request, u16 smid, struct scsi_cmnd *scmd,
+	struct _pcie_device *pcie_device)
+{
+	struct scatterlist *sg_scmd;
+	int sges_left;
+	u32 i, sge_dwords, length, offset, entry_len, num_entries;
+	u32 buff_len, sges_in_segment, page_mask;
+	u32 page_mask_result;
+	u32 *curr_buff, *ptr_sgl, *ptr_first_sgl;
+	u32 first_page_offset, first_page_data_size, end_residual;
+	u64 *msg_phys;
+	dma_addr_t paddr;
+	int build_native_sgl = 0, first_prp_entry;
+	Mpi25IeeeSgeChain64_t *main_chain_element = NULL;
+
+	/* Get the SG list pointer and info. */
+	sg_scmd = scsi_sglist(scmd);
+	sges_left = scsi_dma_map(scmd);
+	if (sges_left < 0) {
+		sdev_printk(KERN_ERR, scmd->device,
+			"scsi_dma_map failed: request for %d bytes!\n",
+			scsi_bufflen(scmd));
+		return 1;
+	}
+	buff_len = cpu_to_le32(scsi_bufflen(scmd));
+
+	/*
+	 * For NVMe, check if the data transfer length exceeds the MDTS (Maximum
+	 * Data Transfer Size) for this device.  If so, just return 1 so a
+	 * normal IEEE SGL is built.  F/W will break up the I/O into multiple
+	 * I/O's.  [nvme_mdts = 0 means unlimited]
+	 */
+	if ((pcie_device->nvme_mdts > 0) && (buff_len > pcie_device->nvme_mdts))
+		goto out;
+
+
+	/* Create page_mask (to get offset within page) */
+	page_mask = ioc->page_size - 1;
+
+	/*
+	 * Check if the number of elements exceeds the max number that can be
+	 * put in the main message frame (H/W can only translate an SGL that
+	 * is contained entirely in the main message frame).
+	 */
+	sges_in_segment = (ioc->request_sz -
+	    offsetof(Mpi25SCSIIORequest_t, SGL))/ioc->sge_size_ieee;
+	if (sges_left > sges_in_segment)
+		build_native_sgl = 1;
+	else {
+		/*
+		 * NVMe uses one PRP for each physical page (or part of
+		 * physical page)
+		 * look at the data length
+		 *    if 4 pages or less then IEEE is OK
+		 *    if > 5 pages then we need to build a native SGL
+		 *    if > 4 and <= 5 pages, then check the physical
+		 *      address of the first SG entry, then if this
+		 *      first size in the page is >= the residual beyond
+		 *      4 pages then use IEEE, otherwise use native SGL
+		 */
+		if (buff_len > (ioc->page_size * 5))
+			build_native_sgl = 1;
+		else if ((buff_len > (ioc->page_size * 4)) &&
+		    (buff_len <= (ioc->page_size * 5))) {
+			msg_phys = (u64 *) sg_dma_address(sg_scmd);
+			first_page_offset = ((u32)(u64)msg_phys & page_mask);
+			first_page_data_size = ioc->page_size -
+			    first_page_offset;
+			end_residual = buff_len % ioc->page_size;
+
+			/*
+			 * If offset into first page pushes the end of
+			 * the data beyond end of the 5th page, we need
+			 * the extra PRP list
+			 */
+			if (first_page_data_size < end_residual)
+				build_native_sgl = 1;
+
+			/*
+			 * Check if first SG entry size is < residual
+			 * beyond 4 pages.
+			 */
+			if (sg_dma_len(sg_scmd) <
+			    (buff_len - (ioc->page_size * 4)))
+				build_native_sgl = 1;
+		}
+	}
+
+	/* check if native SGL is needed */
+	if (!build_native_sgl)
+		goto out;
+
+	/*
+	 * Native SGL is needed.
+	 * Put a chain element in main message frame that points to the first
+	 * chain buffer.
+	 *
+	 * NOTE:  The ChainOffset field must be 0 when using a chain pointer to
+	 *        a native SGL.
+	 */
+
+	/* Set main message chain element pointer */
+	main_chain_element = (pMpi25IeeeSgeChain64_t)&mpi_request->SGL;
+
+	/*
+	 * For NVMe the chain element needs to be the 2nd SG entry in the main
+	 * message.
+	 */
+	main_chain_element = (Mpi25IeeeSgeChain64_t *)
+	    ((u8 *)main_chain_element + sizeof(MPI25_IEEE_SGE_CHAIN64));
+
+	/*
+	 * For the PRP entries, use the specially allocated buffer of
+	 * contiguous memory.  Normal chain buffers can't be used
+	 * because each chain buffer would need to be the size of an OS
+	 * page (4k).
+	 */
+	curr_buff = (u32 *)mpt3sas_base_get_pcie_sgl(ioc, smid);
+	msg_phys = (u64 *)mpt3sas_base_get_pcie_sgl_dma(ioc, smid);
+
+	/*
+	 * Check if we are within 1 entry of a page boundary we don't
+	 * want our first entry to be a PRP List entry.
+	 */
+	page_mask_result = (uintptr_t)((u8 *)curr_buff + 8) & page_mask;
+	if (!page_mask_result) {
+		/* Bump up to next page boundary. */
+		curr_buff = (u32 *)((u8 *)curr_buff + 8);
+		msg_phys = (u64 *)((u8 *)msg_phys + 8);
+	}
+
+	/*
+	 * Fill in the chain element and make it an NVMe segment type.
+	 */
+	main_chain_element->Address = cpu_to_le64((uintptr_t)msg_phys);
+	main_chain_element->NextChainOffset = 0;
+	main_chain_element->Flags = MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
+		MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR |
+		MPI26_IEEE_SGE_FLAGS_NSF_NVME_PRP;
+
+	/* Set SGL pointer to start of contiguous PCIe buffer. */
+	ptr_sgl = curr_buff;
+	sge_dwords = 2;
+	num_entries = 0;
+
+	/*
+	 * NVMe has a very convoluted PRP format.  One PRP is required
+	 * for each page or partial page.  We need to split up OS SG
+	 * entries if they are longer than one page or cross a page
+	 * boundary.  We also have to insert a PRP list pointer entry as
+	 * the last entry in each physical page of the PRP list.
+	 *
+	 * NOTE: The first PRP "entry" is actually placed in the first
+	 * SGL entry in the main message in IEEE 64 format.  The 2nd
+	 * entry in the main message is the chain element, and the rest
+	 * of the PRP entries are built in the contiguous PCIe buffer.
+	 */
+	first_prp_entry = 1;
+	ptr_first_sgl = (u32 *)&mpi_request->SGL;
+
+	for (i = 0; i < sges_left; i++) {
+		/* Get physical address and length of this SG entry. */
+		paddr = sg_dma_address(sg_scmd);
+		length = sg_dma_len(sg_scmd);
+
+		/* Except the first PRP all other PRP entries should be page
+		 * aligned for NVMe drives, if not the I/O need to be split
+		 * into multiple I/Os. Let the firmware do the split by sending
+		 * IEEE SGEs for the case of non first SGE having a page
+		 * unaligned address. Watch this if there is a performance
+		 * issue with NVMe drives.
+		 */
+		if ((paddr & page_mask) && i)
+			goto out;
+
+		/* Apart from last SGE, if any other SGE boundary is not page
+		 * aligned then it means that hole exists. Existence of hole
+		 * leads to data corruption. So fallback to IEEE SGEs.
+		 */
+		if (i != (sges_left - 1))
+			if ((paddr + length) & page_mask)
+				goto out;
+
+		/* Loop while the length is not zero. */
+		while (length) {
+			/*
+			 * Check if we need to put a list pointer here
+			 * if we are at page boundary - 8.
+			 */
+			page_mask_result =
+			    (uintptr_t)((u8 *)ptr_sgl + 8) & page_mask;
+			if (!page_mask_result) {
+				/*
+				 * Need to put a PRP list pointer here.
+				 */
+				msg_phys = (u64 *)((u8 *)msg_phys + 8);
+				*ptr_sgl =
+				    cpu_to_le32((uintptr_t)msg_phys);
+				*(ptr_sgl+1) = cpu_to_le32(
+				    (u64)(uintptr_t)msg_phys >> 32);
+				ptr_sgl += sge_dwords;
+				num_entries++;
+			}
+
+			/*
+			 * Need to handle if entry will be part of a
+			 * page.
+			 */
+			offset = (u32)paddr & page_mask;
+			entry_len = ioc->page_size - offset;
+
+			if (first_prp_entry) {
+				/*
+				 * Put IEEE entry in 1st SGE in main
+				 * message.  (Simple element, System
+				 * addr, not end of list.)
+				 */
+				*ptr_first_sgl = cpu_to_le32((u32)paddr);
+				*(ptr_first_sgl+1) =
+					cpu_to_le32((u32)(paddr >> 32));
+				*(ptr_first_sgl+2) = cpu_to_le32(entry_len);
+				*(ptr_first_sgl+3) = 0;
+				/* No longer the first PRP entry. */
+				first_prp_entry = 0;
+			} else {
+				/* Put entry in list. */
+				*ptr_sgl = cpu_to_le32((u32)paddr);
+				*(ptr_sgl+1) = cpu_to_le32((u32)(paddr >> 32));
+				/*
+				 * Bump ptr_SGL, msg_phys, and
+				 * num_entries.
+				 */
+				ptr_sgl += sge_dwords;
+				msg_phys = (u64 *)((u8 *)msg_phys + 8);
+				num_entries++;
+			}
+
+			/* Bump the phys address by the entry_len. */
+			paddr += entry_len;
+
+			/*
+			 * Decrement length accounting for last partial
+			 * page.
+			 */
+			if (entry_len > length)
+				length = 0;
+			else
+				length -= entry_len;
+		}
+
+		/* Done with this SG entry, get the next one. */
+		sg_scmd = sg_next(sg_scmd);
+	}
+	/* Set chain element Length. */
+	main_chain_element->Length = cpu_to_le32(num_entries * 8);
+
+	/* Return 0, indicating we built a native SGL. */
+	return 0;
+out:
+	scsi_dma_unmap(scmd);
+	return 1;
+}
+
+/**
  * _base_add_sg_single_ieee - add sg element for IEEE format
  * @paddr: virtual address for SGE
  * @flags: SGE flags
@@ -1391,9 +1889,11 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr)
 
 /**
  * _base_build_sg_scmd - main sg creation routine
+ *		pcie_device is unused here!
  * @ioc: per adapter object
  * @scmd: scsi command
  * @smid: system request message index
+ * @unused: unused pcie_device pointer
  * Context: none.
  *
  * The main routine that builds scatter gather table from a given
@@ -1403,7 +1903,7 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr)
  */
 static int
 _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc,
-		struct scsi_cmnd *scmd, u16 smid)
+	struct scsi_cmnd *scmd, u16 smid, struct _pcie_device *unused)
 {
 	Mpi2SCSIIORequest_t *mpi_request;
 	dma_addr_t chain_dma;
@@ -1537,6 +2037,8 @@ _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc,
  * @ioc: per adapter object
  * @scmd: scsi command
  * @smid: system request message index
+ * @pcie_device: Pointer to pcie_device. If set, the pcie native sgl will be
+ * constructed on need.
  * Context: none.
  *
  * The main routine that builds scatter gather table from a given
@@ -1546,9 +2048,9 @@ _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc,
  */
 static int
 _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc,
-	struct scsi_cmnd *scmd, u16 smid)
+	struct scsi_cmnd *scmd, u16 smid, struct _pcie_device *pcie_device)
 {
-	Mpi2SCSIIORequest_t *mpi_request;
+	Mpi25SCSIIORequest_t *mpi_request;
 	dma_addr_t chain_dma;
 	struct scatterlist *sg_scmd;
 	void *sg_local, *chain;
@@ -1571,6 +2073,13 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc,
 	chain_sgl_flags = MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
 	    MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR;
 
+	/* Check if we need to build a native SG list. */
+	if ((pcie_device) && (_base_check_pcie_native_sgl(ioc, mpi_request,
+	    smid, scmd, pcie_device) == 0)) {
+		/* We built a native SG list, just return. */
+		return 0;
+	}
+
 	sg_scmd = scsi_sglist(scmd);
 	sges_left = scsi_dma_map(scmd);
 	if (sges_left < 0) {
@@ -1582,12 +2091,12 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc,
 
 	sg_local = &mpi_request->SGL;
 	sges_in_segment = (ioc->request_sz -
-	    offsetof(Mpi2SCSIIORequest_t, SGL))/ioc->sge_size_ieee;
+		   offsetof(Mpi25SCSIIORequest_t, SGL))/ioc->sge_size_ieee;
 	if (sges_left <= sges_in_segment)
 		goto fill_in_last_segment;
 
 	mpi_request->ChainOffset = (sges_in_segment - 1 /* chain element */) +
-	    (offsetof(Mpi2SCSIIORequest_t, SGL)/ioc->sge_size_ieee);
+	    (offsetof(Mpi25SCSIIORequest_t, SGL)/ioc->sge_size_ieee);
 
 	/* fill in main message segment when there is a chain following */
 	while (sges_in_segment > 1) {
@@ -2267,6 +2776,33 @@ mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid)
 }
 
 /**
+ * mpt3sas_base_get_pcie_sgl - obtain a PCIe SGL virt addr
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Returns virt pointer to a PCIe SGL.
+ */
+void *
+mpt3sas_base_get_pcie_sgl(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+{
+	return (void *)(ioc->scsi_lookup[smid - 1].pcie_sg_list.pcie_sgl);
+}
+
+/**
+ * mpt3sas_base_get_pcie_sgl_dma - obtain a PCIe SGL dma addr
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Returns phys pointer to the address of the PCIe buffer.
+ */
+void *
+mpt3sas_base_get_pcie_sgl_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+{
+	return (void *)(uintptr_t)
+	    (ioc->scsi_lookup[smid - 1].pcie_sg_list.pcie_sgl_dma);
+}
+
+/**
  * mpt3sas_base_get_reply_virt_addr - obtain reply frames virt address
  * @ioc: per adapter object
  * @phys_addr: lower 32 physical addr of the reply
@@ -2945,6 +3481,11 @@ _base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc)
 
 	_base_display_OEMs_branding(ioc);
 
+	if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_NVME_DEVICES) {
+		pr_info("%sNVMe", i ? "," : "");
+		i++;
+	}
+
 	pr_info(MPT3SAS_FMT "Protocol=(", ioc->name);
 
 	if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR) {
@@ -3249,6 +3790,17 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 		kfree(ioc->reply_post);
 	}
 
+	if (ioc->pcie_sgl_dma_pool) {
+		for (i = 0; i < ioc->scsiio_depth; i++) {
+			if (ioc->scsi_lookup[i].pcie_sg_list.pcie_sgl)
+				pci_pool_free(ioc->pcie_sgl_dma_pool,
+				ioc->scsi_lookup[i].pcie_sg_list.pcie_sgl,
+				ioc->scsi_lookup[i].pcie_sg_list.pcie_sgl_dma);
+		}
+		if (ioc->pcie_sgl_dma_pool)
+			pci_pool_destroy(ioc->pcie_sgl_dma_pool);
+	}
+
 	if (ioc->config_page) {
 		dexitprintk(ioc, pr_info(MPT3SAS_FMT
 		    "config_page(0x%p): free\n", ioc->name,
@@ -3291,7 +3843,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 	u16 chains_needed_per_io;
 	u32 sz, total_sz, reply_post_free_sz;
 	u32 retry_sz;
-	u16 max_request_credit;
+	u16 max_request_credit, nvme_blocks_needed;
 	unsigned short sg_tablesize;
 	u16 sge_size;
 	int i;
@@ -3627,7 +4179,52 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 		"internal(0x%p): depth(%d), start smid(%d)\n",
 		ioc->name, ioc->internal,
 	    ioc->internal_depth, ioc->internal_smid));
+	/*
+	 * The number of NVMe page sized blocks needed is:
+	 *     (((sg_tablesize * 8) - 1) / (page_size - 8)) + 1
+	 * ((sg_tablesize * 8) - 1) is the max PRP's minus the first PRP entry
+	 * that is placed in the main message frame.  8 is the size of each PRP
+	 * entry or PRP list pointer entry.  8 is subtracted from page_size
+	 * because of the PRP list pointer entry at the end of a page, so this
+	 * is not counted as a PRP entry.  The 1 added page is a round up.
+	 *
+	 * To avoid allocation failures due to the amount of memory that could
+	 * be required for NVMe PRP's, only each set of NVMe blocks will be
+	 * contiguous, so a new set is allocated for each possible I/O.
+	 */
+	if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_NVME_DEVICES) {
+		nvme_blocks_needed =
+			(ioc->shost->sg_tablesize * NVME_PRP_SIZE) - 1;
+		nvme_blocks_needed /= (ioc->page_size - NVME_PRP_SIZE);
+		nvme_blocks_needed++;
+
+		sz = nvme_blocks_needed * ioc->page_size;
+		ioc->pcie_sgl_dma_pool =
+			pci_pool_create("PCIe SGL pool", ioc->pdev, sz, 16, 0);
+		if (!ioc->pcie_sgl_dma_pool) {
+			pr_info(MPT3SAS_FMT
+			    "PCIe SGL pool: pci_pool_create failed\n",
+			    ioc->name);
+			goto out;
+		}
+		for (i = 0; i < ioc->scsiio_depth; i++) {
+			ioc->scsi_lookup[i].pcie_sg_list.pcie_sgl =
+					pci_pool_alloc(ioc->pcie_sgl_dma_pool,
+					GFP_KERNEL,
+				&ioc->scsi_lookup[i].pcie_sg_list.pcie_sgl_dma);
+			if (!ioc->scsi_lookup[i].pcie_sg_list.pcie_sgl) {
+				pr_info(MPT3SAS_FMT
+				    "PCIe SGL pool: pci_pool_alloc failed\n",
+				    ioc->name);
+				goto out;
+			}
+		}
 
+		dinitprintk(ioc, pr_info(MPT3SAS_FMT "PCIe sgl pool depth(%d), "
+			"element_size(%d), pool_size(%d kB)\n", ioc->name,
+			ioc->scsiio_depth, sz, (sz * ioc->scsiio_depth)/1024));
+		total_sz += sz * ioc->scsiio_depth;
+	}
 	/* sense buffers, 4 byte align */
 	sz = ioc->scsiio_depth * SCSI_SENSE_BUFFERSIZE;
 	ioc->sense_dma_pool = pci_pool_create("sense pool", ioc->pdev, sz, 4,
@@ -4472,6 +5069,19 @@ _base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc)
 	    le16_to_cpu(mpi_reply.HighPriorityCredit);
 	facts->ReplyFrameSize = mpi_reply.ReplyFrameSize;
 	facts->MaxDevHandle = le16_to_cpu(mpi_reply.MaxDevHandle);
+	facts->CurrentHostPageSize = mpi_reply.CurrentHostPageSize;
+
+	/*
+	 * Get the Page Size from IOC Facts. If it's 0, default to 4k.
+	 */
+	ioc->page_size = 1 << facts->CurrentHostPageSize;
+	if (ioc->page_size == 1) {
+		pr_info(MPT3SAS_FMT "CurrentHostPageSize is 0: Setting "
+			"default host page size to 4k\n", ioc->name);
+		ioc->page_size = 1 << MPT3SAS_HOST_PAGE_SIZE_4K;
+	}
+	dinitprintk(ioc, pr_info(MPT3SAS_FMT "CurrentHostPageSize(%d)\n",
+		ioc->name, facts->CurrentHostPageSize));
 
 	dinitprintk(ioc, pr_info(MPT3SAS_FMT
 		"hba queue depth(%d), max chains per io(%d)\n",
@@ -4511,6 +5121,7 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc)
 	mpi_request.VP_ID = 0;
 	mpi_request.MsgVersion = cpu_to_le16(ioc->hba_mpi_version_belonged);
 	mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION);
+	mpi_request.HostPageSize = MPT3SAS_HOST_PAGE_SIZE_4K;
 
 	if (_base_is_controller_msix_enabled(ioc))
 		mpi_request.HostMSIxVectors = ioc->reply_queue_count;
@@ -5379,6 +5990,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
 		 */
 		ioc->build_sg_scmd = &_base_build_sg_scmd_ieee;
 		ioc->build_sg = &_base_build_sg_ieee;
+		ioc->build_nvme_prp = &_base_build_nvme_prp;
 		ioc->build_zero_len_sge = &_base_build_zero_len_sge_ieee;
 		ioc->sge_size_ieee = sizeof(Mpi2IeeeSgeSimple64_t);
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index c522057..fed3d97 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -54,6 +54,7 @@
 #include "mpi/mpi2_raid.h"
 #include "mpi/mpi2_tool.h"
 #include "mpi/mpi2_sas.h"
+#include "mpi/mpi2_pci.h"
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -113,6 +114,7 @@
 #define MPT3SAS_RAID_QUEUE_DEPTH	128
 
 #define MPT3SAS_RAID_MAX_SECTORS	8192
+#define MPT3SAS_HOST_PAGE_SIZE_4K	12
 
 #define MPT_NAME_LENGTH			32	/* generic length of strings */
 #define MPT_STRING_LENGTH		64
@@ -131,6 +133,14 @@
 #define DEFAULT_NUM_FWCHAIN_ELEMTS	8
 
 /*
+ * NVMe defines
+ */
+#define	NVME_PRP_SIZE			8	/* PRP size */
+#define	NVME_CMD_PRP1_OFFSET		24	/* PRP1 offset in NVMe cmd */
+#define	NVME_CMD_PRP2_OFFSET		32	/* PRP2 offset in NVMe cmd */
+#define	NVME_ERROR_RESPONSE_SIZE	16	/* Max NVME Error Response */
+
+/*
  * reset phases
  */
 #define MPT3_IOC_PRE_RESET		1 /* prior to host reset */
@@ -731,6 +741,16 @@ enum reset_type {
 };
 
 /**
+ * struct pcie_sg_list - PCIe SGL buffer (contiguous per I/O)
+ * @pcie_sgl: PCIe native SGL for NVMe devices
+ * @pcie_sgl_dma: physical address
+ */
+struct pcie_sg_list {
+	void            *pcie_sgl;
+	dma_addr_t      pcie_sgl_dma;
+};
+
+/**
  * struct chain_tracker - firmware chain tracker
  * @chain_buffer: chain buffer
  * @chain_buffer_dma: physical address
@@ -756,6 +776,7 @@ struct scsiio_tracker {
 	struct scsi_cmnd *scmd;
 	u8	cb_idx;
 	u8	direct_io;
+	struct pcie_sg_list pcie_sg_list;
 	struct list_head chain_list;
 	struct list_head tracker_list;
 	u16     msix_io;
@@ -829,13 +850,19 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
 
 /* SAS3.0 support */
 typedef int (*MPT_BUILD_SG_SCMD)(struct MPT3SAS_ADAPTER *ioc,
-		struct scsi_cmnd *scmd, u16 smid);
+	struct scsi_cmnd *scmd, u16 smid, struct _pcie_device *pcie_device);
 typedef void (*MPT_BUILD_SG)(struct MPT3SAS_ADAPTER *ioc, void *psge,
 		dma_addr_t data_out_dma, size_t data_out_sz,
 		dma_addr_t data_in_dma, size_t data_in_sz);
 typedef void (*MPT_BUILD_ZERO_LEN_SGE)(struct MPT3SAS_ADAPTER *ioc,
 		void *paddr);
 
+/* SAS3.5 support */
+typedef void (*NVME_BUILD_PRP)(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+	Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request,
+	dma_addr_t data_out_dma, size_t data_out_sz, dma_addr_t data_in_dma,
+	size_t data_in_sz);
+
 /* To support atomic and non atomic descriptors*/
 typedef void (*PUT_SMID_IO_FP_HIP) (struct MPT3SAS_ADAPTER *ioc, u16 smid,
 	u16 funcdep);
@@ -878,6 +905,7 @@ struct mpt3sas_facts {
 	u16			MaxDevHandle;
 	u16			MaxPersistentEntries;
 	u16			MinDevHandle;
+	u8			CurrentHostPageSize;
 };
 
 struct mpt3sas_port_facts {
@@ -1149,6 +1177,9 @@ struct MPT3SAS_ADAPTER {
 	MPT_BUILD_SG    build_sg_mpi;
 	MPT_BUILD_ZERO_LEN_SGE build_zero_len_sge_mpi;
 
+	/* function ptr for NVMe PRP elements only */
+	NVME_BUILD_PRP  build_nvme_prp;
+
 	/* event log */
 	u32		event_type[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
 	u32		event_context;
@@ -1217,6 +1248,12 @@ struct MPT3SAS_ADAPTER {
 	int		pending_io_count;
 	wait_queue_head_t reset_wq;
 
+	/* PCIe SGL */
+	struct dma_pool *pcie_sgl_dma_pool;
+
+	/* Host Page Size */
+	u32		page_size;
+
 	/* chain */
 	struct chain_tracker *chain_lookup;
 	struct list_head free_chain_list;
@@ -1350,7 +1387,8 @@ void *mpt3sas_base_get_msg_frame(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 void *mpt3sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 __le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc,
 	u16 smid);
-
+void *mpt3sas_base_get_pcie_sgl(struct MPT3SAS_ADAPTER *ioc, u16 smid);
+void *mpt3sas_base_get_pcie_sgl_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc);
 
 /* hi-priority queue */
@@ -1564,7 +1602,7 @@ void
 mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io);
 void
 mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
-	struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
+	struct _raid_device *raid_device, Mpi25SCSIIORequest_t *mpi_request,
 	u16 smid);
 
 /* NCQ Prio Handling Check */
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index bdffb69..0c18831 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -299,6 +299,7 @@ mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
 			}
 		}
 	}
+
 	_ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply);
 	ioc->ctl_cmds.status &= ~MPT3_CMD_PENDING;
 	complete(&ioc->ctl_cmds.done);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 1568bff..598fb77 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4244,7 +4244,7 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc)
  */
 static void
 _scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
-	Mpi2SCSIIORequest_t *mpi_request)
+	Mpi25SCSIIORequest_t *mpi_request)
 {
 	u16 eedp_flags;
 	unsigned char prot_op = scsi_get_prot_op(scmd);
@@ -4347,7 +4347,8 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
 	struct _raid_device *raid_device;
 	struct request *rq = scmd->request;
 	int class;
-	Mpi2SCSIIORequest_t *mpi_request;
+	Mpi25SCSIIORequest_t *mpi_request;
+	struct _pcie_device *pcie_device = NULL;
 	u32 mpi_control;
 	u16 smid;
 	u16 handle;
@@ -4435,7 +4436,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
 		goto out;
 	}
 	mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
-	memset(mpi_request, 0, sizeof(Mpi2SCSIIORequest_t));
+	memset(mpi_request, 0, ioc->request_sz);
 	_scsih_setup_eedp(ioc, scmd, mpi_request);
 
 	if (scmd->cmd_len == 32)
@@ -4454,13 +4455,14 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
 	mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
 	mpi_request->SenseBufferLowAddress =
 	    mpt3sas_base_get_sense_buffer_dma(ioc, smid);
-	mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4;
+	mpi_request->SGLOffset0 = offsetof(Mpi25SCSIIORequest_t, SGL) / 4;
 	int_to_scsilun(sas_device_priv_data->lun, (struct scsi_lun *)
 	    mpi_request->LUN);
 	memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
 
 	if (mpi_request->DataLength) {
-		if (ioc->build_sg_scmd(ioc, scmd, smid)) {
+		pcie_device = sas_target_priv_data->pcie_dev;
+		if (ioc->build_sg_scmd(ioc, scmd, smid, pcie_device)) {
 			mpt3sas_base_free_smid(ioc, smid);
 			goto out;
 		}
@@ -4931,7 +4933,7 @@ out_unlock:
 static u8
 _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
 {
-	Mpi2SCSIIORequest_t *mpi_request;
+	Mpi25SCSIIORequest_t *mpi_request;
 	Mpi2SCSIIOReply_t *mpi_reply;
 	struct scsi_cmnd *scmd;
 	u16 ioc_status;
diff --git a/drivers/scsi/mpt3sas/mpt3sas_warpdrive.c b/drivers/scsi/mpt3sas/mpt3sas_warpdrive.c
index 540bd50..ced7d9f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_warpdrive.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_warpdrive.c
@@ -299,7 +299,7 @@ mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io)
  */
 void
 mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
-	struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
+	struct _raid_device *raid_device, Mpi25SCSIIORequest_t *mpi_request,
 	u16 smid)
 {
 	sector_t v_lba, p_lba, stripe_off, column, io_size;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 04/13] mpt3sas: Added support for nvme encapsulated request message.
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
                   ` (2 preceding siblings ...)
  2017-07-14 13:22 ` [PATCH v2 03/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe devices Suganath Prabu S
@ 2017-07-14 13:22 ` Suganath Prabu S
  2017-08-03  6:33   ` Hannes Reinecke
  2017-07-14 13:22 ` [PATCH v2 05/13] mpt3sas: API 's to support NVMe drive addition to SML Suganath Prabu S
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

* Mpt3sas driver uses the NVMe Encapsulated Request message to
send an NVMe command to an NVMe device attached to the IOC.

* Normal I/O commands like reads and writes are passed to the
controller as SCSI commands and the controller has the ability
to translate the commands to NVMe equivalent.

* This encapsulated NVMe command is used by applications to send
direct NVMe commands to NVMe drives or for handling unmap where
the translation at controller/firmware level is having
performance issues.

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c |   56 ++++++++++++++++++++++++++++-
 drivers/scsi/mpt3sas/mpt3sas_base.h |    1 +
 drivers/scsi/mpt3sas/mpt3sas_ctl.c  |   69 ++++++++++++++++++++++++++++++++---
 3 files changed, 119 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index a90c386..c3a6c7a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -557,6 +557,11 @@ _base_sas_ioc_info(struct MPT3SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply,
 		frame_sz = sizeof(Mpi2SmpPassthroughRequest_t) + ioc->sge_size;
 		func_str = "smp_passthru";
 		break;
+	case MPI2_FUNCTION_NVME_ENCAPSULATED:
+		frame_sz = sizeof(Mpi26NVMeEncapsulatedRequest_t) +
+		    ioc->sge_size;
+		func_str = "nvme_encapsulated";
+		break;
 	default:
 		frame_sz = 32;
 		func_str = "unknown";
@@ -985,7 +990,9 @@ _base_interrupt(int irq, void *bus_id)
 		if (request_desript_type ==
 		    MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS ||
 		    request_desript_type ==
-		    MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
+		    MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS ||
+		    request_desript_type ==
+		    MPI26_RPY_DESCRIPT_FLAGS_PCIE_ENCAPSULATED_SUCCESS) {
 			cb_idx = _base_get_cb_idx(ioc, smid);
 			if ((likely(cb_idx < MPT_MAX_CALLBACKS)) &&
 			    (likely(mpt_callbacks[cb_idx] != NULL))) {
@@ -3080,6 +3087,30 @@ _base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
 }
 
 /**
+ * _base_put_smid_nvme_encap - send NVMe encapsulated request to
+ *  firmware
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Return nothing.
+ */
+static void
+_base_put_smid_nvme_encap(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+{
+	Mpi2RequestDescriptorUnion_t descriptor;
+	u64 *request = (u64 *)&descriptor;
+
+	descriptor.Default.RequestFlags =
+		MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
+	descriptor.Default.MSIxIndex =  _base_get_msix_index(ioc);
+	descriptor.Default.SMID = cpu_to_le16(smid);
+	descriptor.Default.LMID = 0;
+	descriptor.Default.DescriptorTypeDependent = 0;
+	_base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
+	    &ioc->scsi_lookup_lock);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * @ioc: per adapter object
  * @smid: system request message index
@@ -3170,6 +3201,27 @@ _base_put_smid_hi_priority_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid,
 }
 
 /**
+ * _base_put_smid_nvme_encap_atomic - send NVMe encapsulated request to
+ *   firmware using Atomic Request Descriptor
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Return nothing.
+ */
+static void
+_base_put_smid_nvme_encap_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+{
+	Mpi26AtomicRequestDescriptor_t descriptor;
+	u32 *request = (u32 *)&descriptor;
+
+	descriptor.RequestFlags = MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
+	descriptor.MSIxIndex = _base_get_msix_index(ioc);
+	descriptor.SMID = cpu_to_le16(smid);
+
+	writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * use Atomic Request Descriptor
  * @ioc: per adapter object
@@ -6002,11 +6054,13 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
 		ioc->put_smid_scsi_io = &_base_put_smid_scsi_io_atomic;
 		ioc->put_smid_fast_path = &_base_put_smid_fast_path_atomic;
 		ioc->put_smid_hi_priority = &_base_put_smid_hi_priority_atomic;
+		ioc->put_smid_nvme_encap = &_base_put_smid_nvme_encap_atomic;
 	} else {
 		ioc->put_smid_default = &_base_put_smid_default;
 		ioc->put_smid_scsi_io = &_base_put_smid_scsi_io;
 		ioc->put_smid_fast_path = &_base_put_smid_fast_path;
 		ioc->put_smid_hi_priority = &_base_put_smid_hi_priority;
+		ioc->put_smid_nvme_encap = &_base_put_smid_nvme_encap;
 	}
 
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index fed3d97..bd32b0c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1351,6 +1351,7 @@ struct MPT3SAS_ADAPTER {
 	PUT_SMID_IO_FP_HIP put_smid_fast_path;
 	PUT_SMID_IO_FP_HIP put_smid_hi_priority;
 	PUT_SMID_DEFAULT put_smid_default;
+	PUT_SMID_DEFAULT put_smid_nvme_encap;
 
 };
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 0c18831..6362d60 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -272,6 +272,7 @@ mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
 {
 	MPI2DefaultReply_t *mpi_reply;
 	Mpi2SCSIIOReply_t *scsiio_reply;
+	Mpi26NVMeEncapsulatedErrorReply_t *nvme_error_reply;
 	const void *sense_data;
 	u32 sz;
 
@@ -298,6 +299,18 @@ mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
 				memcpy(ioc->ctl_cmds.sense, sense_data, sz);
 			}
 		}
+		/*
+		 * Get Error Response data for NVMe device. The ctl_cmds.sense
+		 * buffer is used to store the Error Response data.
+		 */
+		if (mpi_reply->Function == MPI2_FUNCTION_NVME_ENCAPSULATED) {
+			nvme_error_reply =
+			    (Mpi26NVMeEncapsulatedErrorReply_t *)mpi_reply;
+			sz = min_t(u32, NVME_ERROR_RESPONSE_SIZE,
+			    le32_to_cpu(nvme_error_reply->ErrorResponseCount));
+			sense_data = mpt3sas_base_get_sense_buffer(ioc, smid);
+			memcpy(ioc->ctl_cmds.sense, sense_data, sz);
+		}
 	}
 
 	_ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply);
@@ -641,11 +654,12 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
 {
 	MPI2RequestHeader_t *mpi_request = NULL, *request;
 	MPI2DefaultReply_t *mpi_reply;
+	Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request = NULL;
 	u32 ioc_state;
 	u16 smid;
 	unsigned long timeout;
 	u8 issue_reset;
-	u32 sz;
+	u32 sz, sz_arg;
 	void *psge;
 	void *data_out = NULL;
 	dma_addr_t data_out_dma = 0;
@@ -742,7 +756,8 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
 	if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
 	    mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH ||
 	    mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT ||
-	    mpi_request->Function == MPI2_FUNCTION_SATA_PASSTHROUGH) {
+	    mpi_request->Function == MPI2_FUNCTION_SATA_PASSTHROUGH ||
+	    mpi_request->Function == MPI2_FUNCTION_NVME_ENCAPSULATED) {
 
 		device_handle = le16_to_cpu(mpi_request->FunctionDependent1);
 		if (!device_handle || (device_handle >
@@ -793,6 +808,38 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
 
 	init_completion(&ioc->ctl_cmds.done);
 	switch (mpi_request->Function) {
+	case MPI2_FUNCTION_NVME_ENCAPSULATED:
+	{
+		nvme_encap_request = (Mpi26NVMeEncapsulatedRequest_t *)request;
+		/*
+		 * Get the Physical Address of the sense buffer.
+		 * Use Error Response buffer address field to hold the sense
+		 * buffer address.
+		 * Clear the internal sense buffer, which will potentially hold
+		 * the Completion Queue Entry on return, or 0 if no Entry.
+		 * Build the PRPs and set direction bits.
+		 * Send the request.
+		 */
+		nvme_encap_request->ErrorResponseBaseAddress = ioc->sense_dma &
+		    0xFFFFFFFF00000000;
+		nvme_encap_request->ErrorResponseBaseAddress |=
+		    (U64)mpt3sas_base_get_sense_buffer_dma(ioc, smid);
+		nvme_encap_request->ErrorResponseAllocationLength =
+						NVME_ERROR_RESPONSE_SIZE;
+		memset(ioc->ctl_cmds.sense, 0, NVME_ERROR_RESPONSE_SIZE);
+		ioc->build_nvme_prp(ioc, smid, nvme_encap_request,
+		    data_out_dma, data_out_sz, data_in_dma, data_in_sz);
+		if (test_bit(device_handle, ioc->device_remove_in_progress)) {
+			dtmprintk(ioc, pr_info(MPT3SAS_FMT "handle(0x%04x) :"
+			    "ioctl failed due to device removal in progress\n",
+			    ioc->name, device_handle));
+			mpt3sas_base_free_smid(ioc, smid);
+			ret = -EINVAL;
+			goto out;
+		}
+		ioc->put_smid_nvme_encap(ioc, smid);
+		break;
+	}
 	case MPI2_FUNCTION_SCSI_IO_REQUEST:
 	case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
 	{
@@ -1008,15 +1055,25 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
 		}
 	}
 
-	/* copy out sense to user */
+	/* copy out sense/NVMe Error Response to user */
 	if (karg.max_sense_bytes && (mpi_request->Function ==
 	    MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function ==
-	    MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
-		sz = min_t(u32, karg.max_sense_bytes, SCSI_SENSE_BUFFERSIZE);
+	    MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH || mpi_request->Function ==
+	    MPI2_FUNCTION_NVME_ENCAPSULATED)) {
+		if (karg.sense_data_ptr == NULL) {
+			pr_info(MPT3SAS_FMT "Response buffer provided"
+			    " by application is NULL; Response data will"
+			    " not be returned.\n", ioc->name);
+			goto out;
+		}
+		sz_arg = (mpi_request->Function ==
+		MPI2_FUNCTION_NVME_ENCAPSULATED) ? NVME_ERROR_RESPONSE_SIZE :
+							SCSI_SENSE_BUFFERSIZE;
+		sz = min_t(u32, karg.max_sense_bytes, sz_arg);
 		if (copy_to_user(karg.sense_data_ptr, ioc->ctl_cmds.sense,
 		    sz)) {
 			pr_err("failure at %s:%d/%s()!\n", __FILE__,
-			    __LINE__, __func__);
+				__LINE__, __func__);
 			ret = -ENODATA;
 			goto out;
 		}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 05/13] mpt3sas: API 's to support NVMe drive addition to SML
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
                   ` (3 preceding siblings ...)
  2017-07-14 13:22 ` [PATCH v2 04/13] mpt3sas: Added support for nvme encapsulated request message Suganath Prabu S
@ 2017-07-14 13:22 ` Suganath Prabu S
  2017-08-03  6:35   ` Hannes Reinecke
  2017-07-14 13:22 ` [PATCH v2 06/13] mpt3sas: API's to remove nvme drive from sml Suganath Prabu S
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

Below Functions are added in various paths to support NVMe
drive addition.

_scsih_pcie_add_device
_scsih_pcie_device_add
_scsih_pcie_device_init_add
_scsih_check_pcie_access_status
_scsih_pcie_check_device

mpt3sas_get_pdev_by_handle

mpt3sas_config_get_pcie_device_pg0
mpt3sas_config_get_pcie_device_pg2

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h   |   10 +
 drivers/scsi/mpt3sas/mpt3sas_config.c |  100 +++++++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c  |  473 ++++++++++++++++++++++++++++++++-
 3 files changed, 575 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index bd32b0c..0a8187e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1458,6 +1458,10 @@ struct _sas_device *mpt3sas_get_sdev_by_addr(
 	 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
 struct _sas_device *__mpt3sas_get_sdev_by_addr(
 	 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
+struct _sas_device *mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
+	u16 handle);
+struct _pcie_device *mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
+	u16 handle);
 
 void mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc);
 struct _raid_device *
@@ -1496,6 +1500,12 @@ int mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc,
 int mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
 	Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
 	u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+	Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+	u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
+	Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
+	u32 form, u32 handle);
 int mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
 	Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
 	u16 sz);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c
index dd62701..1c747cf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -150,6 +150,24 @@ _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
 		case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
 			desc = "driver_mapping";
 			break;
+		case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:
+			desc = "sas_port";
+			break;
+		case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:
+			desc = "ext_manufacturing";
+			break;
+		case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:
+			desc = "pcie_io_unit";
+			break;
+		case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:
+			desc = "pcie_switch";
+			break;
+		case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:
+			desc = "pcie_device";
+			break;
+		case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:
+			desc = "pcie_link";
+			break;
 		}
 		break;
 	}
@@ -1053,6 +1071,88 @@ mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
+ * @ioc: per adapter object
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * @form: GET_NEXT_HANDLE or HANDLE
+ * @handle: device handle
+ * Context: sleep.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+	Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+	u32 form, u32 handle)
+{
+	Mpi2ConfigRequest_t mpi_request;
+	int r;
+
+	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+	mpi_request.Function = MPI2_FUNCTION_CONFIG;
+	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
+	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
+	mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
+	mpi_request.Header.PageNumber = 0;
+	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
+	r = _config_request(ioc, &mpi_request, mpi_reply,
+			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+	if (r)
+		goto out;
+
+	mpi_request.PageAddress = cpu_to_le32(form | handle);
+	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
+	r = _config_request(ioc, &mpi_request, mpi_reply,
+			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+			sizeof(*config_page));
+out:
+	return r;
+}
+
+/**
+ * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2
+ * @ioc: per adapter object
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * @form: GET_NEXT_HANDLE or HANDLE
+ * @handle: device handle
+ * Context: sleep.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
+	Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
+	u32 form, u32 handle)
+{
+	Mpi2ConfigRequest_t mpi_request;
+	int r;
+
+	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+	mpi_request.Function = MPI2_FUNCTION_CONFIG;
+	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
+	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
+	mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION;
+	mpi_request.Header.PageNumber = 2;
+	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
+	r = _config_request(ioc, &mpi_request, mpi_reply,
+			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+	if (r)
+		goto out;
+
+	mpi_request.PageAddress = cpu_to_le32(form | handle);
+	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
+	r = _config_request(ioc, &mpi_request, mpi_reply,
+			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+			sizeof(*config_page));
+out:
+	return r;
+}
+
+/**
  * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host
  * @ioc: per adapter object
  * @num_phys: pointer returned with the number of phys
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 598fb77..d813a11 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -72,7 +72,7 @@ static void _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc,
 	struct _sas_device *sas_device);
 static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 	u8 retry_count, u8 is_pd);
-
+static int _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
 /* global parameters */
@@ -409,11 +409,6 @@ _scsih_get_sas_address(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 
 	*sas_address = 0;
 
-	if (handle <= ioc->sas_hba.num_phys) {
-		*sas_address = ioc->sas_hba.sas_address;
-		return 0;
-	}
-
 	if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
 	    MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
 		pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name,
@@ -423,7 +418,16 @@ _scsih_get_sas_address(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 
 	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
 	if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
-		*sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
+		/*
+		 * For HBA vSES don't return hba sas address instead return
+		 * vSES's sas address.
+		 */
+		if ((handle <= ioc->sas_hba.num_phys) &&
+				(!(le32_to_cpu(sas_device_pg0.DeviceInfo) &
+				   MPI2_SAS_DEVICE_INFO_SEP)))
+			*sas_address = ioc->sas_hba.sas_address;
+		else
+			*sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
 		return 0;
 	}
 
@@ -684,7 +688,7 @@ found_device:
  * This searches for sas_device based on sas_address, then return sas_device
  * object.
  */
-static struct _sas_device *
+struct _sas_device *
 mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 {
 	struct _sas_device *sas_device;
@@ -995,6 +999,55 @@ mpt3sas_get_pdev_by_idchannel(struct MPT3SAS_ADAPTER *ioc, int id, int channel)
 
 	return pcie_device;
 }
+
+
+struct _pcie_device *
+__mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+	struct _pcie_device *pcie_device;
+
+	assert_spin_locked(&ioc->pcie_device_lock);
+
+	list_for_each_entry(pcie_device, &ioc->pcie_device_list, list)
+		if (pcie_device->handle == handle)
+			goto found_device;
+
+	list_for_each_entry(pcie_device, &ioc->pcie_device_init_list, list)
+		if (pcie_device->handle == handle)
+			goto found_device;
+
+	return NULL;
+
+found_device:
+	pcie_device_get(pcie_device);
+	return pcie_device;
+}
+
+
+/**
+ * mpt3sas_get_pdev_by_handle - pcie device search
+ * @ioc: per adapter object
+ * @handle: Firmware device handle
+ *
+ * Context: This function will acquire ioc->pcie_device_lock and will release
+ * before returning the pcie_device object.
+ *
+ * This searches for pcie_device based on handle, then return pcie_device
+ * object.
+ */
+struct _pcie_device *
+mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+	struct _pcie_device *pcie_device;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
+	return pcie_device;
+}
+
 /**
  * _scsih_pcie_device_remove - remove pcie_device from list.
  * @ioc: per adapter object
@@ -1040,6 +1093,85 @@ _scsih_pcie_device_remove(struct MPT3SAS_ADAPTER *ioc,
 	}
 }
 /**
+ * _scsih_pcie_device_add - add pcie_device object
+ * @ioc: per adapter object
+ * @pcie_device: pcie_device object
+ *
+ * This is added to the pcie_device_list link list.
+ */
+static void
+_scsih_pcie_device_add(struct MPT3SAS_ADAPTER *ioc,
+	struct _pcie_device *pcie_device)
+{
+	unsigned long flags;
+
+	dewtprintk(ioc, pr_info(MPT3SAS_FMT
+		"%s: handle (0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
+		pcie_device->handle, (unsigned long long)pcie_device->wwid));
+	if (pcie_device->enclosure_handle != 0)
+		dewtprintk(ioc, pr_info(MPT3SAS_FMT
+			"%s: enclosure logical id(0x%016llx), slot( %d)\n",
+			ioc->name, __func__,
+			(unsigned long long)pcie_device->enclosure_logical_id,
+			pcie_device->slot));
+	if (pcie_device->connector_name[0] != '\0')
+		dewtprintk(ioc, pr_info(MPT3SAS_FMT
+			"%s: enclosure level(0x%04x), connector name( %s)\n",
+			ioc->name, __func__, pcie_device->enclosure_level,
+			pcie_device->connector_name));
+
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	pcie_device_get(pcie_device);
+	list_add_tail(&pcie_device->list, &ioc->pcie_device_list);
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
+	if (scsi_add_device(ioc->shost, PCIE_CHANNEL, pcie_device->id, 0)) {
+		_scsih_pcie_device_remove(ioc, pcie_device);
+	} else if (!pcie_device->starget) {
+		if (!ioc->is_driver_loading) {
+/*TODO-- Need to find out whether this condition will occur or not*/
+			clear_bit(pcie_device->handle, ioc->pend_os_device_add);
+		}
+	} else
+		clear_bit(pcie_device->handle, ioc->pend_os_device_add);
+}
+
+/*
+ * _scsih_pcie_device_init_add - insert pcie_device to the init list.
+ * @ioc: per adapter object
+ * @pcie_device: the pcie_device object
+ * Context: This function will acquire ioc->pcie_device_lock.
+ *
+ * Adding new object at driver load time to the ioc->pcie_device_init_list.
+ */
+static void
+_scsih_pcie_device_init_add(struct MPT3SAS_ADAPTER *ioc,
+				struct _pcie_device *pcie_device)
+{
+	unsigned long flags;
+
+	dewtprintk(ioc, pr_info(MPT3SAS_FMT
+		"%s: handle (0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
+		pcie_device->handle, (unsigned long long)pcie_device->wwid));
+	if (pcie_device->enclosure_handle != 0)
+		dewtprintk(ioc, pr_info(MPT3SAS_FMT
+			"%s: enclosure logical id(0x%016llx), slot( %d)\n",
+			ioc->name, __func__,
+			(unsigned long long)pcie_device->enclosure_logical_id,
+			pcie_device->slot));
+	if (pcie_device->connector_name[0] != '\0')
+		dewtprintk(ioc, pr_info(MPT3SAS_FMT
+			"%s: enclosure level(0x%04x), connector name( %s)\n",
+			ioc->name, __func__, pcie_device->enclosure_level,
+			pcie_device->connector_name));
+
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	pcie_device_get(pcie_device);
+	list_add_tail(&pcie_device->list, &ioc->pcie_device_init_list);
+	_scsih_determine_boot_device(ioc, pcie_device, PCIE_CHANNEL);
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+}
+/**
  * _scsih_raid_device_find_by_id - raid device search
  * @ioc: per adapter object
  * @id: sas device target id
@@ -1250,6 +1382,23 @@ _scsih_is_end_device(u32 device_info)
 }
 
 /**
+ * _scsih_is_nvme_device - determines if device is an nvme device
+ * @device_info: bitfield providing information about the device.
+ * Context: none
+ *
+ * Returns 1 if nvme device.
+ */
+static int
+_scsih_is_nvme_device(u32 device_info)
+{
+	if ((device_info & MPI26_PCIE_DEVINFO_MASK_DEVICE_TYPE)
+					== MPI26_PCIE_DEVINFO_NVME)
+		return 1;
+	else
+		return 0;
+}
+
+/**
  * _scsih_scsi_lookup_get - returns scmd entry
  * @ioc: per adapter object
  * @smid: system request message index
@@ -6299,6 +6448,314 @@ out:
 }
 
 /**
+ * _scsih_check_pcie_access_status - check access flags
+ * @ioc: per adapter object
+ * @wwid: wwid
+ * @handle: sas device handle
+ * @access_flags: errors returned during discovery of the device
+ *
+ * Return 0 for success, else failure
+ */
+static u8
+_scsih_check_pcie_access_status(struct MPT3SAS_ADAPTER *ioc, u64 wwid,
+	u16 handle, u8 access_status)
+{
+	u8 rc = 1;
+	char *desc = NULL;
+
+	switch (access_status) {
+	case MPI26_PCIEDEV0_ASTATUS_NO_ERRORS:
+	case MPI26_PCIEDEV0_ASTATUS_NEEDS_INITIALIZATION:
+		rc = 0;
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_CAPABILITY_FAILED:
+		desc = "PCIe device capability failed";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_DEVICE_BLOCKED:
+		desc = "PCIe device blocked";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_MEMORY_SPACE_ACCESS_FAILED:
+		desc = "PCIe device mem space access failed";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_UNSUPPORTED_DEVICE:
+		desc = "PCIe device unsupported";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_MSIX_REQUIRED:
+		desc = "PCIe device MSIx Required";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_INIT_FAIL_MAX:
+		desc = "PCIe device init fail max";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_UNKNOWN:
+		desc = "PCIe device status unknown";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_NVME_READY_TIMEOUT:
+		desc = "nvme ready timeout";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_NVME_DEVCFG_UNSUPPORTED:
+		desc = "nvme device configuration unsupported";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_NVME_IDENTIFY_FAILED:
+		desc = "nvme identify failed";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_NVME_QCONFIG_FAILED:
+		desc = "nvme qconfig failed";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_NVME_QCREATION_FAILED:
+		desc = "nvme qcreation failed";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_NVME_EVENTCFG_FAILED:
+		desc = "nvme eventcfg failed";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_NVME_GET_FEATURE_STAT_FAILED:
+		desc = "nvme get feature stat failed";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_NVME_IDLE_TIMEOUT:
+		desc = "nvme idle timeout";
+		break;
+	case MPI26_PCIEDEV0_ASTATUS_NVME_FAILURE_STATUS:
+		desc = "nvme failure status";
+		break;
+	default:
+		pr_err(MPT3SAS_FMT
+		    " NVMe discovery error(0x%02x): wwid(0x%016llx),"
+			"handle(0x%04x)\n", ioc->name, access_status,
+			(unsigned long long)wwid, handle);
+		return rc;
+	}
+
+	if (!rc)
+		return rc;
+
+	pr_info(MPT3SAS_FMT
+		"NVMe discovery error(%s): wwid(0x%016llx), handle(0x%04x)\n",
+			ioc->name, desc,
+			(unsigned long long)wwid, handle);
+	return rc;
+}
+/**
+ * _scsih_pcie_check_device - checking device responsiveness
+ * @ioc: per adapter object
+ * @handle: attached device handle
+ *
+ * Returns nothing.
+ */
+static void
+_scsih_pcie_check_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+	Mpi2ConfigReply_t mpi_reply;
+	Mpi26PCIeDevicePage0_t pcie_device_pg0;
+	u32 ioc_status;
+	struct _pcie_device *pcie_device;
+	u64 wwid;
+	unsigned long flags;
+	struct scsi_target *starget;
+	struct MPT3SAS_TARGET *sas_target_priv_data;
+	u32 device_info;
+
+	if ((mpt3sas_config_get_pcie_device_pg0(ioc, &mpi_reply,
+		&pcie_device_pg0, MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE, handle)))
+		return;
+
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
+		return;
+
+	/* check if this is end device */
+	device_info = le32_to_cpu(pcie_device_pg0.DeviceInfo);
+	if (!(_scsih_is_nvme_device(device_info)))
+		return;
+
+	wwid = le64_to_cpu(pcie_device_pg0.WWID);
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	pcie_device = __mpt3sas_get_pdev_by_wwid(ioc, wwid);
+
+	if (!pcie_device) {
+		spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+		return;
+	}
+
+	if (unlikely(pcie_device->handle != handle)) {
+		starget = pcie_device->starget;
+		sas_target_priv_data = starget->hostdata;
+		starget_printk(KERN_INFO, starget,
+		    "handle changed from(0x%04x) to (0x%04x)!!!\n",
+		    pcie_device->handle, handle);
+		sas_target_priv_data->handle = handle;
+		pcie_device->handle = handle;
+
+		if (le32_to_cpu(pcie_device_pg0.Flags) &
+		    MPI26_PCIEDEV0_FLAGS_ENCL_LEVEL_VALID) {
+			pcie_device->enclosure_level =
+			    pcie_device_pg0.EnclosureLevel;
+			memcpy(&pcie_device->connector_name[0],
+			    &pcie_device_pg0.ConnectorName[0], 4);
+		} else {
+			pcie_device->enclosure_level = 0;
+			pcie_device->connector_name[0] = '\0';
+		}
+	}
+
+	/* check if device is present */
+	if (!(le32_to_cpu(pcie_device_pg0.Flags) &
+	    MPI26_PCIEDEV0_FLAGS_DEVICE_PRESENT)) {
+		pr_info(MPT3SAS_FMT
+		    "device is not present handle(0x%04x), flags!!!\n",
+		    ioc->name, handle);
+		spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+		pcie_device_put(pcie_device);
+		return;
+	}
+
+	/* check if there were any issues with discovery */
+	if (_scsih_check_pcie_access_status(ioc, wwid, handle,
+	    pcie_device_pg0.AccessStatus)) {
+		spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+		pcie_device_put(pcie_device);
+		return;
+	}
+
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+	pcie_device_put(pcie_device);
+
+	_scsih_ublock_io_device(ioc, wwid);
+
+	return;
+}
+
+/**
+ * _scsih_pcie_add_device -  creating pcie device object
+ * @ioc: per adapter object
+ * @handle: pcie device handle
+ *
+ * Creating end device object, stored in ioc->pcie_device_list.
+ *
+ * Return 1 means queue the event later, 0 means complete the event
+ */
+static int
+_scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+	Mpi26PCIeDevicePage0_t pcie_device_pg0;
+	Mpi26PCIeDevicePage2_t pcie_device_pg2;
+	Mpi2ConfigReply_t mpi_reply;
+	Mpi2SasEnclosurePage0_t enclosure_pg0;
+	struct _pcie_device *pcie_device;
+	u32 pcie_device_type;
+	u32 ioc_status;
+	u64 wwid;
+
+	if ((mpt3sas_config_get_pcie_device_pg0(ioc, &mpi_reply,
+	    &pcie_device_pg0, MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE, handle))) {
+		pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		return 0;
+	}
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+	    MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+		pr_err(MPT3SAS_FMT
+		    "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		return 0;
+	}
+
+	set_bit(handle, ioc->pend_os_device_add);
+	wwid = le64_to_cpu(pcie_device_pg0.WWID);
+
+	/* check if device is present */
+	if (!(le32_to_cpu(pcie_device_pg0.Flags) &
+		MPI26_PCIEDEV0_FLAGS_DEVICE_PRESENT)) {
+		pr_err(MPT3SAS_FMT
+		    "device is not present handle(0x04%x)!!!\n",
+		    ioc->name, handle);
+		return 0;
+	}
+
+	/* check if there were any issues with discovery */
+	if (_scsih_check_pcie_access_status(ioc, wwid, handle,
+	    pcie_device_pg0.AccessStatus))
+		return 0;
+
+	if (!(_scsih_is_nvme_device(le32_to_cpu(pcie_device_pg0.DeviceInfo))))
+		return 0;
+
+	pcie_device = mpt3sas_get_pdev_by_wwid(ioc, wwid);
+	if (pcie_device) {
+		clear_bit(handle, ioc->pend_os_device_add);
+		pcie_device_put(pcie_device);
+		return 0;
+	}
+
+	pcie_device = kzalloc(sizeof(struct _pcie_device), GFP_KERNEL);
+	if (!pcie_device) {
+		pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
+			ioc->name, __FILE__, __LINE__, __func__);
+		return 0;
+	}
+
+	kref_init(&pcie_device->refcount);
+	pcie_device->id = ioc->pcie_target_id++;
+	pcie_device->channel = PCIE_CHANNEL;
+	pcie_device->handle = handle;
+	pcie_device->device_info = le32_to_cpu(pcie_device_pg0.DeviceInfo);
+	pcie_device->wwid = wwid;
+	pcie_device->port_num = pcie_device_pg0.PortNum;
+	pcie_device->fast_path = (le32_to_cpu(pcie_device_pg0.Flags) &
+	    MPI26_PCIEDEV0_FLAGS_FAST_PATH_CAPABLE) ? 1 : 0;
+	pcie_device_type = pcie_device->device_info &
+	    MPI26_PCIE_DEVINFO_MASK_DEVICE_TYPE;
+
+	pcie_device->enclosure_handle =
+	    le16_to_cpu(pcie_device_pg0.EnclosureHandle);
+	if (pcie_device->enclosure_handle != 0)
+		pcie_device->slot = le16_to_cpu(pcie_device_pg0.Slot);
+
+	if (le16_to_cpu(pcie_device_pg0.Flags) &
+	    MPI26_PCIEDEV0_FLAGS_ENCL_LEVEL_VALID) {
+		pcie_device->enclosure_level = pcie_device_pg0.EnclosureLevel;
+		memcpy(&pcie_device->connector_name[0],
+		    &pcie_device_pg0.ConnectorName[0], 4);
+	} else {
+		pcie_device->enclosure_level = 0;
+		pcie_device->connector_name[0] = '\0';
+	}
+
+	/* get enclosure_logical_id */
+	if (pcie_device->enclosure_handle &&
+		!(mpt3sas_config_get_enclosure_pg0(ioc, &mpi_reply,
+			&enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
+			pcie_device->enclosure_handle)))
+		pcie_device->enclosure_logical_id =
+			le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
+
+	/*TODO -- Add device name once FW supports it*/
+	if (mpt3sas_config_get_pcie_device_pg2(ioc, &mpi_reply,
+		&pcie_device_pg2, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle)) {
+		pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
+				ioc->name, __FILE__, __LINE__, __func__);
+		kfree(pcie_device);
+		return 0;
+	}
+
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+		pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
+			ioc->name, __FILE__, __LINE__, __func__);
+		kfree(pcie_device);
+		return 0;
+	}
+	pcie_device->nvme_mdts =
+		le32_to_cpu(pcie_device_pg2.MaximumDataTransferSize);
+
+	if (ioc->wait_for_discovery_to_complete)
+		_scsih_pcie_device_init_add(ioc, pcie_device);
+	else
+		_scsih_pcie_device_add(ioc, pcie_device);
+
+	pcie_device_put(pcie_device);
+	return 0;
+}
+/**
  * _scsih_sas_enclosure_dev_status_change_event_debug - debug for enclosure
  * event
  * @ioc: per adapter object
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 06/13] mpt3sas: API's to remove nvme drive from sml
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
                   ` (4 preceding siblings ...)
  2017-07-14 13:22 ` [PATCH v2 05/13] mpt3sas: API 's to support NVMe drive addition to SML Suganath Prabu S
@ 2017-07-14 13:22 ` Suganath Prabu S
  2017-08-03  6:36   ` Hannes Reinecke
  2017-07-14 13:22 ` [PATCH v2 07/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware Suganath Prabu S
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

Below API's are included in nvme drive remove path.
_scsih_pcie_device_remove_by_handle
_scsih_pcie_device_remove_from_sml

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  148 +++++++++++++++++++++++++++++++++-
 1 files changed, 145 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index d813a11..6d730bc 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -73,6 +73,8 @@ static void _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc,
 static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 	u8 retry_count, u8 is_pd);
 static int _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
+static void _scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
+	struct _pcie_device *pcie_device);
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
 /* global parameters */
@@ -1092,6 +1094,41 @@ _scsih_pcie_device_remove(struct MPT3SAS_ADAPTER *ioc,
 		pcie_device_put(pcie_device);
 	}
 }
+
+
+/**
+ * _scsih_pcie_device_remove_by_handle - removing pcie device object by handle
+ * @ioc: per adapter object
+ * @handle: device handle
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_remove_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+	struct _pcie_device *pcie_device;
+	unsigned long flags;
+	int was_on_pcie_device_list = 0;
+
+	if (ioc->shost_recovery)
+		return;
+
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+	if (pcie_device) {
+		if (!list_empty(&pcie_device->list)) {
+			list_del_init(&pcie_device->list);
+			was_on_pcie_device_list = 1;
+			pcie_device_put(pcie_device);
+		}
+	}
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+	if (was_on_pcie_device_list) {
+		_scsih_pcie_device_remove_from_sml(ioc, pcie_device);
+		pcie_device_put(pcie_device);
+	}
+}
+
 /**
  * _scsih_pcie_device_add - add pcie_device object
  * @ioc: per adapter object
@@ -6533,6 +6570,83 @@ _scsih_check_pcie_access_status(struct MPT3SAS_ADAPTER *ioc, u64 wwid,
 			(unsigned long long)wwid, handle);
 	return rc;
 }
+
+/**
+ * _scsih_pcie_device_remove_from_sml -  removing pcie device
+ * from SML and free up associated memory
+ * @ioc: per adapter object
+ * @pcie_device: the pcie_device object
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
+	struct _pcie_device *pcie_device)
+{
+	struct MPT3SAS_TARGET *sas_target_priv_data;
+
+	dewtprintk(ioc, pr_info(MPT3SAS_FMT
+	    "%s: enter: handle(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
+	    pcie_device->handle, (unsigned long long)
+	    pcie_device->wwid));
+	if (pcie_device->enclosure_handle != 0)
+		dewtprintk(ioc, pr_info(MPT3SAS_FMT
+		    "%s: enter: enclosure logical id(0x%016llx), slot(%d)\n",
+		    ioc->name, __func__,
+		    (unsigned long long)pcie_device->enclosure_logical_id,
+		    pcie_device->slot));
+	if (pcie_device->connector_name[0] != '\0')
+		dewtprintk(ioc, pr_info(MPT3SAS_FMT
+		    "%s: enter: enclosure level(0x%04x), connector name( %s)\n",
+		    ioc->name, __func__,
+		    pcie_device->enclosure_level,
+		    pcie_device->connector_name));
+
+	if (pcie_device->starget && pcie_device->starget->hostdata) {
+		sas_target_priv_data = pcie_device->starget->hostdata;
+		sas_target_priv_data->deleted = 1;
+		_scsih_ublock_io_device(ioc, pcie_device->wwid);
+		sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE;
+	}
+
+	pr_info(MPT3SAS_FMT
+		"removing handle(0x%04x), wwid (0x%016llx)\n",
+		ioc->name, pcie_device->handle,
+		(unsigned long long) pcie_device->wwid);
+	if (pcie_device->enclosure_handle != 0)
+		pr_info(MPT3SAS_FMT
+		    "removing : enclosure logical id(0x%016llx), slot(%d)\n",
+		    ioc->name,
+		    (unsigned long long)pcie_device->enclosure_logical_id,
+		    pcie_device->slot);
+	if (pcie_device->connector_name[0] != '\0')
+		pr_info(MPT3SAS_FMT
+		    "removing: enclosure level(0x%04x), connector name( %s)\n",
+		    ioc->name, pcie_device->enclosure_level,
+		    pcie_device->connector_name);
+
+	if (pcie_device->starget)
+		scsi_remove_target(&pcie_device->starget->dev);
+	dewtprintk(ioc, pr_info(MPT3SAS_FMT
+	    "%s: exit: handle(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
+	    pcie_device->handle, (unsigned long long)
+	    pcie_device->wwid));
+	if (pcie_device->enclosure_handle != 0)
+		dewtprintk(ioc, pr_info(MPT3SAS_FMT
+			"%s: exit: enclosure logical id(0x%016llx), slot(%d)\n",
+			ioc->name, __func__,
+			(unsigned long long)pcie_device->enclosure_logical_id,
+			pcie_device->slot));
+	if (pcie_device->connector_name[0] != '\0')
+		dewtprintk(ioc, pr_info(MPT3SAS_FMT
+		    "%s: exit: enclosure level(0x%04x), connector name( %s)\n",
+		    ioc->name, __func__, pcie_device->enclosure_level,
+		    pcie_device->connector_name));
+
+	kfree(pcie_device->serial_number);
+}
+
+
 /**
  * _scsih_pcie_check_device - checking device responsiveness
  * @ioc: per adapter object
@@ -8127,17 +8241,18 @@ _scsih_search_responding_expanders(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
- * _scsih_remove_unresponding_sas_devices - removing unresponding devices
+ * _scsih_remove_unresponding_devices - removing unresponding devices
  * @ioc: per adapter object
  *
  * Return nothing.
  */
 static void
-_scsih_remove_unresponding_sas_devices(struct MPT3SAS_ADAPTER *ioc)
+_scsih_remove_unresponding_devices(struct MPT3SAS_ADAPTER *ioc)
 {
 	struct _sas_device *sas_device, *sas_device_next;
 	struct _sas_node *sas_expander, *sas_expander_next;
 	struct _raid_device *raid_device, *raid_device_next;
+	struct _pcie_device *pcie_device, *pcie_device_next;
 	struct list_head tmp_list;
 	unsigned long flags;
 	LIST_HEAD(head);
@@ -8171,6 +8286,26 @@ _scsih_remove_unresponding_sas_devices(struct MPT3SAS_ADAPTER *ioc)
 		sas_device_put(sas_device);
 	}
 
+	pr_info(MPT3SAS_FMT
+		" Removing unresponding devices: pcie end-devices\n"
+		, ioc->name);
+	INIT_LIST_HEAD(&head);
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	list_for_each_entry_safe(pcie_device, pcie_device_next,
+	    &ioc->pcie_device_list, list) {
+		if (!pcie_device->responding)
+			list_move_tail(&pcie_device->list, &head);
+		else
+			pcie_device->responding = 0;
+	}
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
+	list_for_each_entry_safe(pcie_device, pcie_device_next, &head, list) {
+		_scsih_pcie_device_remove_from_sml(ioc, pcie_device);
+		list_del_init(&pcie_device->list);
+		pcie_device_put(pcie_device);
+	}
+
 	/* removing unresponding volumes */
 	if (ioc->ir_firmware) {
 		pr_info(MPT3SAS_FMT "removing unresponding devices: volumes\n",
@@ -8573,7 +8708,7 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
 				goto out;
 			ssleep(1);
 		}
-		_scsih_remove_unresponding_sas_devices(ioc);
+		_scsih_remove_unresponding_devices(ioc);
 		_scsih_scan_for_devices_after_reset(ioc);
 		break;
 	case MPT3SAS_PORT_ENABLE_COMPLETE:
@@ -8955,6 +9090,7 @@ static void scsih_remove(struct pci_dev *pdev)
 	struct _sas_port *mpt3sas_port, *next_port;
 	struct _raid_device *raid_device, *next;
 	struct MPT3SAS_TARGET *sas_target_priv_data;
+	struct _pcie_device *pcie_device, *pcienext;
 	struct workqueue_struct	*wq;
 	unsigned long flags;
 
@@ -8983,6 +9119,12 @@ static void scsih_remove(struct pci_dev *pdev)
 		    (unsigned long long) raid_device->wwid);
 		_scsih_raid_device_remove(ioc, raid_device);
 	}
+	list_for_each_entry_safe(pcie_device, pcienext, &ioc->pcie_device_list,
+		list) {
+		_scsih_pcie_device_remove_from_sml(ioc, pcie_device);
+		list_del_init(&pcie_device->list);
+		pcie_device_put(pcie_device);
+	}
 
 	/* free ports attached to the sas_host */
 	list_for_each_entry_safe(mpt3sas_port, next_port,
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 07/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware.
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
                   ` (5 preceding siblings ...)
  2017-07-14 13:22 ` [PATCH v2 06/13] mpt3sas: API's to remove nvme drive from sml Suganath Prabu S
@ 2017-07-14 13:22 ` Suganath Prabu S
  2017-08-03  6:38   ` Hannes Reinecke
  2017-07-14 13:22 ` [PATCH v2 08/13] mpt3sas: Set NVMe device queue depth as 128 Suganath Prabu S
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

* The controller firmware sends separate events for NVMe devices and
PCIe switches similar to existing SAS events.

* NVMe device detection, addition and removal are reported by the
firmware through PCIe Topology Change list events.

* The PCIe device state change events are sent when the firmware
detects any abnormal conditions with a NVMe device or switch.

* The enumeration event are sent when the firmware starts PCIe device
enumeration and stops.

* This patch has the code change to handle the events and add/remove
NVMe devices in driver's inventory.

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |   30 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  471 +++++++++++++++++++++++++++++++++-
 2 files changed, 495 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index c3a6c7a..794b2c0 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -663,6 +663,26 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
 	case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
 		desc = "Active cable exception";
 		break;
+	case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
+		desc = "PCIE Device Status Change";
+		break;
+	case MPI2_EVENT_PCIE_ENUMERATION:
+	{
+		Mpi26EventDataPCIeEnumeration_t *event_data =
+			(Mpi26EventDataPCIeEnumeration_t *)mpi_reply->EventData;
+		pr_info(MPT3SAS_FMT "PCIE Enumeration: (%s)", ioc->name,
+			   (event_data->ReasonCode ==
+				MPI26_EVENT_PCIE_ENUM_RC_STARTED) ?
+				"start" : "stop");
+		if (event_data->EnumerationStatus)
+			pr_info("enumeration_status(0x%08x)",
+				   le32_to_cpu(event_data->EnumerationStatus));
+		pr_info("\n");
+		return;
+	}
+	case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
+		desc = "PCIE Topology Change List";
+		break;
 	}
 
 	if (!desc)
@@ -6188,8 +6208,16 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
 	_base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS);
 	_base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
 	_base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD);
-	if (ioc->hba_mpi_version_belonged == MPI26_VERSION)
+	if (ioc->hba_mpi_version_belonged == MPI26_VERSION) {
 		_base_unmask_events(ioc, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
+		if (ioc->is_gen35_ioc) {
+			_base_unmask_events(ioc,
+				MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE);
+			_base_unmask_events(ioc, MPI2_EVENT_PCIE_ENUMERATION);
+			_base_unmask_events(ioc,
+				MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST);
+		}
+	}
 
 	r = _base_make_ioc_operational(ioc);
 	if (r)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 6d730bc..1dd9674 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -75,6 +75,8 @@ static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 static int _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static void _scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
 	struct _pcie_device *pcie_device);
+static void
+_scsih_pcie_check_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
 /* global parameters */
@@ -3458,8 +3460,6 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	struct _sas_device *sas_device;
 
 	sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
-	if (!sas_device)
-		return;
 
 	shost_for_each_device(sdev, ioc->shost) {
 		sas_device_priv_data = sdev->hostdata;
@@ -3469,7 +3469,7 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 			continue;
 		if (sas_device_priv_data->block)
 			continue;
-		if (sas_device->pend_sas_rphy_add)
+		if (sas_device && sas_device->pend_sas_rphy_add)
 			continue;
 		if (sas_device_priv_data->ignore_delay_remove) {
 			sdev_printk(KERN_INFO, sdev,
@@ -3480,7 +3480,8 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 		_scsih_internal_device_block(sdev, sas_device_priv_data);
 	}
 
-	sas_device_put(sas_device);
+	if (sas_device)
+		sas_device_put(sas_device);
 }
 
 /**
@@ -3564,6 +3565,33 @@ _scsih_block_io_to_children_attached_directly(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _scsih_block_io_to_pcie_children_attached_directly
+ * @ioc: per adapter object
+ * @event_data: topology change event data
+ *
+ * This routine set sdev state to SDEV_BLOCK for all devices
+ * direct attached during device pull/reconnect.
+ */
+static void
+_scsih_block_io_to_pcie_children_attached_directly(struct MPT3SAS_ADAPTER *ioc,
+		Mpi26EventDataPCIeTopologyChangeList_t *event_data)
+{
+	int i;
+	u16 handle;
+	u16 reason_code;
+
+	for (i = 0; i < event_data->NumEntries; i++) {
+		handle =
+			le16_to_cpu(event_data->PortEntry[i].AttachedDevHandle);
+		if (!handle)
+			continue;
+		reason_code = event_data->PortEntry[i].PortStatus;
+		if (reason_code ==
+				MPI26_EVENT_PCIE_TOPO_PS_DELAY_NOT_RESPONDING)
+			_scsih_block_io_device(ioc, handle);
+	}
+}
+/**
  * _scsih_tm_tr_send - send task management request
  * @ioc: per adapter object
  * @handle: device handle
@@ -4182,6 +4210,81 @@ _scsih_check_topo_delete_events(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _scsih_check_pcie_topo_remove_events - sanity check on topo
+ * events
+ * @ioc: per adapter object
+ * @event_data: the event data payload
+ *
+ * This handles the case where driver receives multiple switch
+ * or device add and delete events in a single shot.  When there
+ * is a delete event the routine will void any pending add
+ * events waiting in the event queue.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_check_pcie_topo_remove_events(struct MPT3SAS_ADAPTER *ioc,
+	Mpi26EventDataPCIeTopologyChangeList_t *event_data)
+{
+	struct fw_event_work *fw_event;
+	Mpi26EventDataPCIeTopologyChangeList_t *local_event_data;
+	unsigned long flags;
+	int i, reason_code;
+	u16 handle, switch_handle;
+
+	for (i = 0; i < event_data->NumEntries; i++) {
+		handle =
+			le16_to_cpu(event_data->PortEntry[i].AttachedDevHandle);
+		if (!handle)
+			continue;
+		reason_code = event_data->PortEntry[i].PortStatus;
+		if (reason_code == MPI26_EVENT_PCIE_TOPO_PS_NOT_RESPONDING)
+			_scsih_tm_tr_send(ioc, handle);
+	}
+
+	switch_handle = le16_to_cpu(event_data->SwitchDevHandle);
+	if (!switch_handle) {
+		_scsih_block_io_to_pcie_children_attached_directly(
+							ioc, event_data);
+		return;
+	}
+    /* TODO We are not supporting cascaded PCIe Switch removal yet*/
+	if ((event_data->SwitchStatus
+		== MPI26_EVENT_PCIE_TOPO_SS_DELAY_NOT_RESPONDING) ||
+		(event_data->SwitchStatus ==
+					MPI26_EVENT_PCIE_TOPO_SS_RESPONDING))
+		_scsih_block_io_to_pcie_children_attached_directly(
+							ioc, event_data);
+
+	if (event_data->SwitchStatus != MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING)
+		return;
+
+	/* mark ignore flag for pending events */
+	spin_lock_irqsave(&ioc->fw_event_lock, flags);
+	list_for_each_entry(fw_event, &ioc->fw_event_list, list) {
+		if (fw_event->event != MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST ||
+			fw_event->ignore)
+			continue;
+		local_event_data =
+			(Mpi26EventDataPCIeTopologyChangeList_t *)
+			fw_event->event_data;
+		if (local_event_data->SwitchStatus ==
+		    MPI2_EVENT_SAS_TOPO_ES_ADDED ||
+		    local_event_data->SwitchStatus ==
+		    MPI2_EVENT_SAS_TOPO_ES_RESPONDING) {
+			if (le16_to_cpu(local_event_data->SwitchDevHandle) ==
+				switch_handle) {
+				dewtprintk(ioc, pr_info(MPT3SAS_FMT
+					"setting ignoring flag for switch event\n",
+					ioc->name));
+				fw_event->ignore = 1;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
+}
+
+/**
  * _scsih_set_volume_delete_flag - setting volume delete flag
  * @ioc: per adapter object
  * @handle: device handle
@@ -6481,9 +6584,9 @@ out:
 		sas_device_put(sas_device);
 
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
 }
 
+
 /**
  * _scsih_check_pcie_access_status - check access flags
  * @ioc: per adapter object
@@ -6869,6 +6972,319 @@ _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	pcie_device_put(pcie_device);
 	return 0;
 }
+
+/**
+ * _scsih_pcie_topology_change_event_debug - debug for topology
+ * event
+ * @ioc: per adapter object
+ * @event_data: event data payload
+ * Context: user.
+ */
+static void
+_scsih_pcie_topology_change_event_debug(struct MPT3SAS_ADAPTER *ioc,
+	Mpi26EventDataPCIeTopologyChangeList_t *event_data)
+{
+	int i;
+	u16 handle;
+	u16 reason_code;
+	u8 port_number;
+	char *status_str = NULL;
+	u8 link_rate, prev_link_rate;
+
+	switch (event_data->SwitchStatus) {
+	case MPI26_EVENT_PCIE_TOPO_SS_ADDED:
+		status_str = "add";
+		break;
+	case MPI26_EVENT_PCIE_TOPO_SS_NOT_RESPONDING:
+		status_str = "remove";
+		break;
+	case MPI26_EVENT_PCIE_TOPO_SS_RESPONDING:
+	case 0:
+		status_str =  "responding";
+		break;
+	case MPI26_EVENT_PCIE_TOPO_SS_DELAY_NOT_RESPONDING:
+		status_str = "remove delay";
+		break;
+	default:
+		status_str = "unknown status";
+		break;
+	}
+	pr_info(MPT3SAS_FMT "pcie topology change: (%s)\n",
+		ioc->name, status_str);
+	pr_info("\tswitch_handle(0x%04x), enclosure_handle(0x%04x)"
+		"start_port(%02d), count(%d)\n",
+		le16_to_cpu(event_data->SwitchDevHandle),
+		le16_to_cpu(event_data->EnclosureHandle),
+		event_data->StartPortNum, event_data->NumEntries);
+	for (i = 0; i < event_data->NumEntries; i++) {
+		handle =
+			le16_to_cpu(event_data->PortEntry[i].AttachedDevHandle);
+		if (!handle)
+			continue;
+		port_number = event_data->StartPortNum + i;
+		reason_code = event_data->PortEntry[i].PortStatus;
+		switch (reason_code) {
+		case MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED:
+			status_str = "target add";
+			break;
+		case MPI26_EVENT_PCIE_TOPO_PS_NOT_RESPONDING:
+			status_str = "target remove";
+			break;
+		case MPI26_EVENT_PCIE_TOPO_PS_DELAY_NOT_RESPONDING:
+			status_str = "delay target remove";
+			break;
+		case MPI26_EVENT_PCIE_TOPO_PS_PORT_CHANGED:
+			status_str = "link rate change";
+			break;
+		case MPI26_EVENT_PCIE_TOPO_PS_NO_CHANGE:
+			status_str = "target responding";
+			break;
+		default:
+			status_str = "unknown";
+			break;
+		}
+		link_rate = event_data->PortEntry[i].CurrentPortInfo &
+			MPI26_EVENT_PCIE_TOPO_PI_RATE_MASK;
+		prev_link_rate = event_data->PortEntry[i].PreviousPortInfo &
+			MPI26_EVENT_PCIE_TOPO_PI_RATE_MASK;
+		pr_info("\tport(%02d), attached_handle(0x%04x): %s:"
+			" link rate: new(0x%02x), old(0x%02x)\n", port_number,
+			handle, status_str, link_rate, prev_link_rate);
+	}
+}
+
+/**
+ * _scsih_pcie_topology_change_event - handle PCIe topology
+ *  changes
+ * @ioc: per adapter object
+ * @fw_event: The fw_event_work object
+ * Context: user.
+ *
+ */
+static int
+_scsih_pcie_topology_change_event(struct MPT3SAS_ADAPTER *ioc,
+	struct fw_event_work *fw_event)
+{
+	int i;
+	u16 handle;
+	u16 reason_code;
+	u8 link_rate, prev_link_rate;
+	unsigned long flags;
+	int rc;
+	int requeue_event;
+	Mpi26EventDataPCIeTopologyChangeList_t *event_data =
+		(Mpi26EventDataPCIeTopologyChangeList_t *) fw_event->event_data;
+	struct _pcie_device *pcie_device;
+
+	if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
+		_scsih_pcie_topology_change_event_debug(ioc, event_data);
+
+	if (ioc->shost_recovery || ioc->remove_host ||
+		ioc->pci_error_recovery)
+		return 0;
+
+	if (fw_event->ignore) {
+		dewtprintk(ioc, pr_info(MPT3SAS_FMT "ignoring switch event\n",
+			ioc->name));
+		return 0;
+	}
+
+	/* handle siblings events */
+	for (i = 0; i < event_data->NumEntries; i++) {
+		if (fw_event->ignore) {
+			dewtprintk(ioc, pr_info(MPT3SAS_FMT
+				"ignoring switch event\n", ioc->name));
+			return 0;
+		}
+		if (ioc->remove_host || ioc->pci_error_recovery)
+			return 0;
+		reason_code = event_data->PortEntry[i].PortStatus;
+		handle =
+			le16_to_cpu(event_data->PortEntry[i].AttachedDevHandle);
+		if (!handle)
+			continue;
+
+		link_rate = event_data->PortEntry[i].CurrentPortInfo
+			& MPI26_EVENT_PCIE_TOPO_PI_RATE_MASK;
+		prev_link_rate = event_data->PortEntry[i].PreviousPortInfo
+			& MPI26_EVENT_PCIE_TOPO_PI_RATE_MASK;
+
+		switch (reason_code) {
+		case MPI26_EVENT_PCIE_TOPO_PS_PORT_CHANGED:
+			if (ioc->shost_recovery)
+				break;
+			if (link_rate == prev_link_rate)
+				break;
+			if (link_rate < MPI26_EVENT_PCIE_TOPO_PI_RATE_2_5)
+				break;
+
+			_scsih_pcie_check_device(ioc, handle);
+
+			/* This code after this point handles the test case
+			 * where a device has been added, however its returning
+			 * BUSY for sometime.  Then before the Device Missing
+			 * Delay expires and the device becomes READY, the
+			 * device is removed and added back.
+			 */
+			spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+			pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+			spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
+			if (pcie_device) {
+				pcie_device_put(pcie_device);
+				break;
+			}
+
+			if (!test_bit(handle, ioc->pend_os_device_add))
+				break;
+
+			dewtprintk(ioc, pr_info(MPT3SAS_FMT
+				"handle(0x%04x) device not found: convert "
+				"event to a device add\n", ioc->name, handle));
+			event_data->PortEntry[i].PortStatus &= 0xF0;
+			event_data->PortEntry[i].PortStatus |=
+				MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED;
+		case MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED:
+			if (ioc->shost_recovery)
+				break;
+			if (link_rate < MPI26_EVENT_PCIE_TOPO_PI_RATE_2_5)
+				break;
+
+			rc = _scsih_pcie_add_device(ioc, handle);
+			if (!rc) {
+				/* mark entry vacant */
+				/* TODO This needs to be reviewed and fixed,
+				 * we dont have an entry
+				 * to make an event void like vacant
+				 */
+				event_data->PortEntry[i].PortStatus |=
+					MPI26_EVENT_PCIE_TOPO_PS_NO_CHANGE;
+			}
+			break;
+		case MPI26_EVENT_PCIE_TOPO_PS_NOT_RESPONDING:
+			_scsih_pcie_device_remove_by_handle(ioc, handle);
+			break;
+		}
+	}
+	return requeue_event;
+}
+
+/**
+ * _scsih_pcie_device_status_change_event_debug - debug for
+ * device event
+ * @event_data: event data payload
+ * Context: user.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_status_change_event_debug(struct MPT3SAS_ADAPTER *ioc,
+	Mpi26EventDataPCIeDeviceStatusChange_t *event_data)
+{
+	char *reason_str = NULL;
+
+	switch (event_data->ReasonCode) {
+	case MPI26_EVENT_PCIDEV_STAT_RC_SMART_DATA:
+		reason_str = "smart data";
+		break;
+	case MPI26_EVENT_PCIDEV_STAT_RC_UNSUPPORTED:
+		reason_str = "unsupported device discovered";
+		break;
+	case MPI26_EVENT_PCIDEV_STAT_RC_INTERNAL_DEVICE_RESET:
+		reason_str = "internal device reset";
+		break;
+	case MPI26_EVENT_PCIDEV_STAT_RC_TASK_ABORT_INTERNAL:
+		reason_str = "internal task abort";
+		break;
+	case MPI26_EVENT_PCIDEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
+		reason_str = "internal task abort set";
+		break;
+	case MPI26_EVENT_PCIDEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
+		reason_str = "internal clear task set";
+		break;
+	case MPI26_EVENT_PCIDEV_STAT_RC_QUERY_TASK_INTERNAL:
+		reason_str = "internal query task";
+		break;
+	case MPI26_EVENT_PCIDEV_STAT_RC_DEV_INIT_FAILURE:
+		reason_str = "device init failure";
+		break;
+	case MPI26_EVENT_PCIDEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
+		reason_str = "internal device reset complete";
+		break;
+	case MPI26_EVENT_PCIDEV_STAT_RC_CMP_TASK_ABORT_INTERNAL:
+		reason_str = "internal task abort complete";
+		break;
+	case MPI26_EVENT_PCIDEV_STAT_RC_ASYNC_NOTIFICATION:
+		reason_str = "internal async notification";
+		break;
+	default:
+		reason_str = "unknown reason";
+		break;
+	}
+
+	pr_info(MPT3SAS_FMT "PCIE device status change: (%s)\n"
+		"\thandle(0x%04x), WWID(0x%016llx), tag(%d)",
+		ioc->name, reason_str, le16_to_cpu(event_data->DevHandle),
+		(unsigned long long)le64_to_cpu(event_data->WWID),
+		le16_to_cpu(event_data->TaskTag));
+	if (event_data->ReasonCode == MPI26_EVENT_PCIDEV_STAT_RC_SMART_DATA)
+		pr_info(MPT3SAS_FMT ", ASC(0x%x), ASCQ(0x%x)\n", ioc->name,
+			event_data->ASC, event_data->ASCQ);
+	pr_info("\n");
+}
+
+/**
+ * _scsih_pcie_device_status_change_event - handle device status
+ * change
+ * @ioc: per adapter object
+ * @fw_event: The fw_event_work object
+ * Context: user.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_status_change_event(struct MPT3SAS_ADAPTER *ioc,
+	struct fw_event_work *fw_event)
+{
+	struct MPT3SAS_TARGET *target_priv_data;
+	struct _pcie_device *pcie_device;
+	u64 wwid;
+	unsigned long flags;
+	Mpi26EventDataPCIeDeviceStatusChange_t *event_data =
+		(Mpi26EventDataPCIeDeviceStatusChange_t *)fw_event->event_data;
+	if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
+		_scsih_pcie_device_status_change_event_debug(ioc,
+			event_data);
+
+	if (event_data->ReasonCode !=
+		MPI26_EVENT_PCIDEV_STAT_RC_INTERNAL_DEVICE_RESET &&
+		event_data->ReasonCode !=
+		MPI26_EVENT_PCIDEV_STAT_RC_CMP_INTERNAL_DEV_RESET)
+		return;
+
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	wwid = le64_to_cpu(event_data->WWID);
+	pcie_device = __mpt3sas_get_pdev_by_wwid(ioc, wwid);
+
+	if (!pcie_device || !pcie_device->starget)
+		goto out;
+
+	target_priv_data = pcie_device->starget->hostdata;
+	if (!target_priv_data)
+		goto out;
+
+	if (event_data->ReasonCode ==
+		MPI26_EVENT_PCIDEV_STAT_RC_INTERNAL_DEVICE_RESET)
+		target_priv_data->tm_busy = 1;
+	else
+		target_priv_data->tm_busy = 0;
+out:
+	if (pcie_device)
+		pcie_device_put(pcie_device);
+
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+}
+
 /**
  * _scsih_sas_enclosure_dev_status_change_event_debug - debug for enclosure
  * event
@@ -7120,6 +7536,34 @@ _scsih_sas_discovery_event(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _scsih_pcie_enumeration_event - handle enumeration events
+ * @ioc: per adapter object
+ * @fw_event: The fw_event_work object
+ * Context: user.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_enumeration_event(struct MPT3SAS_ADAPTER *ioc,
+	struct fw_event_work *fw_event)
+{
+	Mpi26EventDataPCIeEnumeration_t *event_data =
+		(Mpi26EventDataPCIeEnumeration_t *)fw_event->event_data;
+
+	if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) {
+		pr_info(MPT3SAS_FMT "pcie enumeration event: (%s) Flag 0x%02x",
+			ioc->name,
+			((event_data->ReasonCode ==
+			MPI26_EVENT_PCIE_ENUM_RC_STARTED) ?
+			"started" : "completed"), event_data->Flags);
+	if (event_data->EnumerationStatus)
+		pr_info("enumeration_status(0x%08x)",
+		    le32_to_cpu(event_data->EnumerationStatus));
+	pr_info("\n");
+	}
+}
+
+/**
  * _scsih_ir_fastpath - turn on fastpath for IR physdisk
  * @ioc: per adapter object
  * @handle: device handle for physical disk
@@ -8751,6 +9195,16 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
 	case MPI2_EVENT_IR_OPERATION_STATUS:
 		_scsih_sas_ir_operation_status_event(ioc, fw_event);
 		break;
+	case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
+		_scsih_pcie_device_status_change_event(ioc, fw_event);
+		break;
+	case MPI2_EVENT_PCIE_ENUMERATION:
+		_scsih_pcie_enumeration_event(ioc, fw_event);
+		break;
+	case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
+		_scsih_pcie_topology_change_event(ioc, fw_event);
+			return;
+	break;
 	}
 out:
 	fw_event_work_put(fw_event);
@@ -8841,6 +9295,11 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
 		    (Mpi2EventDataSasTopologyChangeList_t *)
 		    mpi_reply->EventData);
 		break;
+	case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
+	_scsih_check_pcie_topo_remove_events(ioc,
+		    (Mpi26EventDataPCIeTopologyChangeList_t *)
+		    mpi_reply->EventData);
+		break;
 	case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
 		_scsih_check_ir_config_unhide_events(ioc,
 		    (Mpi2EventDataIrConfigChangeList_t *)
@@ -8903,6 +9362,8 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
 	case MPI2_EVENT_SAS_DISCOVERY:
 	case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
 	case MPI2_EVENT_IR_PHYSICAL_DISK:
+	case MPI2_EVENT_PCIE_ENUMERATION:
+	case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
 		break;
 
 	case MPI2_EVENT_TEMP_THRESHOLD:
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 08/13] mpt3sas: Set NVMe device queue depth as 128
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
                   ` (6 preceding siblings ...)
  2017-07-14 13:22 ` [PATCH v2 07/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware Suganath Prabu S
@ 2017-07-14 13:22 ` Suganath Prabu S
  2017-08-03  6:39   ` Hannes Reinecke
  2017-07-14 13:22 ` [PATCH v2 09/13] mpt3sas: scan and add nvme device after controller reset Suganath Prabu S
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

Sets nvme device queue depth, name and displays device capabilities

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |    2 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   40 ++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 0a8187e..b7855c8 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -115,7 +115,7 @@
 
 #define MPT3SAS_RAID_MAX_SECTORS	8192
 #define MPT3SAS_HOST_PAGE_SIZE_4K	12
-
+#define MPT3SAS_NVME_QUEUE_DEPTH	128
 #define MPT_NAME_LENGTH			32	/* generic length of strings */
 #define MPT_STRING_LENGTH		64
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 1dd9674..c5a131f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2290,6 +2290,7 @@ scsih_slave_configure(struct scsi_device *sdev)
 	struct MPT3SAS_DEVICE *sas_device_priv_data;
 	struct MPT3SAS_TARGET *sas_target_priv_data;
 	struct _sas_device *sas_device;
+	struct _pcie_device *pcie_device;
 	struct _raid_device *raid_device;
 	unsigned long flags;
 	int qdepth;
@@ -2420,6 +2421,45 @@ scsih_slave_configure(struct scsi_device *sdev)
 		}
 	}
 
+	/* PCIe handling */
+	if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+		spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+		pcie_device = __mpt3sas_get_pdev_by_wwid(ioc,
+				sas_device_priv_data->sas_target->sas_address);
+		if (!pcie_device) {
+			spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+			dfailprintk(ioc, pr_warn(MPT3SAS_FMT
+				"failure at %s:%d/%s()!\n", ioc->name, __FILE__,
+				__LINE__, __func__));
+			return 1;
+		}
+
+		/*TODO-right Queue Depth?*/
+		qdepth = MPT3SAS_NVME_QUEUE_DEPTH;
+		ds = "NVMe";
+		/*TODO-Add device name when defined*/
+		sdev_printk(KERN_INFO, sdev,
+			"%s: handle(0x%04x), wwid(0x%016llx), port(%d)\n",
+			ds, handle, (unsigned long long)pcie_device->wwid,
+			pcie_device->port_num);
+		if (pcie_device->enclosure_handle != 0)
+			sdev_printk(KERN_INFO, sdev,
+			"%s: enclosure logical id(0x%016llx), slot(%d)\n",
+			ds,
+			(unsigned long long)pcie_device->enclosure_logical_id,
+			pcie_device->slot);
+		if (pcie_device->connector_name[0] != '\0')
+			sdev_printk(KERN_INFO, sdev,
+				"%s: enclosure level(0x%04x),"
+				"connector name( %s)\n", ds,
+				pcie_device->enclosure_level,
+				pcie_device->connector_name);
+		pcie_device_put(pcie_device);
+		spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+		scsih_change_queue_depth(sdev, qdepth);
+		return 0;
+	}
+
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	sas_device = __mpt3sas_get_sdev_by_addr(ioc,
 	   sas_device_priv_data->sas_target->sas_address);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 09/13] mpt3sas: scan and add nvme device after controller reset
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
                   ` (7 preceding siblings ...)
  2017-07-14 13:22 ` [PATCH v2 08/13] mpt3sas: Set NVMe device queue depth as 128 Suganath Prabu S
@ 2017-07-14 13:22 ` Suganath Prabu S
  2017-08-03  6:40   ` Hannes Reinecke
  2017-07-14 13:22 ` [PATCH v2 10/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives Suganath Prabu S
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

After Controller reset, Scan and add nvme device back to the topology.

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  194 +++++++++++++++++++++++++++++++++-
 1 files changed, 190 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index c5a131f..e3e803c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4869,6 +4869,7 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
 	char *desc_scsi_state = ioc->tmp_string;
 	u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
 	struct _sas_device *sas_device = NULL;
+	struct _pcie_device *pcie_device = NULL;
 	struct scsi_target *starget = scmd->device->sdev_target;
 	struct MPT3SAS_TARGET *priv_target = starget->hostdata;
 	char *device_str = NULL;
@@ -5001,6 +5002,28 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
 	if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
 		pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
 		    device_str, (unsigned long long)priv_target->sas_address);
+	} else if (priv_target->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+		pcie_device = mpt3sas_get_pdev_from_target(ioc, priv_target);
+		if (pcie_device) {
+			pr_info(MPT3SAS_FMT "\twwid(0x%016llx), port(%d)\n",
+			    ioc->name,
+			    (unsigned long long)pcie_device->wwid,
+			    pcie_device->port_num);
+			if (pcie_device->enclosure_handle != 0)
+				pr_info(MPT3SAS_FMT
+				    "\tenclosure logical id(0x%016llx), "
+				    "slot(%d)\n", ioc->name,
+				    (unsigned long long)
+				    pcie_device->enclosure_logical_id,
+				    pcie_device->slot);
+			if (pcie_device->connector_name[0])
+				pr_info(MPT3SAS_FMT
+				    "\tenclosure level(0x%04x),"
+				    "connector name( %s)\n",
+				    ioc->name, pcie_device->enclosure_level,
+				    pcie_device->connector_name);
+			pcie_device_put(pcie_device);
+		}
 	} else {
 		sas_device = mpt3sas_get_sdev_from_target(ioc, priv_target);
 		if (sas_device) {
@@ -5047,11 +5070,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
 		struct sense_info data;
 		_scsih_normalize_sense(scmd->sense_buffer, &data);
 		pr_warn(MPT3SAS_FMT
-			"\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
-			ioc->name, data.skey,
-		    data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
+		  "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
+		  ioc->name, data.skey,
+		  data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
 	}
-
 	if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
 		response_info = le32_to_cpu(mpi_reply->ResponseInfo);
 		response_bytes = (u8 *)&response_info;
@@ -8512,6 +8534,130 @@ _scsih_search_responding_sas_devices(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * _scsih_mark_responding_pcie_device - mark a pcie_device as responding
+ * @ioc: per adapter object
+ * @pcie_device_pg0: PCIe Device page 0
+ *
+ * After host reset, find out whether devices are still responding.
+ * Used in _scsih_remove_unresponding_devices.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_mark_responding_pcie_device(struct MPT3SAS_ADAPTER *ioc,
+	Mpi26PCIeDevicePage0_t *pcie_device_pg0)
+{
+	struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
+	struct scsi_target *starget;
+	struct _pcie_device *pcie_device;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
+		if ((pcie_device->wwid == pcie_device_pg0->WWID) &&
+		    (pcie_device->slot == pcie_device_pg0->Slot)) {
+			pcie_device->responding = 1;
+			starget = pcie_device->starget;
+			if (starget && starget->hostdata) {
+				sas_target_priv_data = starget->hostdata;
+				sas_target_priv_data->tm_busy = 0;
+				sas_target_priv_data->deleted = 0;
+			} else
+				sas_target_priv_data = NULL;
+			if (starget) {
+				starget_printk(KERN_INFO, starget,
+				    "handle(0x%04x), wwid(0x%016llx) ",
+				    pcie_device->handle,
+				    (unsigned long long)pcie_device->wwid);
+				if (pcie_device->enclosure_handle != 0)
+					starget_printk(KERN_INFO, starget,
+					    "enclosure logical id(0x%016llx), "
+					    "slot(%d)\n",
+					    (unsigned long long)
+					    pcie_device->enclosure_logical_id,
+					    pcie_device->slot);
+			}
+
+			if (((le32_to_cpu(pcie_device_pg0->Flags)) &
+			    MPI26_PCIEDEV0_FLAGS_ENCL_LEVEL_VALID) &&
+			    (ioc->hba_mpi_version_belonged != MPI2_VERSION)) {
+				pcie_device->enclosure_level =
+				    pcie_device_pg0->EnclosureLevel;
+				memcpy(&pcie_device->connector_name[0],
+				    &pcie_device_pg0->ConnectorName[0], 4);
+			} else {
+				pcie_device->enclosure_level = 0;
+				pcie_device->connector_name[0] = '\0';
+			}
+
+			if (pcie_device->handle == pcie_device_pg0->DevHandle)
+				goto out;
+			pr_info(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
+			    pcie_device->handle);
+			pcie_device->handle = pcie_device_pg0->DevHandle;
+			if (sas_target_priv_data)
+				sas_target_priv_data->handle =
+				    pcie_device_pg0->DevHandle;
+			goto out;
+		}
+	}
+
+ out:
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+}
+
+/**
+ * _scsih_search_responding_pcie_devices -
+ * @ioc: per adapter object
+ *
+ * After host reset, find out whether devices are still responding.
+ * If not remove.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_search_responding_pcie_devices(struct MPT3SAS_ADAPTER *ioc)
+{
+	Mpi26PCIeDevicePage0_t pcie_device_pg0;
+	Mpi2ConfigReply_t mpi_reply;
+	u16 ioc_status;
+	u16 handle;
+	u32 device_info;
+
+	pr_info(MPT3SAS_FMT "search for end-devices: start\n", ioc->name);
+
+	if (list_empty(&ioc->pcie_device_list))
+		goto out;
+
+	handle = 0xFFFF;
+	while (!(mpt3sas_config_get_pcie_device_pg0(ioc, &mpi_reply,
+		&pcie_device_pg0, MPI26_PCIE_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
+		handle))) {
+		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+		    MPI2_IOCSTATUS_MASK;
+		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+			pr_info(MPT3SAS_FMT "\tbreak from %s: "
+			    "ioc_status(0x%04x), loginfo(0x%08x)\n", ioc->name,
+			    __func__, ioc_status,
+			    le32_to_cpu(mpi_reply.IOCLogInfo));
+			break;
+		}
+		handle = le16_to_cpu(pcie_device_pg0.DevHandle);
+		device_info = le32_to_cpu(pcie_device_pg0.DeviceInfo);
+		if (!(_scsih_is_nvme_device(device_info)))
+			continue;
+		pcie_device_pg0.WWID = le64_to_cpu(pcie_device_pg0.WWID),
+		pcie_device_pg0.Slot = le16_to_cpu(pcie_device_pg0.Slot);
+		pcie_device_pg0.Flags = le32_to_cpu(pcie_device_pg0.Flags);
+		pcie_device_pg0.DevHandle = handle;
+		_scsih_mark_responding_pcie_device(ioc, &pcie_device_pg0);
+	}
+out:
+	pr_info(MPT3SAS_FMT "search for PCIe end-devices: complete\n",
+	    ioc->name);
+}
+
+/**
  * _scsih_mark_responding_raid_device - mark a raid_device as responding
  * @ioc: per adapter object
  * @wwid: world wide identifier for raid volume
@@ -8863,6 +9009,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
 {
 	Mpi2ExpanderPage0_t expander_pg0;
 	Mpi2SasDevicePage0_t sas_device_pg0;
+	Mpi26PCIeDevicePage0_t pcie_device_pg0;
 	Mpi2RaidVolPage1_t volume_pg1;
 	Mpi2RaidVolPage0_t volume_pg0;
 	Mpi2RaidPhysDiskPage0_t pd_pg0;
@@ -8873,6 +9020,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
 	u16 handle, parent_handle;
 	u64 sas_address;
 	struct _sas_device *sas_device;
+	struct _pcie_device *pcie_device;
 	struct _sas_node *expander_device;
 	static struct _raid_device *raid_device;
 	u8 retry_count;
@@ -9098,7 +9246,44 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
 	}
 	pr_info(MPT3SAS_FMT "\tscan devices: end devices complete\n",
 	    ioc->name);
+	pr_info(MPT3SAS_FMT "\tscan devices: pcie end devices start\n",
+	    ioc->name);
 
+	/* pcie devices */
+	handle = 0xFFFF;
+	while (!(mpt3sas_config_get_pcie_device_pg0(ioc, &mpi_reply,
+		&pcie_device_pg0, MPI26_PCIE_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
+		handle))) {
+		ioc_status = le16_to_cpu(mpi_reply.IOCStatus)
+				& MPI2_IOCSTATUS_MASK;
+		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+			pr_info(MPT3SAS_FMT "\tbreak from pcie end device"
+				" scan: ioc_status(0x%04x), loginfo(0x%08x)\n",
+				ioc->name, ioc_status,
+				le32_to_cpu(mpi_reply.IOCLogInfo));
+			break;
+		}
+		handle = le16_to_cpu(pcie_device_pg0.DevHandle);
+		if (!(_scsih_is_nvme_device(
+			le32_to_cpu(pcie_device_pg0.DeviceInfo))))
+			continue;
+		pcie_device = mpt3sas_get_pdev_by_wwid(ioc,
+				le64_to_cpu(pcie_device_pg0.WWID));
+		if (pcie_device) {
+			pcie_device_put(pcie_device);
+			continue;
+		}
+		retry_count = 0;
+		parent_handle = le16_to_cpu(pcie_device_pg0.ParentDevHandle);
+		_scsih_pcie_add_device(ioc, handle);
+
+		pr_info(MPT3SAS_FMT "\tAFTER adding pcie end device: "
+			"handle (0x%04x), wwid(0x%016llx)\n", ioc->name,
+			handle,
+			(unsigned long long) le64_to_cpu(pcie_device_pg0.WWID));
+	}
+	pr_info(MPT3SAS_FMT "\tpcie devices: pcie end devices complete\n",
+		ioc->name);
 	pr_info(MPT3SAS_FMT "scan devices: complete\n", ioc->name);
 }
 /**
@@ -9148,6 +9333,7 @@ mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
 		    !ioc->sas_hba.num_phys)) {
 			_scsih_prep_device_scan(ioc);
 			_scsih_search_responding_sas_devices(ioc);
+			_scsih_search_responding_pcie_devices(ioc);
 			_scsih_search_responding_raid_devices(ioc);
 			_scsih_search_responding_expanders(ioc);
 			_scsih_error_recovery_delete_devices(ioc);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 10/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives.
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
                   ` (8 preceding siblings ...)
  2017-07-14 13:22 ` [PATCH v2 09/13] mpt3sas: scan and add nvme device after controller reset Suganath Prabu S
@ 2017-07-14 13:22 ` Suganath Prabu S
  2017-08-03  6:43   ` Hannes Reinecke
  2017-07-14 13:22 ` [PATCH v2 11/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info Suganath Prabu S
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

Added debug information for NVMe/PCIe drives in target rest path.

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   83 ++++++++++++++++++++++++++++-----
 1 files changed, 70 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index e3e803c..4ac40bf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2893,6 +2893,7 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd)
 	struct scsi_target *starget = scmd->device->sdev_target;
 	struct MPT3SAS_TARGET *priv_target = starget->hostdata;
 	struct _sas_device *sas_device = NULL;
+	struct _pcie_device *pcie_device = NULL;
 	unsigned long flags;
 	char *device_str = NULL;
 
@@ -2909,6 +2910,31 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd)
 			"%s handle(0x%04x), %s wwid(0x%016llx)\n",
 			device_str, priv_target->handle,
 		    device_str, (unsigned long long)priv_target->sas_address);
+
+	} else if (priv_target->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+		spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+		pcie_device = __mpt3sas_get_pdev_from_target(ioc, priv_target);
+		if (pcie_device) {
+			starget_printk(KERN_INFO, starget,
+				"handle(0x%04x), wwid(0x%016llx), port(%d)\n",
+				pcie_device->handle,
+				(unsigned long long)pcie_device->wwid,
+				pcie_device->port_num);
+			if (pcie_device->enclosure_handle != 0)
+				starget_printk(KERN_INFO, starget,
+					"enclosure logical id(0x%016llx), slot(%d)\n",
+					(unsigned long long)
+					pcie_device->enclosure_logical_id,
+					pcie_device->slot);
+			if (pcie_device->connector_name[0] != '\0')
+				starget_printk(KERN_INFO, starget,
+					"enclosure level(0x%04x), connector name( %s)\n",
+					pcie_device->enclosure_level,
+					pcie_device->connector_name);
+			pcie_device_put(pcie_device);
+		}
+		spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
 	} else {
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
 		sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
@@ -3652,6 +3678,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 	Mpi2SCSITaskManagementRequest_t *mpi_request;
 	u16 smid;
 	struct _sas_device *sas_device = NULL;
+	struct _pcie_device *pcie_device = NULL;
 	struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
 	u64 sas_address = 0;
 	unsigned long flags;
@@ -3694,24 +3721,52 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 		sas_address = sas_device->sas_address;
 	}
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
+	if (!sas_device) {
+		spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+		pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+		if (pcie_device && pcie_device->starget &&
+			pcie_device->starget->hostdata) {
+			sas_target_priv_data = pcie_device->starget->hostdata;
+			sas_target_priv_data->deleted = 1;
+			sas_address = pcie_device->wwid;
+		}
+		spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+	}
 	if (sas_target_priv_data) {
 		dewtprintk(ioc, pr_info(MPT3SAS_FMT
 			"setting delete flag: handle(0x%04x), sas_addr(0x%016llx)\n",
 			ioc->name, handle,
 		    (unsigned long long)sas_address));
-		if (sas_device->enclosure_handle != 0)
-			dewtprintk(ioc, pr_info(MPT3SAS_FMT
-			 "setting delete flag:enclosure logical id(0x%016llx),"
-			 " slot(%d)\n", ioc->name, (unsigned long long)
-			  sas_device->enclosure_logical_id,
-			  sas_device->slot));
-		if (sas_device->connector_name[0] != '\0')
-			dewtprintk(ioc, pr_info(MPT3SAS_FMT
-			 "setting delete flag: enclosure level(0x%04x),"
-			 " connector name( %s)\n", ioc->name,
-			  sas_device->enclosure_level,
-			  sas_device->connector_name));
+		if (sas_device) {
+			if (sas_device->enclosure_handle != 0)
+				dewtprintk(ioc, pr_info(MPT3SAS_FMT
+				    "setting delete flag:enclosure logical "
+				    "id(0x%016llx), slot(%d)\n", ioc->name,
+				    (unsigned long long)
+				    sas_device->enclosure_logical_id,
+				    sas_device->slot));
+			if (sas_device->connector_name[0] != '\0')
+				dewtprintk(ioc, pr_info(MPT3SAS_FMT
+				    "setting delete flag: enclosure "
+				    "level(0x%04x), connector name( %s)\n",
+				    ioc->name, sas_device->enclosure_level,
+				    sas_device->connector_name));
+		} else if (pcie_device) {
+			if (pcie_device->enclosure_handle != 0)
+				dewtprintk(ioc, pr_info(MPT3SAS_FMT
+				    "setting delete flag: logical "
+				    "id(0x%016llx), slot(%d)\n", ioc->name,
+				    (unsigned long long)
+				    pcie_device->enclosure_logical_id,
+				    pcie_device->slot));
+			if (pcie_device->connector_name[0] != '\0')
+				dewtprintk(ioc, pr_info(MPT3SAS_FMT
+				    "setting delete flag:, enclosure "
+				    "level(0x%04x), "
+				    "connector name( %s)\n", ioc->name,
+				    pcie_device->enclosure_level,
+				    pcie_device->connector_name));
+		}
 		_scsih_ublock_io_device(ioc, sas_address);
 		sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE;
 	}
@@ -3746,6 +3801,8 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
 out:
 	if (sas_device)
 		sas_device_put(sas_device);
+	if (pcie_device)
+		pcie_device_put(pcie_device);
 }
 
 /**
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 11/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
                   ` (9 preceding siblings ...)
  2017-07-14 13:22 ` [PATCH v2 10/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives Suganath Prabu S
@ 2017-07-14 13:22 ` Suganath Prabu S
  2017-08-03  6:44   ` Hannes Reinecke
  2017-07-14 13:22 ` [PATCH v2 12/13] mpt3sas: Fix nvme drives checking for tlr Suganath Prabu S
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

* Added debug prints for pcie devices in ioctl debug path. Which
will be helpful for debugging.
* Added PCIe device support for ioctl BTDHMAPPING ioctl.

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c |   88 +++++++++++++++++++++++------------
 1 files changed, 58 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 6362d60..99147ad 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -79,32 +79,6 @@ enum block_state {
 };
 
 /**
- * _ctl_sas_device_find_by_handle - sas device search
- * @ioc: per adapter object
- * @handle: sas device handle (assigned by firmware)
- * Context: Calling function should acquire ioc->sas_device_lock
- *
- * This searches for sas_device based on sas_address, then return sas_device
- * object.
- */
-static struct _sas_device *
-_ctl_sas_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
-{
-	struct _sas_device *sas_device, *r;
-
-	r = NULL;
-	list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
-		if (sas_device->handle != handle)
-			continue;
-		r = sas_device;
-		goto out;
-	}
-
- out:
-	return r;
-}
-
-/**
  * _ctl_display_some_debug - debug routine
  * @ioc: per adapter object
  * @smid: system request message index
@@ -229,10 +203,9 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
 		Mpi2SCSIIOReply_t *scsi_reply =
 		    (Mpi2SCSIIOReply_t *)mpi_reply;
 		struct _sas_device *sas_device = NULL;
-		unsigned long flags;
+		struct _pcie_device *pcie_device = NULL;
 
-		spin_lock_irqsave(&ioc->sas_device_lock, flags);
-		sas_device = _ctl_sas_device_find_by_handle(ioc,
+		sas_device = mpt3sas_get_sdev_by_handle(ioc,
 		    le16_to_cpu(scsi_reply->DevHandle));
 		if (sas_device) {
 			pr_warn(MPT3SAS_FMT "\tsas_address(0x%016llx), phy(%d)\n",
@@ -242,8 +215,25 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
 			    "\tenclosure_logical_id(0x%016llx), slot(%d)\n",
 			    ioc->name, (unsigned long long)
 			    sas_device->enclosure_logical_id, sas_device->slot);
+			sas_device_put(sas_device);
+		}
+		if (!sas_device) {
+			pcie_device = mpt3sas_get_pdev_by_handle(ioc,
+				le16_to_cpu(scsi_reply->DevHandle));
+			if (pcie_device) {
+				pr_warn(MPT3SAS_FMT
+				    "\tWWID(0x%016llx), port(%d)\n", ioc->name,
+				    (unsigned long long)pcie_device->wwid,
+				    pcie_device->port_num);
+				if (pcie_device->enclosure_handle != 0)
+					pr_warn(MPT3SAS_FMT
+					    "\tenclosure_logical_id(0x%016llx), slot(%d)\n",
+					    ioc->name, (unsigned long long)
+					    pcie_device->enclosure_logical_id,
+					    pcie_device->slot);
+				pcie_device_put(pcie_device);
+			}
 		}
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 		if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)
 			pr_info(MPT3SAS_FMT
 			    "\tscsi_state(0x%02x), scsi_status"
@@ -1353,6 +1343,42 @@ _ctl_btdh_search_sas_device(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _ctl_btdh_search_pcie_device - searching for pcie device
+ * @ioc: per adapter object
+ * @btdh: btdh ioctl payload
+ */
+static int
+_ctl_btdh_search_pcie_device(struct MPT3SAS_ADAPTER *ioc,
+	struct mpt3_ioctl_btdh_mapping *btdh)
+{
+	struct _pcie_device *pcie_device;
+	unsigned long flags;
+	int rc = 0;
+
+	if (list_empty(&ioc->pcie_device_list))
+		return rc;
+
+	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+	list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
+		if (btdh->bus == 0xFFFFFFFF && btdh->id == 0xFFFFFFFF &&
+			   btdh->handle == pcie_device->handle) {
+			btdh->bus = pcie_device->channel;
+			btdh->id = pcie_device->id;
+			rc = 1;
+			goto out;
+		} else if (btdh->bus == pcie_device->channel && btdh->id ==
+			   pcie_device->id && btdh->handle == 0xFFFF) {
+			btdh->handle = pcie_device->handle;
+			rc = 1;
+			goto out;
+		}
+	}
+ out:
+	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+	return rc;
+}
+
+/**
  * _ctl_btdh_search_raid_device - searching for raid device
  * @ioc: per adapter object
  * @btdh: btdh ioctl payload
@@ -1410,6 +1436,8 @@ _ctl_btdh_mapping(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
 
 	rc = _ctl_btdh_search_sas_device(ioc, &karg);
 	if (!rc)
+		rc = _ctl_btdh_search_pcie_device(ioc, &karg);
+	if (!rc)
 		_ctl_btdh_search_raid_device(ioc, &karg);
 
 	if (copy_to_user(arg, &karg, sizeof(karg))) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 12/13] mpt3sas: Fix nvme drives checking for tlr.
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
                   ` (10 preceding siblings ...)
  2017-07-14 13:22 ` [PATCH v2 11/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info Suganath Prabu S
@ 2017-07-14 13:22 ` Suganath Prabu S
  2017-08-03  6:44   ` Hannes Reinecke
  2017-07-14 13:22 ` [PATCH v2 13/13] mpt3sas: Update mpt3sas driver version Suganath Prabu S
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

Check for NVMe drives before enabling or checking tlr.

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   22 ++++++++++++++++------
 1 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 4ac40bf..c34001b 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2014,6 +2014,14 @@ scsih_is_raid(struct device *dev)
 	return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
 }
 
+static int
+scsih_is_nvme(struct device *dev)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+
+	return (sdev->channel == PCIE_CHANNEL) ? 1 : 0;
+}
+
 /**
  * scsih_get_resync - get raid volume resync percent complete
  * @dev the device struct object
@@ -4811,8 +4819,9 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
 	/* Make sure Device is not raid volume.
 	 * We do not expose raid functionality to upper layer for warpdrive.
 	 */
-	if (!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev)
-	    && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
+	if (((!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev))
+		&& !scsih_is_nvme(&scmd->device->sdev_gendev))
+		&& sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
 		mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
 
 	smid = mpt3sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
@@ -4857,8 +4866,8 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
 
 	raid_device = sas_target_priv_data->raid_device;
 	if (raid_device && raid_device->direct_io_enabled)
-		mpt3sas_setup_direct_io(ioc, scmd, raid_device, mpi_request,
-		    smid);
+		mpt3sas_setup_direct_io(ioc, scmd,
+			raid_device, mpi_request, smid);
 
 	if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) {
 		if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) {
@@ -5406,9 +5415,10 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
 		    le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
 	if (!sas_device_priv_data->tlr_snoop_check) {
 		sas_device_priv_data->tlr_snoop_check++;
-		if (!ioc->is_warpdrive &&
+		if ((!ioc->is_warpdrive &&
 		    !scsih_is_raid(&scmd->device->sdev_gendev) &&
-		    sas_is_tlr_enabled(scmd->device) &&
+		    !scsih_is_nvme(&scmd->device->sdev_gendev))
+		    && sas_is_tlr_enabled(scmd->device) &&
 		    response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
 			sas_disable_tlr(scmd->device);
 			sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 13/13] mpt3sas: Update mpt3sas driver version.
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
                   ` (11 preceding siblings ...)
  2017-07-14 13:22 ` [PATCH v2 12/13] mpt3sas: Fix nvme drives checking for tlr Suganath Prabu S
@ 2017-07-14 13:22 ` Suganath Prabu S
  2017-08-03  6:45   ` Hannes Reinecke
  2017-07-25  5:20 ` [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu Subramani
  2017-08-02  8:14 ` Hannes Reinecke
  14 siblings, 1 reply; 44+ messages in thread
From: Suganath Prabu S @ 2017-07-14 13:22 UTC (permalink / raw)
  To: jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, suganath-prabu.subramani, chaitra.basappa,
	sreekanth.reddy, linux-nvme

Updated mpt3sas driver version to 15.101.00.00

Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index b7855c8..b705199 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -74,9 +74,9 @@
 #define MPT3SAS_DRIVER_NAME		"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies <MPT-FusionLinux.pdl@avagotech.com>"
 #define MPT3SAS_DESCRIPTION	"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION		"15.100.00.00"
+#define MPT3SAS_DRIVER_VERSION		"15.101.00.00"
 #define MPT3SAS_MAJOR_VERSION		15
-#define MPT3SAS_MINOR_VERSION		100
+#define MPT3SAS_MINOR_VERSION		101
 #define MPT3SAS_BUILD_VERSION		0
 #define MPT3SAS_RELEASE_VERSION	00
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
                   ` (12 preceding siblings ...)
  2017-07-14 13:22 ` [PATCH v2 13/13] mpt3sas: Update mpt3sas driver version Suganath Prabu S
@ 2017-07-25  5:20 ` Suganath Prabu Subramani
  2017-08-02  8:14 ` Hannes Reinecke
  14 siblings, 0 replies; 44+ messages in thread
From: Suganath Prabu Subramani @ 2017-07-25  5:20 UTC (permalink / raw)
  To: jejb, Christoph Hellwig, linux-nvme
  Cc: Martin K. Petersen, linux-scsi, Sathya Prakash, Kashyap Desai,
	linux-kernel, Suganath Prabu S, Chaitra Basappa, Sreekanth Reddy

Is there any update on these patches ?

Thanks,
Suganath Prabu S

On Fri, Jul 14, 2017 at 6:52 PM, Suganath Prabu S
<suganath-prabu.subramani@broadcom.com> wrote:
> Ventura Series controller are Tri-mode. The controller and
> firmware are capable of supporting NVMe devices and
> PCIe switches to be connected with the controller. This
> patch set adds driver level support for NVMe devices and
> PCIe switches.
>
> Suganath Prabu S (13):
>   mpt3sas: Update MPI Header
>   mpt3sas: Add nvme device support in slave alloc, target alloc and
>     probe
>   mpt3sas: SGL to PRP Translation for I/Os to NVMe  devices
>   mpt3sas: Added support for nvme encapsulated request message.
>   mpt3sas: API 's to support NVMe drive addition to SML
>   mpt3sas: API's to remove nvme drive from sml
>   mpt3sas: Handle NVMe PCIe device related events generated
>        from firmware.
>   mpt3sas: Set NVMe device queue depth as 128
>   mpt3sas: scan and add nvme device after controller reset
>   mpt3as: Add-Task-management-debug-info-for-NVMe-drives.
>   mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log
>     info
>   mpt3sas: Fix nvme drives checking for tlr.
>   mpt3sas: Update mpt3sas driver version.
>
>  drivers/scsi/mpt3sas/mpi/mpi2.h          |   43 +-
>  drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h     |  647 ++++++++++-
>  drivers/scsi/mpt3sas/mpi/mpi2_init.h     |   11 +-
>  drivers/scsi/mpt3sas/mpi/mpi2_ioc.h      |  331 ++++++-
>  drivers/scsi/mpt3sas/mpi/mpi2_pci.h      |  142 +++
>  drivers/scsi/mpt3sas/mpi/mpi2_tool.h     |   14 +-
>  drivers/scsi/mpt3sas/mpt3sas_base.c      |  710 +++++++++++-
>  drivers/scsi/mpt3sas/mpt3sas_base.h      |  171 +++-
>  drivers/scsi/mpt3sas/mpt3sas_config.c    |  100 ++
>  drivers/scsi/mpt3sas/mpt3sas_ctl.c       |  158 ++-
>  drivers/scsi/mpt3sas/mpt3sas_scsih.c     | 1874 ++++++++++++++++++++++++++++--
>  drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |    2 +-
>  12 files changed, 4063 insertions(+), 140 deletions(-)
>  create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h
>
> Thanks,
> Suganath Prabu S

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 03/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe  devices
  2017-07-14 13:22 ` [PATCH v2 03/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe devices Suganath Prabu S
@ 2017-07-27 13:26   ` Martin K. Petersen
  0 siblings, 0 replies; 44+ messages in thread
From: Martin K. Petersen @ 2017-07-27 13:26 UTC (permalink / raw)
  To: Suganath Prabu S
  Cc: jejb, hch, martin.petersen, linux-scsi, Sathya.Prakash,
	kashyap.desai, linux-kernel, chaitra.basappa, sreekanth.reddy,
	linux-nvme


Suganath,

> * Added support for translating the SGLs associated with incoming
> commands either to IEE SGL or NVMe PRPs for NVMe devices.

This all seems very convoluted. You should rely on the block layer
infrastructure instead of doing all this slicing and dicing by hand.

If the attached device is an NVMe drive, call blk_queue_virt_boundary()
and you will only receive requests that are suitable for a device with
PRP-style scatterlist constraints.

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
  2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
                   ` (13 preceding siblings ...)
  2017-07-25  5:20 ` [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu Subramani
@ 2017-08-02  8:14 ` Hannes Reinecke
  2017-08-03  6:48   ` Hannes Reinecke
  2017-08-05 13:53   ` Christoph Hellwig
  14 siblings, 2 replies; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-02  8:14 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
> Ventura Series controller are Tri-mode. The controller and
> firmware are capable of supporting NVMe devices and
> PCIe switches to be connected with the controller. This
> patch set adds driver level support for NVMe devices and
> PCIe switches.
> 
> Suganath Prabu S (13):
>   mpt3sas: Update MPI Header
>   mpt3sas: Add nvme device support in slave alloc, target alloc and
>     probe
>   mpt3sas: SGL to PRP Translation for I/Os to NVMe  devices
>   mpt3sas: Added support for nvme encapsulated request message.
>   mpt3sas: API 's to support NVMe drive addition to SML
>   mpt3sas: API's to remove nvme drive from sml
>   mpt3sas: Handle NVMe PCIe device related events generated            
>        from firmware.
>   mpt3sas: Set NVMe device queue depth as 128
>   mpt3sas: scan and add nvme device after controller reset
>   mpt3as: Add-Task-management-debug-info-for-NVMe-drives.
>   mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log
>     info
>   mpt3sas: Fix nvme drives checking for tlr.
>   mpt3sas: Update mpt3sas driver version.
> 
>  drivers/scsi/mpt3sas/mpi/mpi2.h          |   43 +-
>  drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h     |  647 ++++++++++-
>  drivers/scsi/mpt3sas/mpi/mpi2_init.h     |   11 +-
>  drivers/scsi/mpt3sas/mpi/mpi2_ioc.h      |  331 ++++++-
>  drivers/scsi/mpt3sas/mpi/mpi2_pci.h      |  142 +++
>  drivers/scsi/mpt3sas/mpi/mpi2_tool.h     |   14 +-
>  drivers/scsi/mpt3sas/mpt3sas_base.c      |  710 +++++++++++-
>  drivers/scsi/mpt3sas/mpt3sas_base.h      |  171 +++-
>  drivers/scsi/mpt3sas/mpt3sas_config.c    |  100 ++
>  drivers/scsi/mpt3sas/mpt3sas_ctl.c       |  158 ++-
>  drivers/scsi/mpt3sas/mpt3sas_scsih.c     | 1874 ++++++++++++++++++++++++++++--
>  drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |    2 +-
>  12 files changed, 4063 insertions(+), 140 deletions(-)
>  create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h
> 
I'm not happy with this approach.
NVMe devices should _not_ appear as SCSI devices; this will just confuse
matters _and_ will be incompatible with 'normal' NVMe devices.

Rather I would like to see the driver to hook into the existing NVMe
framework (which essentially means to treat the mpt3sas as a weird
NVMe-over-Fabrics HBA), and expose the NVMe devices like any other NVMe HBA.

I'm sorry that you'll have to redo your patchset (again), but this is
the only way I see how this patchset can be brought forward.

I'd be happy to discuss implementation details with you.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 01/13] mpt3sas: Update MPI Header
  2017-07-14 13:22 ` [PATCH v2 01/13] mpt3sas: Update MPI Header Suganath Prabu S
@ 2017-08-03  6:24   ` Hannes Reinecke
  2017-08-03  7:55     ` Johannes Thumshirn
  0 siblings, 1 reply; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-03  6:24 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
> Update MPI Files for NVMe support
> 
> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
> ---
>  drivers/scsi/mpt3sas/mpi/mpi2.h      |   43 +++-
>  drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  647 +++++++++++++++++++++++++++++++++-
>  drivers/scsi/mpt3sas/mpi/mpi2_init.h |   11 +-
>  drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |  331 +++++++++++++++++-
>  drivers/scsi/mpt3sas/mpi/mpi2_pci.h  |  142 ++++++++
>  drivers/scsi/mpt3sas/mpi/mpi2_tool.h |   14 +-
>  6 files changed, 1177 insertions(+), 11 deletions(-)
>  create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h
> 
> diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h
> index a9a659f..bc59058 100644
> --- a/drivers/scsi/mpt3sas/mpi/mpi2.h
> +++ b/drivers/scsi/mpt3sas/mpi/mpi2.h
> @@ -8,7 +8,7 @@
>   *                 scatter/gather formats.
>   * Creation Date:  June 21, 2006
>   *
> - * mpi2.h Version:  02.00.42
> + * mpi2.h Version:  02.00.48
>   *
>   * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
>   *       prefix are for use only on MPI v2.5 products, and must not be used
> @@ -103,6 +103,16 @@
>   * 08-25-15  02.00.40  Bumped MPI2_HEADER_VERSION_UNIT.
>   * 12-15-15  02.00.41  Bumped MPI_HEADER_VERSION_UNIT
>   * 01-01-16  02.00.42  Bumped MPI_HEADER_VERSION_UNIT
> + * 04-05-16  02.00.43  Modified  MPI26_DIAG_BOOT_DEVICE_SELECT defines
> + *                     to be unique within first 32 characters.
> + *                     Removed AHCI support.
> + *                     Removed SOP support.
> + *                     Bumped MPI2_HEADER_VERSION_UNIT.
> + * 04-10-16  02.00.44  Bumped MPI2_HEADER_VERSION_UNIT.
> + * 07-06-16  02.00.45  Bumped MPI2_HEADER_VERSION_UNIT.
> + * 09-02-16  02.00.46  Bumped MPI2_HEADER_VERSION_UNIT.
> + * 11-23-16  02.00.47  Bumped MPI2_HEADER_VERSION_UNIT.
> + * 02-03-17  02.00.48  Bumped MPI2_HEADER_VERSION_UNIT.
>   * --------------------------------------------------------------------------
>   */
>  
> @@ -142,7 +152,7 @@
>  #define MPI2_VERSION_02_06		    (0x0206)
>  
>  /*Unit and Dev versioning for this MPI header set */
> -#define MPI2_HEADER_VERSION_UNIT            (0x2A)
> +#define MPI2_HEADER_VERSION_UNIT            (0x30)
>  #define MPI2_HEADER_VERSION_DEV             (0x00)
>  #define MPI2_HEADER_VERSION_UNIT_MASK       (0xFF00)
>  #define MPI2_HEADER_VERSION_UNIT_SHIFT      (8)
> @@ -249,6 +259,12 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS {
>  #define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT    (0x00000000)
>  #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW       (0x00000800)
>  
> +/* Defines for V7A/V7R HostDiagnostic Register */
> +#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH      (0x00000000)
> +#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW       (0x00000800)
> +#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH      (0x00001000)
> +#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW       (0x00001800)
> +
>  #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG           (0x00000400)
>  #define MPI2_DIAG_FORCE_HCB_ON_RESET            (0x00000200)
>  #define MPI2_DIAG_HCB_MODE                      (0x00000100)
> @@ -367,6 +383,7 @@ typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR {
>  #define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE            (0x08)
>  #define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR        (0x0A)
>  #define MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO      (0x0C)
> +#define MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED      (0x10)
>  
>  #define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER         (0x01)
>  
> @@ -425,6 +442,13 @@ typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
>  	Mpi25FastPathSCSIIORequestDescriptor_t,
>  	*pMpi25FastPathSCSIIORequestDescriptor_t;
>  
> +/*PCIe Encapsulated Request Descriptor */
> +typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
> +	MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
> +	*PTR_MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
> +	Mpi26PCIeEncapsulatedRequestDescriptor_t,
> +	*pMpi26PCIeEncapsulatedRequestDescriptor_t;
> +
>  /*union of Request Descriptors */
>  typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
>  	MPI2_DEFAULT_REQUEST_DESCRIPTOR Default;
> @@ -433,6 +457,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
>  	MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget;
>  	MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator;
>  	MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR FastPathSCSIIO;
> +	MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR PCIeEncapsulated;
>  	U64 Words;
>  } MPI2_REQUEST_DESCRIPTOR_UNION,
>  	*PTR_MPI2_REQUEST_DESCRIPTOR_UNION,
> @@ -450,6 +475,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
>   *      Atomic SCSI Target Request Descriptor
>   *      Atomic RAID Accelerator Request Descriptor
>   *      Atomic Fast Path SCSI IO Request Descriptor
> + *      Atomic PCIe Encapsulated Request Descriptor
>   */
>  
>  /*Atomic Request Descriptor */
> @@ -487,6 +513,7 @@ typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR {
>  #define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER       (0x03)
>  #define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS    (0x05)
>  #define MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS  (0x06)
> +#define MPI26_RPY_DESCRIPT_FLAGS_PCIE_ENCAPSULATED_SUCCESS  (0x08)
>  #define MPI2_RPY_DESCRIPT_FLAGS_UNUSED                      (0x0F)
>  
>  /*values for marking a reply descriptor as unused */
> @@ -565,6 +592,13 @@ typedef MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR
>  	Mpi25FastPathSCSIIOSuccessReplyDescriptor_t,
>  	*pMpi25FastPathSCSIIOSuccessReplyDescriptor_t;
>  
> +/*PCIe Encapsulated Success Reply Descriptor */
> +typedef MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR
> +	MPI26_PCIE_ENCAPSULATED_SUCCESS_REPLY_DESCRIPTOR,
> +	*PTR_MPI26_PCIE_ENCAPSULATED_SUCCESS_REPLY_DESCRIPTOR,
> +	Mpi26PCIeEncapsulatedSuccessReplyDescriptor_t,
> +	*pMpi26PCIeEncapsulatedSuccessReplyDescriptor_t;
> +
>  /*union of Reply Descriptors */
>  typedef union _MPI2_REPLY_DESCRIPTORS_UNION {
>  	MPI2_DEFAULT_REPLY_DESCRIPTOR Default;
> @@ -574,6 +608,8 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION {
>  	MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer;
>  	MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR RAIDAcceleratorSuccess;
>  	MPI25_FP_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR FastPathSCSIIOSuccess;
> +	MPI26_PCIE_ENCAPSULATED_SUCCESS_REPLY_DESCRIPTOR
> +						PCIeEncapsulatedSuccess;
>  	U64 Words;
>  } MPI2_REPLY_DESCRIPTORS_UNION,
>  	*PTR_MPI2_REPLY_DESCRIPTORS_UNION,
> @@ -616,6 +652,7 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION {
>  #define MPI2_FUNCTION_HOST_BASED_DISCOVERY_ACTION   (0x2F)
>  #define MPI2_FUNCTION_PWR_MGMT_CONTROL              (0x30)
>  #define MPI2_FUNCTION_SEND_HOST_MESSAGE             (0x31)
> +#define MPI2_FUNCTION_NVME_ENCAPSULATED             (0x33)
>  #define MPI2_FUNCTION_MIN_PRODUCT_SPECIFIC          (0xF0)
>  #define MPI2_FUNCTION_MAX_PRODUCT_SPECIFIC          (0xFF)
>  
> @@ -1162,6 +1199,8 @@ typedef union _MPI25_SGE_IO_UNION {
>  
>  #define MPI26_IEEE_SGE_FLAGS_NSF_MASK           (0x1C)
>  #define MPI26_IEEE_SGE_FLAGS_NSF_MPI_IEEE       (0x00)
> +#define MPI26_IEEE_SGE_FLAGS_NSF_NVME_PRP       (0x08)
> +#define MPI26_IEEE_SGE_FLAGS_NSF_NVME_SGL       (0x10)
>  
>  /*Data Location Address Space */
>  
> diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
> index fa61baf..3bb6833 100644
> --- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
> +++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
> @@ -6,7 +6,7 @@
>   *         Title:  MPI Configuration messages and pages
>   * Creation Date:  November 10, 2006
>   *
> - *   mpi2_cnfg.h Version:  02.00.35
> + *   mpi2_cnfg.h Version:  02.00.40
>   *
>   * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
>   *       prefix are for use only on MPI v2.5 products, and must not be used
> @@ -189,6 +189,35 @@
>   *                     MPI2_CONFIG_PAGE_BIOS_1.
>   * 08-25-15  02.00.34  Bumped Header Version.
>   * 12-18-15  02.00.35  Added SATADeviceWaitTime to SAS IO Unit Page 4.
> + * 01-21-16  02.00.36  Added/modified MPI2_MFGPAGE_DEVID_SAS defines.
> + *                     Added Link field to PCIe Link Pages
> + *                     Added EnclosureLevel and ConnectorName to PCIe
> + *                     Device Page 0.
> + *                     Added define for PCIE IoUnit page 1 max rate shift.
> + *                     Added comment for reserved ExtPageTypes.
> + *                     Added SAS 4 22.5 gbs speed support.
> + *                     Added PCIe 4 16.0 GT/sec speec support.
> + *                     Removed AHCI support.
> + *                     Removed SOP support.
> + *                     Added NegotiatedLinkRate and NegotiatedPortWidth to
> + *                     PCIe device page 0.
> + * 04-10-16  02.00.37  Fixed MPI2_MFGPAGE_DEVID_SAS3616/3708 defines
> + * 07-01-16  02.00.38  Added Manufacturing page 7 Connector types.
> + *                     Changed declaration of ConnectorName in PCIe DevicePage0
> + *                     to match SAS DevicePage 0.
> + *                     Added SATADeviceWaitTime to IO Unit Page 11.
> + *                     Added MPI26_MFGPAGE_DEVID_SAS4008
> + *                     Added x16 PCIe width to IO Unit Page 7
> + *                     Added LINKFLAGS to control SRIS in PCIe IO Unit page 1
> + *                     phy data.
> + *                     Added InitStatus to PCIe IO Unit Page 1 header.
> + * 09-01-16  02.00.39  Added MPI26_CONFIG_PAGE_ENCLOSURE_0 and related defines.
> + *                     Added MPI26_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE and
> + *                     MPI26_ENCLOS_PGAD_FORM_HANDLE page address formats.
> + * 02-02-17  02.00.40  Added MPI2_MANPAGE7_SLOT_UNKNOWN.
> + *                     Added ChassisSlot field to SAS Enclosure Page 0.
> + *                     Added ChassisSlot Valid bit (bit 5) to the Flags field
> + *                     in SAS Enclosure Page 0.
>   * --------------------------------------------------------------------------
>   */
>  
> @@ -272,6 +301,10 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION {
>  #define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT            (0x18)
>  #define MPI2_CONFIG_EXTPAGETYPE_ETHERNET            (0x19)
>  #define MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING   (0x1A)
> +#define MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT        (0x1B)
> +#define MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH         (0x1C)
> +#define MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE         (0x1D)
> +#define MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK           (0x1E)
>  
>  
>  /*****************************************************************************
> @@ -339,6 +372,12 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION {
>  
>  #define MPI2_SAS_ENCLOS_PGAD_HANDLE_MASK            (0x0000FFFF)
>  
> +/*Enclosure PageAddress format */
> +#define MPI26_ENCLOS_PGAD_FORM_MASK                 (0xF0000000)
> +#define MPI26_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE      (0x00000000)
> +#define MPI26_ENCLOS_PGAD_FORM_HANDLE               (0x10000000)
> +
> +#define MPI26_ENCLOS_PGAD_HANDLE_MASK               (0x0000FFFF)
>  
>  /*RAID Configuration PageAddress format */
>  #define MPI2_RAID_PGAD_FORM_MASK                    (0xF0000000)
> @@ -365,6 +404,33 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION {
>  #define MPI2_ETHERNET_PGAD_IF_NUMBER_MASK           (0x000000FF)
>  
>  
> +/*PCIe Switch PageAddress format */
> +#define MPI26_PCIE_SWITCH_PGAD_FORM_MASK            (0xF0000000)
> +#define MPI26_PCIE_SWITCH_PGAD_FORM_GET_NEXT_HNDL   (0x00000000)
> +#define MPI26_PCIE_SWITCH_PGAD_FORM_HNDL_PORTNUM    (0x10000000)
> +#define MPI26_PCIE_SWITCH_EXPAND_PGAD_FORM_HNDL     (0x20000000)
> +
> +#define MPI26_PCIE_SWITCH_PGAD_HANDLE_MASK          (0x0000FFFF)
> +#define MPI26_PCIE_SWITCH_PGAD_PORTNUM_MASK         (0x00FF0000)
> +#define MPI26_PCIE_SWITCH_PGAD_PORTNUM_SHIFT        (16)
> +
> +
> +/*PCIe Device PageAddress format */
> +#define MPI26_PCIE_DEVICE_PGAD_FORM_MASK            (0xF0000000)
> +#define MPI26_PCIE_DEVICE_PGAD_FORM_GET_NEXT_HANDLE (0x00000000)
> +#define MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE          (0x20000000)
> +
> +#define MPI26_PCIE_DEVICE_PGAD_HANDLE_MASK          (0x0000FFFF)
> +
> +/*PCIe Link PageAddress format */
> +#define MPI26_PCIE_LINK_PGAD_FORM_MASK            (0xF0000000)
> +#define MPI26_PCIE_LINK_PGAD_FORM_GET_NEXT_LINK   (0x00000000)
> +#define MPI26_PCIE_LINK_PGAD_FORM_LINK_NUM        (0x10000000)
> +
> +#define MPI26_PCIE_DEVICE_PGAD_LINKNUM_MASK       (0x000000FF)
> +
> +
> +
>  /****************************************************************************
>  *  Configuration messages
>  ****************************************************************************/
> @@ -484,6 +550,12 @@ typedef struct _MPI2_CONFIG_REPLY {
>  #define MPI26_MFGPAGE_DEVID_SAS3508                 (0x00AD)
>  #define MPI26_MFGPAGE_DEVID_SAS3508_1               (0x00AE)
>  #define MPI26_MFGPAGE_DEVID_SAS3408                 (0x00AF)
> +#define MPI26_MFGPAGE_DEVID_SAS3716                 (0x00D0)
> +#define MPI26_MFGPAGE_DEVID_SAS3616                 (0x00D1)
> +#define MPI26_MFGPAGE_DEVID_SAS3708                 (0x00D2)
> +
> +#define MPI26_MFGPAGE_DEVID_SAS4008                 (0x00A1)
> +
>  
>  /*Manufacturing Page 0 */
>  
> @@ -726,6 +798,12 @@ typedef struct _MPI2_MANPAGE7_CONNECTOR_INFO {
>  #define MPI2_MANPAGE7_PINOUT_SFF_8644_8X                (0x0B)
>  #define MPI2_MANPAGE7_PINOUT_SFF_8644_16X               (0x0C)
>  #define MPI2_MANPAGE7_PINOUT_SFF_8436                   (0x0D)
> +#define MPI2_MANPAGE7_PINOUT_SFF_8088_A                 (0x0E)
> +#define MPI2_MANPAGE7_PINOUT_SFF_8643_16i               (0x0F)
> +#define MPI2_MANPAGE7_PINOUT_SFF_8654_4i                (0x10)
> +#define MPI2_MANPAGE7_PINOUT_SFF_8654_8i                (0x11)
> +#define MPI2_MANPAGE7_PINOUT_SFF_8611_4i                (0x12)
> +#define MPI2_MANPAGE7_PINOUT_SFF_8611_8i                (0x13)
>  
>  /*defines for the Location field */
>  #define MPI2_MANPAGE7_LOCATION_UNKNOWN                  (0x01)
> @@ -736,6 +814,9 @@ typedef struct _MPI2_MANPAGE7_CONNECTOR_INFO {
>  #define MPI2_MANPAGE7_LOCATION_NOT_PRESENT              (0x20)
>  #define MPI2_MANPAGE7_LOCATION_NOT_CONNECTED            (0x80)
>  
> +/*defines for the Slot field */
> +#define MPI2_MANPAGE7_SLOT_UNKNOWN                      (0xFFFF)
> +
>  /*
>   *Host code (drivers, BIOS, utilities, etc.) should leave this define set to
>   *one and check the value returned for NumPhys at runtime.
> @@ -999,11 +1080,13 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
>  #define MPI2_IOUNITPAGE7_PCIE_WIDTH_X2              (0x02)
>  #define MPI2_IOUNITPAGE7_PCIE_WIDTH_X4              (0x04)
>  #define MPI2_IOUNITPAGE7_PCIE_WIDTH_X8              (0x08)
> +#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X16             (0x10)
>  
>  /*defines for IO Unit Page 7 PCIeSpeed field */
>  #define MPI2_IOUNITPAGE7_PCIE_SPEED_2_5_GBPS        (0x00)
>  #define MPI2_IOUNITPAGE7_PCIE_SPEED_5_0_GBPS        (0x01)
>  #define MPI2_IOUNITPAGE7_PCIE_SPEED_8_0_GBPS        (0x02)
> +#define MPI2_IOUNITPAGE7_PCIE_SPEED_16_0_GBPS       (0x03)
>  
>  /*defines for IO Unit Page 7 ProcessorState field */
>  #define MPI2_IOUNITPAGE7_PSTATE_MASK_SECOND         (0x0000000F)
> @@ -1970,6 +2053,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 {
>  #define MPI2_SAS_NEG_LINK_RATE_3_0                      (0x09)
>  #define MPI2_SAS_NEG_LINK_RATE_6_0                      (0x0A)
>  #define MPI25_SAS_NEG_LINK_RATE_12_0                    (0x0B)
> +#define MPI26_SAS_NEG_LINK_RATE_22_5                    (0x0C)
>  
>  
>  /*values for AttachedPhyInfo fields */
> @@ -2037,12 +2121,14 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 {
>  #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 MPI26_SAS_PRATE_MAX_RATE_22_5                   (0xC0)
>  #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)
>  #define MPI2_SAS_PRATE_MIN_RATE_3_0                     (0x09)
>  #define MPI2_SAS_PRATE_MIN_RATE_6_0                     (0x0A)
>  #define MPI25_SAS_PRATE_MIN_RATE_12_0                   (0x0B)
> +#define MPI26_SAS_PRATE_MIN_RATE_22_5                   (0x0C)
>  
>  
>  /*values for SAS HwLinkRate fields */
> @@ -2051,11 +2137,13 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 {
>  #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 MPI26_SAS_HWRATE_MAX_RATE_22_5                  (0xC0)
>  #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)
>  #define MPI2_SAS_HWRATE_MIN_RATE_6_0                    (0x0A)
>  #define MPI25_SAS_HWRATE_MIN_RATE_12_0                  (0x0B)
> +#define MPI26_SAS_HWRATE_MIN_RATE_22_5                  (0x0C)
>  
>  
>  
> @@ -2240,11 +2328,13 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_1 {
>  #define MPI2_SASIOUNIT1_MAX_RATE_3_0                                (0x90)
>  #define MPI2_SASIOUNIT1_MAX_RATE_6_0                                (0xA0)
>  #define MPI25_SASIOUNIT1_MAX_RATE_12_0                              (0xB0)
> +#define MPI26_SASIOUNIT1_MAX_RATE_22_5                              (0xC0)
>  #define MPI2_SASIOUNIT1_MIN_RATE_MASK                               (0x0F)
>  #define MPI2_SASIOUNIT1_MIN_RATE_1_5                                (0x08)
>  #define MPI2_SASIOUNIT1_MIN_RATE_3_0                                (0x09)
>  #define MPI2_SASIOUNIT1_MIN_RATE_6_0                                (0x0A)
>  #define MPI25_SASIOUNIT1_MIN_RATE_12_0                              (0x0B)
> +#define MPI26_SASIOUNIT1_MIN_RATE_22_5                              (0x0C)
>  
>  /*see mpi2_sas.h for values for
>   *SAS IO Unit Page 1 ControllerPhyDeviceInfo values */
> @@ -3173,7 +3263,7 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0 {
>  	U16
>  		StartSlot;                  /*0x1A */
>  	U8
> -		Reserved2;                  /*0x1C */
> +		ChassisSlot;                /*0x1C */
>  	U8
>  		EnclosureLevel;		    /*0x1D */
>  	U16
> @@ -3184,11 +3274,15 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0 {
>  		Reserved4;                  /*0x24 */
>  } MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0,
>  	*PTR_MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0,
> -	Mpi2SasEnclosurePage0_t, *pMpi2SasEnclosurePage0_t;
> +	Mpi2SasEnclosurePage0_t, *pMpi2SasEnclosurePage0_t,
> +	MPI26_CONFIG_PAGE_ENCLOSURE_0,
> +	*PTR_MPI26_CONFIG_PAGE_ENCLOSURE_0,
> +	Mpi26EnclosurePage0_t, *pMpi26EnclosurePage0_t;
>  
>  #define MPI2_SASENCLOSURE0_PAGEVERSION      (0x04)
>  
>  /*values for SAS Enclosure Page 0 Flags field */
> +#define MPI2_SAS_ENCLS0_FLAGS_CHASSIS_SLOT_VALID    (0x0020)
>  #define MPI2_SAS_ENCLS0_FLAGS_ENCL_LEVEL_VALID      (0x0010)
>  #define MPI2_SAS_ENCLS0_FLAGS_MNG_MASK              (0x000F)
>  #define MPI2_SAS_ENCLS0_FLAGS_MNG_UNKNOWN           (0x0000)
> @@ -3198,6 +3292,18 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0 {
>  #define MPI2_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE     (0x0004)
>  #define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO          (0x0005)
>  
> +#define MPI26_ENCLOSURE0_PAGEVERSION        (0x04)
> +
> +/*Values for Enclosure Page 0 Flags field */
> +#define MPI26_ENCLS0_FLAGS_CHASSIS_SLOT_VALID       (0x0020)
> +#define MPI26_ENCLS0_FLAGS_ENCL_LEVEL_VALID         (0x0010)
> +#define MPI26_ENCLS0_FLAGS_MNG_MASK                 (0x000F)
> +#define MPI26_ENCLS0_FLAGS_MNG_UNKNOWN              (0x0000)
> +#define MPI26_ENCLS0_FLAGS_MNG_IOC_SES              (0x0001)
> +#define MPI26_ENCLS0_FLAGS_MNG_IOC_SGPIO            (0x0002)
> +#define MPI26_ENCLS0_FLAGS_MNG_EXP_SGPIO            (0x0003)
> +#define MPI26_ENCLS0_FLAGS_MNG_SES_ENCLOSURE        (0x0004)
> +#define MPI26_ENCLS0_FLAGS_MNG_IOC_GPIO             (0x0005)
>  
>  /****************************************************************************
>  *  Log Config Page
> @@ -3497,4 +3603,539 @@ typedef struct _MPI2_CONFIG_PAGE_EXT_MAN_PS {
>  
>  /*PageVersion should be provided by product-specific code */
>  
> +
> +
> +/****************************************************************************
> +*  values for fields used by several types of PCIe Config Pages
> +****************************************************************************/
> +
> +/*values for NegotiatedLinkRates fields */
> +#define MPI26_PCIE_NEG_LINK_RATE_MASK_PHYSICAL          (0x0F)
> +/*link rates used for Negotiated Physical Link Rate */
> +#define MPI26_PCIE_NEG_LINK_RATE_UNKNOWN                (0x00)
> +#define MPI26_PCIE_NEG_LINK_RATE_PHY_DISABLED           (0x01)
> +#define MPI26_PCIE_NEG_LINK_RATE_2_5                    (0x02)
> +#define MPI26_PCIE_NEG_LINK_RATE_5_0                    (0x03)
> +#define MPI26_PCIE_NEG_LINK_RATE_8_0                    (0x04)
> +#define MPI26_PCIE_NEG_LINK_RATE_16_0                   (0x05)
> +
> +
> +/****************************************************************************
> +*  PCIe IO Unit Config Pages (MPI v2.6 and later)
> +****************************************************************************/
> +
> +/*PCIe IO Unit Page 0 */
> +
> +typedef struct _MPI26_PCIE_IO_UNIT0_PHY_DATA {
> +	U8
> +		Link;                   /*0x00 */
> +	U8
> +		LinkFlags;              /*0x01 */
> +	U8
> +		PhyFlags;               /*0x02 */
> +	U8
> +		NegotiatedLinkRate;     /*0x03 */
> +	U32
> +		ControllerPhyDeviceInfo;/*0x04 */
> +	U16
> +		AttachedDevHandle;      /*0x08 */
> +	U16
> +		ControllerDevHandle;    /*0x0A */
> +	U32
> +		EnumerationStatus;      /*0x0C */
> +	U32
> +		Reserved1;              /*0x10 */
> +} MPI26_PCIE_IO_UNIT0_PHY_DATA,
> +	*PTR_MPI26_PCIE_IO_UNIT0_PHY_DATA,
> +	Mpi26PCIeIOUnit0PhyData_t, *pMpi26PCIeIOUnit0PhyData_t;
> +
> +/*
> + *Host code (drivers, BIOS, utilities, etc.) should leave this define set to
> + *one and check the value returned for NumPhys at runtime.
> + */
> +#ifndef MPI26_PCIE_IOUNIT0_PHY_MAX
> +#define MPI26_PCIE_IOUNIT0_PHY_MAX      (1)
> +#endif
> +
> +typedef struct _MPI26_CONFIG_PAGE_PIOUNIT_0 {
> +	MPI2_CONFIG_EXTENDED_PAGE_HEADER
> +		Header;                                 /*0x00 */
> +	U32
> +		Reserved1;                              /*0x08 */
> +	U8
> +		NumPhys;                                /*0x0C */
> +	U8
> +		InitStatus;                             /*0x0D */
> +	U16
> +		Reserved3;                              /*0x0E */
> +	MPI26_PCIE_IO_UNIT0_PHY_DATA
> +		PhyData[MPI26_PCIE_IOUNIT0_PHY_MAX];    /*0x10 */
> +} MPI26_CONFIG_PAGE_PIOUNIT_0,
> +	*PTR_MPI26_CONFIG_PAGE_PIOUNIT_0,
> +	Mpi26PCIeIOUnitPage0_t, *pMpi26PCIeIOUnitPage0_t;
> +
> +#define MPI26_PCIEIOUNITPAGE0_PAGEVERSION                   (0x00)
> +
> +/*values for PCIe IO Unit Page 0 LinkFlags */
> +#define MPI26_PCIEIOUNIT0_LINKFLAGS_ENUMERATION_IN_PROGRESS (0x08)
> +
> +/*values for PCIe IO Unit Page 0 PhyFlags */
> +#define MPI26_PCIEIOUNIT0_PHYFLAGS_PHY_DISABLED             (0x08)
> +
> +/*use MPI26_PCIE_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
> +
> +/*see mpi2_pci.h for values for PCIe IO Unit Page 0 ControllerPhyDeviceInfo
> + *values
> + */
> +
> +/*values for PCIe IO Unit Page 0 EnumerationStatus */
> +#define MPI26_PCIEIOUNIT0_ES_MAX_SWITCHES_EXCEEDED          (0x40000000)
> +#define MPI26_PCIEIOUNIT0_ES_MAX_DEVICES_EXCEEDED           (0x20000000)
> +
> +
> +/*PCIe IO Unit Page 1 */
> +
> +typedef struct _MPI26_PCIE_IO_UNIT1_PHY_DATA {
> +	U8
> +		Link;                       /*0x00 */
> +	U8
> +		LinkFlags;                  /*0x01 */
> +	U8
> +		PhyFlags;                   /*0x02 */
> +	U8
> +		MaxMinLinkRate;             /*0x03 */
> +	U32
> +		ControllerPhyDeviceInfo;    /*0x04 */
> +	U32
> +		Reserved1;                  /*0x08 */
> +} MPI26_PCIE_IO_UNIT1_PHY_DATA,
> +	*PTR_MPI26_PCIE_IO_UNIT1_PHY_DATA,
> +	Mpi26PCIeIOUnit1PhyData_t, *pMpi26PCIeIOUnit1PhyData_t;
> +
> +/*values for LinkFlags */
> +#define MPI26_PCIEIOUNIT1_LINKFLAGS_DIS_SRIS    (0x00)
> +#define MPI26_PCIEIOUNIT1_LINKFLAGS_EN_SRIS     (0x01)
> +
> +/*
> + *Host code (drivers, BIOS, utilities, etc.) should leave this define set to
> + *one and check the value returned for NumPhys at runtime.
> + */
> +#ifndef MPI26_PCIE_IOUNIT1_PHY_MAX
> +#define MPI26_PCIE_IOUNIT1_PHY_MAX      (1)
> +#endif
> +
> +typedef struct _MPI26_CONFIG_PAGE_PIOUNIT_1 {
> +	MPI2_CONFIG_EXTENDED_PAGE_HEADER
> +		Header;                             /*0x00 */
> +	U16
> +		ControlFlags;                       /*0x08 */
> +	U16
> +		Reserved;                           /*0x0A */
> +	U16
> +		AdditionalControlFlags;             /*0x0C */
> +	U16
> +		NVMeMaxQueueDepth;                  /*0x0E */
> +	U8
> +		NumPhys;                            /*0x10 */
> +	U8
> +		Reserved1;                          /*0x11 */
> +	U16
> +		Reserved2;                          /*0x12 */
> +	MPI26_PCIE_IO_UNIT1_PHY_DATA
> +		PhyData[MPI26_PCIE_IOUNIT1_PHY_MAX];/*0x14 */
> +} MPI26_CONFIG_PAGE_PIOUNIT_1,
> +	*PTR_MPI26_CONFIG_PAGE_PIOUNIT_1,
> +	Mpi26PCIeIOUnitPage1_t, *pMpi26PCIeIOUnitPage1_t;
> +
> +#define MPI26_PCIEIOUNITPAGE1_PAGEVERSION   (0x00)
> +
> +/*values for PCIe IO Unit Page 1 PhyFlags */
> +#define MPI26_PCIEIOUNIT1_PHYFLAGS_PHY_DISABLE                      (0x08)
> +#define MPI26_PCIEIOUNIT1_PHYFLAGS_ENDPOINT_ONLY                    (0x01)
> +
> +/*values for PCIe IO Unit Page 1 MaxMinLinkRate */
> +#define MPI26_PCIEIOUNIT1_MAX_RATE_MASK                             (0xF0)
> +#define MPI26_PCIEIOUNIT1_MAX_RATE_SHIFT                            (4)
> +#define MPI26_PCIEIOUNIT1_MAX_RATE_2_5                              (0x20)
> +#define MPI26_PCIEIOUNIT1_MAX_RATE_5_0                              (0x30)
> +#define MPI26_PCIEIOUNIT1_MAX_RATE_8_0                              (0x40)
> +#define MPI26_PCIEIOUNIT1_MAX_RATE_16_0                             (0x50)
> +
> +/*see mpi2_pci.h for values for PCIe IO Unit Page 0 ControllerPhyDeviceInfo
> + *values
> + */
> +
> +
> +/****************************************************************************
> +*  PCIe Switch Config Pages (MPI v2.6 and later)
> +****************************************************************************/
> +
> +/*PCIe Switch Page 0 */
> +
> +typedef struct _MPI26_CONFIG_PAGE_PSWITCH_0 {
> +	MPI2_CONFIG_EXTENDED_PAGE_HEADER
> +		Header;                     /*0x00 */
> +	U8
> +		PhysicalPort;               /*0x08 */
> +	U8
> +		Reserved1;                  /*0x09 */
> +	U16
> +		Reserved2;                  /*0x0A */
> +	U16
> +		DevHandle;                  /*0x0C */
> +	U16
> +		ParentDevHandle;            /*0x0E */
> +	U8
> +		NumPorts;                   /*0x10 */
> +	U8
> +		PCIeLevel;                  /*0x11 */
> +	U16
> +		Reserved3;                  /*0x12 */
> +	U32
> +		Reserved4;                  /*0x14 */
> +	U32
> +		Reserved5;                  /*0x18 */
> +	U32
> +		Reserved6;                  /*0x1C */
> +} MPI26_CONFIG_PAGE_PSWITCH_0, *PTR_MPI26_CONFIG_PAGE_PSWITCH_0,
> +	Mpi26PCIeSwitchPage0_t, *pMpi26PCIeSwitchPage0_t;
> +
> +#define MPI26_PCIESWITCH0_PAGEVERSION       (0x00)
> +
> +
> +/*PCIe Switch Page 1 */
> +
> +typedef struct _MPI26_CONFIG_PAGE_PSWITCH_1 {
> +	MPI2_CONFIG_EXTENDED_PAGE_HEADER
> +		Header;                     /*0x00 */
> +	U8
> +		PhysicalPort;               /*0x08 */
> +	U8
> +		Reserved1;                  /*0x09 */
> +	U16
> +		Reserved2;                  /*0x0A */
> +	U8
> +		NumPorts;                   /*0x0C */
> +	U8
> +		PortNum;                    /*0x0D */
> +	U16
> +		AttachedDevHandle;          /*0x0E */
> +	U16
> +		SwitchDevHandle;            /*0x10 */
> +	U8
> +		NegotiatedPortWidth;        /*0x12 */
> +	U8
> +		NegotiatedLinkRate;         /*0x13 */
> +	U32
> +		Reserved4;                  /*0x14 */
> +	U32
> +		Reserved5;                  /*0x18 */
> +} MPI26_CONFIG_PAGE_PSWITCH_1, *PTR_MPI26_CONFIG_PAGE_PSWITCH_1,
> +	Mpi26PCIeSwitchPage1_t, *pMpi26PCIeSwitchPage1_t;
> +
> +#define MPI26_PCIESWITCH1_PAGEVERSION       (0x00)
> +
> +/*use MPI26_PCIE_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
> +
> +
> +/****************************************************************************
> +*  PCIe Device Config Pages (MPI v2.6 and later)
> +****************************************************************************/
> +
> +/*PCIe Device Page 0 */
> +
> +typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_0 {
> +	MPI2_CONFIG_EXTENDED_PAGE_HEADER
> +		Header;                 /*0x00 */
> +	U16
> +		Slot;                   /*0x08 */
> +	U16
> +		EnclosureHandle;        /*0x0A */
> +	U64
> +		WWID;                   /*0x0C */
> +	U16
> +		ParentDevHandle;        /*0x14 */
> +	U8
> +		PortNum;                /*0x16 */
> +	U8
> +		AccessStatus;           /*0x17 */
> +	U16
> +		DevHandle;              /*0x18 */
> +	U8
> +		PhysicalPort;           /*0x1A */
> +	U8
> +		Reserved1;              /*0x1B */
> +	U32
> +		DeviceInfo;             /*0x1C */
> +	U32
> +		Flags;                  /*0x20 */
> +	U8
> +		SupportedLinkRates;     /*0x24 */
> +	U8
> +		MaxPortWidth;           /*0x25 */
> +	U8
> +		NegotiatedPortWidth;    /*0x26 */
> +	U8
> +		NegotiatedLinkRate;     /*0x27 */
> +	U8
> +		EnclosureLevel;         /*0x28 */
> +	U8
> +		Reserved2;              /*0x29 */
> +	U16
> +		Reserved3;              /*0x2A */
> +	U8
> +		ConnectorName[4];       /*0x2C */
> +	U32
> +		Reserved4;              /*0x30 */
> +	U32
> +		Reserved5;              /*0x34 */
> +} MPI26_CONFIG_PAGE_PCIEDEV_0, *PTR_MPI26_CONFIG_PAGE_PCIEDEV_0,
> +	Mpi26PCIeDevicePage0_t, *pMpi26PCIeDevicePage0_t;
> +
> +#define MPI26_PCIEDEVICE0_PAGEVERSION       (0x01)
> +
> +/*values for PCIe Device Page 0 AccessStatus field */
> +#define MPI26_PCIEDEV0_ASTATUS_NO_ERRORS                    (0x00)
> +#define MPI26_PCIEDEV0_ASTATUS_NEEDS_INITIALIZATION         (0x04)
> +#define MPI26_PCIEDEV0_ASTATUS_CAPABILITY_FAILED            (0x02)
> +#define MPI26_PCIEDEV0_ASTATUS_DEVICE_BLOCKED               (0x07)
> +#define MPI26_PCIEDEV0_ASTATUS_MEMORY_SPACE_ACCESS_FAILED   (0x08)
> +#define MPI26_PCIEDEV0_ASTATUS_UNSUPPORTED_DEVICE           (0x09)
> +#define MPI26_PCIEDEV0_ASTATUS_MSIX_REQUIRED                (0x0A)
> +#define MPI26_PCIEDEV0_ASTATUS_UNKNOWN                      (0x10)
> +
> +#define MPI26_PCIEDEV0_ASTATUS_NVME_READY_TIMEOUT           (0x30)
> +#define MPI26_PCIEDEV0_ASTATUS_NVME_DEVCFG_UNSUPPORTED      (0x31)
> +#define MPI26_PCIEDEV0_ASTATUS_NVME_IDENTIFY_FAILED         (0x32)
> +#define MPI26_PCIEDEV0_ASTATUS_NVME_QCONFIG_FAILED          (0x33)
> +#define MPI26_PCIEDEV0_ASTATUS_NVME_QCREATION_FAILED        (0x34)
> +#define MPI26_PCIEDEV0_ASTATUS_NVME_EVENTCFG_FAILED         (0x35)
> +#define MPI26_PCIEDEV0_ASTATUS_NVME_GET_FEATURE_STAT_FAILED (0x36)
> +#define MPI26_PCIEDEV0_ASTATUS_NVME_IDLE_TIMEOUT            (0x37)
> +#define MPI26_PCIEDEV0_ASTATUS_NVME_FAILURE_STATUS          (0x38)
> +
> +#define MPI26_PCIEDEV0_ASTATUS_INIT_FAIL_MAX                (0x3F)
> +
> +/*see mpi2_pci.h for the MPI26_PCIE_DEVINFO_ defines used for the DeviceInfo
> + *field
> + */
> +
> +/*values for PCIe Device Page 0 Flags field */
> +#define MPI26_PCIEDEV0_FLAGS_UNAUTHORIZED_DEVICE            (0x8000)
> +#define MPI26_PCIEDEV0_FLAGS_ENABLED_FAST_PATH              (0x4000)
> +#define MPI26_PCIEDEV0_FLAGS_FAST_PATH_CAPABLE              (0x2000)
> +#define MPI26_PCIEDEV0_FLAGS_ASYNCHRONOUS_NOTIFICATION      (0x0400)
> +#define MPI26_PCIEDEV0_FLAGS_ATA_SW_PRESERVATION            (0x0200)
> +#define MPI26_PCIEDEV0_FLAGS_UNSUPPORTED_DEVICE             (0x0100)
> +#define MPI26_PCIEDEV0_FLAGS_ATA_48BIT_LBA_SUPPORTED        (0x0080)
> +#define MPI26_PCIEDEV0_FLAGS_ATA_SMART_SUPPORTED            (0x0040)
> +#define MPI26_PCIEDEV0_FLAGS_ATA_NCQ_SUPPORTED              (0x0020)
> +#define MPI26_PCIEDEV0_FLAGS_ATA_FUA_SUPPORTED              (0x0010)
> +#define MPI26_PCIEDEV0_FLAGS_ENCL_LEVEL_VALID               (0x0002)
> +#define MPI26_PCIEDEV0_FLAGS_DEVICE_PRESENT                 (0x0001)
> +
> +/* values for PCIe Device Page 0 SupportedLinkRates field */
> +#define MPI26_PCIEDEV0_LINK_RATE_16_0_SUPPORTED             (0x08)
> +#define MPI26_PCIEDEV0_LINK_RATE_8_0_SUPPORTED              (0x04)
> +#define MPI26_PCIEDEV0_LINK_RATE_5_0_SUPPORTED              (0x02)
> +#define MPI26_PCIEDEV0_LINK_RATE_2_5_SUPPORTED              (0x01)
> +
> +/*use MPI26_PCIE_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
> +
> +
> +/*PCIe Device Page 2 */
> +
> +typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_2 {
> +	MPI2_CONFIG_EXTENDED_PAGE_HEADER
> +		Header;                 /*0x00 */
> +	U16
> +		DevHandle;              /*0x08 */
> +	U16
> +		Reserved1;              /*0x0A */
> +	U32
> +		MaximumDataTransferSize;/*0x0C */
> +	U32
> +		Capabilities;           /*0x10 */
> +	U32
> +		Reserved2;              /*0x14 */
> +} MPI26_CONFIG_PAGE_PCIEDEV_2, *PTR_MPI26_CONFIG_PAGE_PCIEDEV_2,
> +	Mpi26PCIeDevicePage2_t, *pMpi26PCIeDevicePage2_t;
> +
> +#define MPI26_PCIEDEVICE2_PAGEVERSION       (0x00)
> +
> +/*defines for PCIe Device Page 2 Capabilities field */
> +#define MPI26_PCIEDEV2_CAP_SGL_FORMAT                  (0x00000004)
> +#define MPI26_PCIEDEV2_CAP_BIT_BUCKET_SUPPORT          (0x00000002)
> +#define MPI26_PCIEDEV2_CAP_SGL_SUPPORT                 (0x00000001)
> +
> +
> +/****************************************************************************
> +*  PCIe Link Config Pages (MPI v2.6 and later)
> +****************************************************************************/
> +
> +/*PCIe Link Page 1 */
> +
> +typedef struct _MPI26_CONFIG_PAGE_PCIELINK_1 {
> +	MPI2_CONFIG_EXTENDED_PAGE_HEADER
> +		Header;                     /*0x00 */
> +	U8
> +		Link;                       /*0x08 */
> +	U8
> +		Reserved1;                  /*0x09 */
> +	U16
> +		Reserved2;                  /*0x0A */
> +	U32
> +		CorrectableErrorCount;      /*0x0C */
> +	U16
> +		NonFatalErrorCount;         /*0x10 */
> +	U16
> +		Reserved3;                  /*0x12 */
> +	U16
> +		FatalErrorCount;            /*0x14 */
> +	U16
> +		Reserved4;                  /*0x16 */
> +} MPI26_CONFIG_PAGE_PCIELINK_1, *PTR_MPI26_CONFIG_PAGE_PCIELINK_1,
> +	Mpi26PcieLinkPage1_t, *pMpi26PcieLinkPage1_t;
> +
> +#define MPI26_PCIELINK1_PAGEVERSION            (0x00)
> +
> +/*PCIe Link Page 2 */
> +
> +typedef struct _MPI26_PCIELINK2_LINK_EVENT {
> +	U8
> +		LinkEventCode;      /*0x00 */
> +	U8
> +		Reserved1;          /*0x01 */
> +	U16
> +		Reserved2;          /*0x02 */
> +	U32
> +		LinkEventInfo;      /*0x04 */
> +} MPI26_PCIELINK2_LINK_EVENT, *PTR_MPI26_PCIELINK2_LINK_EVENT,
> +	Mpi26PcieLink2LinkEvent_t, *pMpi26PcieLink2LinkEvent_t;
> +
> +/*use MPI26_PCIELINK3_EVTCODE_ for the LinkEventCode field */
> +
> +
> +/*
> + *Host code (drivers, BIOS, utilities, etc.) should leave this define set to
> + *one and check the value returned for NumLinkEvents at runtime.
> + */
> +#ifndef MPI26_PCIELINK2_LINK_EVENT_MAX
> +#define MPI26_PCIELINK2_LINK_EVENT_MAX      (1)
> +#endif
> +
> +typedef struct _MPI26_CONFIG_PAGE_PCIELINK_2 {
> +	MPI2_CONFIG_EXTENDED_PAGE_HEADER
> +		Header;                     /*0x00 */
> +	U8
> +		Link;                       /*0x08 */
> +	U8
> +		Reserved1;                  /*0x09 */
> +	U16
> +		Reserved2;                  /*0x0A */
> +	U8
> +		NumLinkEvents;              /*0x0C */
> +	U8
> +		Reserved3;                  /*0x0D */
> +	U16
> +		Reserved4;                  /*0x0E */
> +	MPI26_PCIELINK2_LINK_EVENT
> +		LinkEvent[MPI26_PCIELINK2_LINK_EVENT_MAX]; /*0x10 */
> +} MPI26_CONFIG_PAGE_PCIELINK_2, *PTR_MPI26_CONFIG_PAGE_PCIELINK_2,
> +	Mpi26PcieLinkPage2_t, *pMpi26PcieLinkPage2_t;
> +
> +#define MPI26_PCIELINK2_PAGEVERSION            (0x00)
> +
> +/*PCIe Link Page 3 */
> +
> +typedef struct _MPI26_PCIELINK3_LINK_EVENT_CONFIG {
> +	U8
> +		LinkEventCode;      /*0x00 */
> +	U8
> +		Reserved1;          /*0x01 */
> +	U16
> +		Reserved2;          /*0x02 */
> +	U8
> +		CounterType;        /*0x04 */
> +	U8
> +		ThresholdWindow;    /*0x05 */
> +	U8
> +		TimeUnits;          /*0x06 */
> +	U8
> +		Reserved3;          /*0x07 */
> +	U32
> +		EventThreshold;     /*0x08 */
> +	U16
> +		ThresholdFlags;     /*0x0C */
> +	U16
> +		Reserved4;          /*0x0E */
> +} MPI26_PCIELINK3_LINK_EVENT_CONFIG, *PTR_MPI26_PCIELINK3_LINK_EVENT_CONFIG,
> +	Mpi26PcieLink3LinkEventConfig_t, *pMpi26PcieLink3LinkEventConfig_t;
> +
> +/*values for LinkEventCode field */
> +#define MPI26_PCIELINK3_EVTCODE_NO_EVENT                              (0x00)
> +#define MPI26_PCIELINK3_EVTCODE_CORRECTABLE_ERROR_RECEIVED            (0x01)
> +#define MPI26_PCIELINK3_EVTCODE_NON_FATAL_ERROR_RECEIVED              (0x02)
> +#define MPI26_PCIELINK3_EVTCODE_FATAL_ERROR_RECEIVED                  (0x03)
> +#define MPI26_PCIELINK3_EVTCODE_DATA_LINK_ERROR_DETECTED              (0x04)
> +#define MPI26_PCIELINK3_EVTCODE_TRANSACTION_LAYER_ERROR_DETECTED      (0x05)
> +#define MPI26_PCIELINK3_EVTCODE_TLP_ECRC_ERROR_DETECTED               (0x06)
> +#define MPI26_PCIELINK3_EVTCODE_POISONED_TLP                          (0x07)
> +#define MPI26_PCIELINK3_EVTCODE_RECEIVED_NAK_DLLP                     (0x08)
> +#define MPI26_PCIELINK3_EVTCODE_SENT_NAK_DLLP                         (0x09)
> +#define MPI26_PCIELINK3_EVTCODE_LTSSM_RECOVERY_STATE                  (0x0A)
> +#define MPI26_PCIELINK3_EVTCODE_LTSSM_RXL0S_STATE                     (0x0B)
> +#define MPI26_PCIELINK3_EVTCODE_LTSSM_TXL0S_STATE                     (0x0C)
> +#define MPI26_PCIELINK3_EVTCODE_LTSSM_L1_STATE                        (0x0D)
> +#define MPI26_PCIELINK3_EVTCODE_LTSSM_DISABLED_STATE                  (0x0E)
> +#define MPI26_PCIELINK3_EVTCODE_LTSSM_HOT_RESET_STATE                 (0x0F)
> +#define MPI26_PCIELINK3_EVTCODE_SYSTEM_ERROR                          (0x10)
> +#define MPI26_PCIELINK3_EVTCODE_DECODE_ERROR                          (0x11)
> +#define MPI26_PCIELINK3_EVTCODE_DISPARITY_ERROR                       (0x12)
> +
> +/*values for the CounterType field */
> +#define MPI26_PCIELINK3_COUNTER_TYPE_WRAPPING               (0x00)
> +#define MPI26_PCIELINK3_COUNTER_TYPE_SATURATING             (0x01)
> +#define MPI26_PCIELINK3_COUNTER_TYPE_PEAK_VALUE             (0x02)
> +
> +/*values for the TimeUnits field */
> +#define MPI26_PCIELINK3_TM_UNITS_10_MICROSECONDS            (0x00)
> +#define MPI26_PCIELINK3_TM_UNITS_100_MICROSECONDS           (0x01)
> +#define MPI26_PCIELINK3_TM_UNITS_1_MILLISECOND              (0x02)
> +#define MPI26_PCIELINK3_TM_UNITS_10_MILLISECONDS            (0x03)
> +
> +/*values for the ThresholdFlags field */
> +#define MPI26_PCIELINK3_TFLAGS_EVENT_NOTIFY                 (0x0001)
> +
> +/*
> + *Host code (drivers, BIOS, utilities, etc.) should leave this define set to
> + *one and check the value returned for NumLinkEvents at runtime.
> + */
> +#ifndef MPI26_PCIELINK3_LINK_EVENT_MAX
> +#define MPI26_PCIELINK3_LINK_EVENT_MAX      (1)
> +#endif
> +
> +typedef struct _MPI26_CONFIG_PAGE_PCIELINK_3 {
> +	MPI2_CONFIG_EXTENDED_PAGE_HEADER
> +		Header;                     /*0x00 */
> +	U8
> +		Link;                       /*0x08 */
> +	U8
> +		Reserved1;                  /*0x09 */
> +	U16
> +		Reserved2;                  /*0x0A */
> +	U8
> +		NumLinkEvents;              /*0x0C */
> +	U8
> +		Reserved3;                  /*0x0D */
> +	U16
> +		Reserved4;                  /*0x0E */
> +	MPI26_PCIELINK3_LINK_EVENT_CONFIG
> +		LinkEventConfig[MPI26_PCIELINK3_LINK_EVENT_MAX]; /*0x10 */
> +} MPI26_CONFIG_PAGE_PCIELINK_3, *PTR_MPI26_CONFIG_PAGE_PCIELINK_3,
> +	Mpi26PcieLinkPage3_t, *pMpi26PcieLinkPage3_t;
> +
> +#define MPI26_PCIELINK3_PAGEVERSION            (0x00)
> +
> +
>  #endif
> diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_init.h b/drivers/scsi/mpt3sas/mpi/mpi2_init.h
> index bba56b6..7597c24 100644
> --- a/drivers/scsi/mpt3sas/mpi/mpi2_init.h
> +++ b/drivers/scsi/mpt3sas/mpi/mpi2_init.h
> @@ -6,7 +6,7 @@
>   *         Title:  MPI SCSI initiator mode messages and structures
>   * Creation Date:  June 23, 2006
>   *
> - * mpi2_init.h Version:  02.00.20
> + * mpi2_init.h Version:  02.00.21
>   *
>   * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
>   *       prefix are for use only on MPI v2.5 products, and must not be used
> @@ -54,6 +54,8 @@
>   * 08-26-15  02.00.18  Added SCSITASKMGMT_MSGFLAGS for Target Reset.
>   * 12-18-15  02.00.19  Added EEDPObservedValue added to SCSI IO Reply message.
>   * 01-04-16  02.00.20  Modified EEDP reported values in SCSI IO Reply message.
> + * 01-21-16  02.00.21  Modified MPI26_SCSITASKMGMT_MSGFLAGS_PCIE* defines to
> + *                     be unique within first 32 characters.
>   * --------------------------------------------------------------------------
>   */
>  
> @@ -373,6 +375,11 @@ typedef struct _MPI2_SCSI_IO_REPLY {
>  } MPI2_SCSI_IO_REPLY, *PTR_MPI2_SCSI_IO_REPLY,
>  	Mpi2SCSIIOReply_t, *pMpi2SCSIIOReply_t;
>  
> +/*SCSI IO Reply MsgFlags bits */
> +#define MPI26_SCSIIO_REPLY_MSGFLAGS_REFTAG_OBSERVED_VALID     (0x01)
> +#define MPI26_SCSIIO_REPLY_MSGFLAGS_GUARD_OBSERVED_VALID      (0x02)
> +#define MPI26_SCSIIO_REPLY_MSGFLAGS_APPTAG_OBSERVED_VALID     (0x04)
> +
>  /*SCSI IO Reply SCSIStatus values (SAM-4 status codes) */
>  
>  #define MPI2_SCSI_STATUS_GOOD                   (0x00)
> @@ -446,11 +453,13 @@ typedef struct _MPI2_SCSI_TASK_MANAGE_REQUEST {
>  /*MsgFlags bits */
>  
>  #define MPI2_SCSITASKMGMT_MSGFLAGS_MASK_TARGET_RESET    (0x18)
> +#define MPI26_SCSITASKMGMT_MSGFLAGS_HOT_RESET_PCIE        (0x00)
>  #define MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET           (0x00)
>  #define MPI2_SCSITASKMGMT_MSGFLAGS_NEXUS_RESET_SRST     (0x08)
>  #define MPI2_SCSITASKMGMT_MSGFLAGS_SAS_HARD_LINK_RESET  (0x10)
>  
>  #define MPI2_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU  (0x01)
> +#define MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE (0x18)
>  
>  /*SCSI Task Management Reply Message */
>  typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY {
> diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
> index af4be40..816ade3 100644
> --- a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
> +++ b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
> @@ -6,7 +6,7 @@
>   *         Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
>   * Creation Date:  October 11, 2006
>   *
> - * mpi2_ioc.h Version:  02.00.27
> + * mpi2_ioc.h Version:  02.00.32
>   *
>   * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
>   *       prefix are for use only on MPI v2.5 products, and must not be used
> @@ -140,7 +140,32 @@
>   *                     Added MPI26_FW_HEADER_PID_FAMILY_3324_SAS and
>   *                     MPI26_FW_HEADER_PID_FAMILY_3516_SAS.
>   *                     Added MPI26_CTRL_OP_SHUTDOWN.
> - * 08-25-15  02.00.27  Added IC ARCH Class based signature defines
> + * 08-25-15  02.00.27  Added IC ARCH Class based signature defines.
> + *                     Added MPI26_EVENT_PCIE_ENUM_ES_RESOURCES_EXHAUSTED event.
> + *                     Added ConigurationFlags field to IOCInit message to
> + *                     support NVMe SGL format control.
> + *                     Added PCIe SRIOV support.
> + * 02-17-16   02.00.28 Added SAS 4 22.5 gbs speed support.
> + *                     Added PCIe 4 16.0 GT/sec speec support.
> + *                     Removed AHCI support.
> + *                     Removed SOP support.
> + * 07-01-16   02.00.29 Added Archclass for 4008 product.
> + *                     Added IOCException MPI2_IOCFACTS_EXCEPT_PCIE_DISABLED
> + * 08-23-16   02.00.30 Added new defines for the ImageType field of FWDownload
> + *                     Request Message.
> + *                     Added new defines for the ImageType field of FWUpload
> + *                     Request Message.
> + *                     Added new values for the RegionType field in the Layout
> + *                     Data sections of the FLASH Layout Extended Image Data.
> + *                     Added new defines for the ReasonCode field of
> + *                     Active Cable Exception Event.
> + *                     Added MPI2_EVENT_ENCL_DEVICE_STATUS_CHANGE and
> + *                     MPI26_EVENT_DATA_ENCL_DEV_STATUS_CHANGE.
> + * 11-23-16   02.00.31 Added MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR and
> + *                     MPI25_EVENT_DATA_SAS_DEVICE_DISCOVERY_ERROR.
> + * 02-02-17   02.00.32 Added MPI2_FW_DOWNLOAD_ITYPE_CBB_BACKUP.
> + *                     Added MPI25_EVENT_DATA_ACTIVE_CABLE_EXCEPT and related
> + *                     defines for the ReasonCode field.
>   * --------------------------------------------------------------------------
>   */
>  
> @@ -212,6 +237,9 @@ typedef struct _MPI2_IOC_INIT_REQUEST {
>  #define MPI2_IOCINIT_HDRVERSION_DEV_MASK        (0x00FF)
>  #define MPI2_IOCINIT_HDRVERSION_DEV_SHIFT       (0)
>  
> +/*ConfigurationFlags */
> +#define MPI26_IOCINIT_CFGFLAGS_NVME_SGL_FORMAT  (0x0001)
> +
>  /*minimum depth for a Reply Descriptor Post Queue */
>  #define MPI2_RDPQ_DEPTH_MIN                     (16)
>  
> @@ -299,6 +327,10 @@ typedef struct _MPI2_IOC_FACTS_REPLY {
>  	U16 MinDevHandle;	/*0x3C */
>  	U8 CurrentHostPageSize;	/* 0x3E */
>  	U8 Reserved4;		/* 0x3F */
> +	U8 SGEModifierMask;	/*0x40 */
> +	U8 SGEModifierValue;	/*0x41 */
> +	U8 SGEModifierShift;	/*0x42 */
> +	U8 Reserved5;		/*0x43 */
>  } MPI2_IOC_FACTS_REPLY, *PTR_MPI2_IOC_FACTS_REPLY,
>  	Mpi2IOCFactsReply_t, *pMpi2IOCFactsReply_t;
>  
> @@ -315,6 +347,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY {
>  #define MPI2_IOCFACTS_HDRVERSION_DEV_SHIFT              (0)
>  
>  /*IOCExceptions */
> +#define MPI2_IOCFACTS_EXCEPT_PCIE_DISABLED              (0x0400)
>  #define MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE     (0x0200)
>  #define MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX      (0x0100)
>  
> @@ -335,6 +368,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY {
>  /*ProductID field uses MPI2_FW_HEADER_PID_ */
>  
>  /*IOCCapabilities */
> +#define MPI26_IOCFACTS_CAPABILITY_PCIE_SRIOV            (0x00100000)
>  #define MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ            (0x00080000)
>  #define MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE     (0x00040000)
>  #define MPI25_IOCFACTS_CAPABILITY_FAST_PATH_CAPABLE     (0x00020000)
> @@ -353,6 +387,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY {
>  #define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004)
>  
>  /*ProtocolFlags */
> +#define MPI2_IOCFACTS_PROTOCOL_NVME_DEVICES             (0x0008)
>  #define MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR           (0x0002)
>  #define MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET              (0x0001)
>  
> @@ -402,6 +437,8 @@ typedef struct _MPI2_PORT_FACTS_REPLY {
>  #define MPI2_PORTFACTS_PORTTYPE_ISCSI               (0x20)
>  #define MPI2_PORTFACTS_PORTTYPE_SAS_PHYSICAL        (0x30)
>  #define MPI2_PORTFACTS_PORTTYPE_SAS_VIRTUAL         (0x31)
> +#define MPI2_PORTFACTS_PORTTYPE_TRI_MODE            (0x40)
> +
>  
>  /****************************************************************************
>  * PortEnable message
> @@ -508,6 +545,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY {
>  #define MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW          (0x0019)
>  #define MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST         (0x001C)
>  #define MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE    (0x001D)
> +#define MPI2_EVENT_ENCL_DEVICE_STATUS_CHANGE        (0x001D)
>  #define MPI2_EVENT_IR_VOLUME                        (0x001E)
>  #define MPI2_EVENT_IR_PHYSICAL_DISK                 (0x001F)
>  #define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST     (0x0020)
> @@ -520,7 +558,12 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY {
>  #define MPI2_EVENT_TEMP_THRESHOLD                   (0x0027)
>  #define MPI2_EVENT_HOST_MESSAGE                     (0x0028)
>  #define MPI2_EVENT_POWER_PERFORMANCE_CHANGE         (0x0029)
> +#define MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE        (0x0030)
> +#define MPI2_EVENT_PCIE_ENUMERATION                 (0x0031)
> +#define MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST        (0x0032)
> +#define MPI2_EVENT_PCIE_LINK_COUNTER                (0x0033)
>  #define MPI2_EVENT_ACTIVE_CABLE_EXCEPTION           (0x0034)
> +#define MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR       (0x0035)
>  #define MPI2_EVENT_MIN_PRODUCT_SPECIFIC             (0x006E)
>  #define MPI2_EVENT_MAX_PRODUCT_SPECIFIC             (0x007F)
>  
> @@ -617,11 +660,20 @@ typedef struct _MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT {
>  	U8          ReasonCode;                         /* 0x04 */
>  	U8          ReceptacleID;                       /* 0x05 */
>  	U16         Reserved1;                          /* 0x06 */
> -} MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
> +} MPI25_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
> +	*PTR_MPI25_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
> +	Mpi25EventDataActiveCableExcept_t,
> +	*pMpi25EventDataActiveCableExcept_t,
> +	MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
>  	*PTR_MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
>  	Mpi26EventDataActiveCableExcept_t,
>  	*pMpi26EventDataActiveCableExcept_t;
>  
> +/*MPI2.5 defines for the ReasonCode field */
> +#define MPI25_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER     (0x00)
> +#define MPI25_EVENT_ACTIVE_CABLE_PRESENT                (0x01)
> +#define MPI25_EVENT_ACTIVE_CABLE_DEGRADED               (0x02)
> +
>  /* defines for ReasonCode field */
>  #define MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER     (0x00)
>  #define MPI26_EVENT_ACTIVE_CABLE_PRESENT                (0x01)
> @@ -957,6 +1009,7 @@ typedef struct _MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST {
>  #define MPI2_EVENT_SAS_TOPO_LR_RATE_3_0                     (0x09)
>  #define MPI2_EVENT_SAS_TOPO_LR_RATE_6_0                     (0x0A)
>  #define MPI25_EVENT_SAS_TOPO_LR_RATE_12_0                   (0x0B)
> +#define MPI26_EVENT_SAS_TOPO_LR_RATE_22_5                   (0x0C)
>  
>  /*values for the PhyStatus field */
>  #define MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT                (0x80)
> @@ -982,12 +1035,43 @@ typedef struct _MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE {
>  } MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE,
>  	*PTR_MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE,
>  	Mpi2EventDataSasEnclDevStatusChange_t,
> -	*pMpi2EventDataSasEnclDevStatusChange_t;
> +	*pMpi2EventDataSasEnclDevStatusChange_t,
> +	MPI26_EVENT_DATA_ENCL_DEV_STATUS_CHANGE,
> +	*PTR_MPI26_EVENT_DATA_ENCL_DEV_STATUS_CHANGE,
> +	Mpi26EventDataEnclDevStatusChange_t,
> +	*pMpi26EventDataEnclDevStatusChange_t;
>  
>  /*SAS Enclosure Device Status Change event ReasonCode values */
>  #define MPI2_EVENT_SAS_ENCL_RC_ADDED                (0x01)
>  #define MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING       (0x02)
>  
> +/*Enclosure Device Status Change event ReasonCode values */
> +#define MPI26_EVENT_ENCL_RC_ADDED                   (0x01)
> +#define MPI26_EVENT_ENCL_RC_NOT_RESPONDING          (0x02)
> +
> +
> +typedef struct _MPI25_EVENT_DATA_SAS_DEVICE_DISCOVERY_ERROR {
> +	U16
> +		DevHandle;                  /*0x00 */
> +	U8
> +		ReasonCode;                 /*0x02 */
> +	U8
> +		PhysicalPort;               /*0x03 */
> +	U32
> +		Reserved1[2];               /*0x04 */
> +	U64
> +		SASAddress;                 /*0x0C */
> +	U32
> +		Reserved2[2];               /*0x14 */
> +} MPI25_EVENT_DATA_SAS_DEVICE_DISCOVERY_ERROR,
> +	*PTR_MPI25_EVENT_DATA_SAS_DEVICE_DISCOVERY_ERROR,
> +	Mpi25EventDataSasDeviceDiscoveryError_t,
> +	*pMpi25EventDataSasDeviceDiscoveryError_t;
> +
> +/*SAS Device Discovery Error Event data ReasonCode values */
> +#define MPI25_EVENT_SAS_DISC_ERR_SMP_FAILED         (0x01)
> +#define MPI25_EVENT_SAS_DISC_ERR_SMP_TIMEOUT        (0x02)
> +
>  /*SAS PHY Counter Event data */
>  
>  typedef struct _MPI2_EVENT_DATA_SAS_PHY_COUNTER {
> @@ -1073,6 +1157,217 @@ typedef struct _MPI2_EVENT_DATA_HBD_PHY {
>  /*values for the DescriptorType field */
>  #define MPI2_EVENT_HBD_DT_SAS               (0x01)
>  
> +
> +/*PCIe Device Status Change Event data (MPI v2.6 and later) */
> +
> +typedef struct _MPI26_EVENT_DATA_PCIE_DEVICE_STATUS_CHANGE {
> +	U16
> +		TaskTag;                        /*0x00 */
> +	U8
> +		ReasonCode;                     /*0x02 */
> +	U8
> +		PhysicalPort;                   /*0x03 */
> +	U8
> +		ASC;                            /*0x04 */
> +	U8
> +		ASCQ;                           /*0x05 */
> +	U16
> +		DevHandle;                      /*0x06 */
> +	U32
> +		Reserved2;                      /*0x08 */
> +	U64
> +		WWID;                           /*0x0C */
> +	U8
> +		LUN[8];                         /*0x14 */
> +} MPI26_EVENT_DATA_PCIE_DEVICE_STATUS_CHANGE,
> +	*PTR_MPI26_EVENT_DATA_PCIE_DEVICE_STATUS_CHANGE,
> +	Mpi26EventDataPCIeDeviceStatusChange_t,
> +	*pMpi26EventDataPCIeDeviceStatusChange_t;
> +
> +/*PCIe Device Status Change Event data ReasonCode values */
> +#define MPI26_EVENT_PCIDEV_STAT_RC_SMART_DATA                           (0x05)
> +#define MPI26_EVENT_PCIDEV_STAT_RC_UNSUPPORTED                          (0x07)
> +#define MPI26_EVENT_PCIDEV_STAT_RC_INTERNAL_DEVICE_RESET                (0x08)
> +#define MPI26_EVENT_PCIDEV_STAT_RC_TASK_ABORT_INTERNAL                  (0x09)
> +#define MPI26_EVENT_PCIDEV_STAT_RC_ABORT_TASK_SET_INTERNAL              (0x0A)
> +#define MPI26_EVENT_PCIDEV_STAT_RC_CLEAR_TASK_SET_INTERNAL              (0x0B)
> +#define MPI26_EVENT_PCIDEV_STAT_RC_QUERY_TASK_INTERNAL                  (0x0C)
> +#define MPI26_EVENT_PCIDEV_STAT_RC_ASYNC_NOTIFICATION                   (0x0D)
> +#define MPI26_EVENT_PCIDEV_STAT_RC_CMP_INTERNAL_DEV_RESET               (0x0E)
> +#define MPI26_EVENT_PCIDEV_STAT_RC_CMP_TASK_ABORT_INTERNAL              (0x0F)
> +#define MPI26_EVENT_PCIDEV_STAT_RC_DEV_INIT_FAILURE                     (0x10)
> +
> +
> +/*PCIe Enumeration Event data (MPI v2.6 and later) */
> +
> +typedef struct _MPI26_EVENT_DATA_PCIE_ENUMERATION {
> +	U8
> +		Flags;                      /*0x00 */
> +	U8
> +		ReasonCode;                 /*0x01 */
> +	U8
> +		PhysicalPort;               /*0x02 */
> +	U8
> +		Reserved1;                  /*0x03 */
> +	U32
> +		EnumerationStatus;          /*0x04 */
> +} MPI26_EVENT_DATA_PCIE_ENUMERATION,
> +	*PTR_MPI26_EVENT_DATA_PCIE_ENUMERATION,
> +	Mpi26EventDataPCIeEnumeration_t,
> +	*pMpi26EventDataPCIeEnumeration_t;
> +
> +/*PCIe Enumeration Event data Flags values */
> +#define MPI26_EVENT_PCIE_ENUM_DEVICE_CHANGE                 (0x02)
> +#define MPI26_EVENT_PCIE_ENUM_IN_PROGRESS                   (0x01)
> +
> +/*PCIe Enumeration Event data ReasonCode values */
> +#define MPI26_EVENT_PCIE_ENUM_RC_STARTED                    (0x01)
> +#define MPI26_EVENT_PCIE_ENUM_RC_COMPLETED                  (0x02)
> +
> +/*PCIe Enumeration Event data EnumerationStatus values */
> +#define MPI26_EVENT_PCIE_ENUM_ES_MAX_SWITCHES_EXCEED            (0x40000000)
> +#define MPI26_EVENT_PCIE_ENUM_ES_MAX_DEVICES_EXCEED             (0x20000000)
> +#define MPI26_EVENT_PCIE_ENUM_ES_RESOURCES_EXHAUSTED            (0x10000000)
> +
> +
> +/*PCIe Topology Change List Event data (MPI v2.6 and later) */
> +
> +/*
> + *Host code (drivers, BIOS, utilities, etc.) should leave this define set to
> + *one and check NumEntries at runtime.
> + */
> +#ifndef MPI26_EVENT_PCIE_TOPO_PORT_COUNT
> +#define MPI26_EVENT_PCIE_TOPO_PORT_COUNT        (1)
> +#endif
> +
> +typedef struct _MPI26_EVENT_PCIE_TOPO_PORT_ENTRY {
> +	U16
> +		AttachedDevHandle;      /*0x00 */
> +	U8
> +		PortStatus;             /*0x02 */
> +	U8
> +		Reserved1;              /*0x03 */
> +	U8
> +		CurrentPortInfo;        /*0x04 */
> +	U8
> +		Reserved2;              /*0x05 */
> +	U8
> +		PreviousPortInfo;       /*0x06 */
> +	U8
> +		Reserved3;              /*0x07 */
> +} MPI26_EVENT_PCIE_TOPO_PORT_ENTRY,
> +	*PTR_MPI26_EVENT_PCIE_TOPO_PORT_ENTRY,
> +	Mpi26EventPCIeTopoPortEntry_t,
> +	*pMpi26EventPCIeTopoPortEntry_t;
> +
> +/*PCIe Topology Change List Event data PortStatus values */
> +#define MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED                  (0x01)
> +#define MPI26_EVENT_PCIE_TOPO_PS_NOT_RESPONDING             (0x02)
> +#define MPI26_EVENT_PCIE_TOPO_PS_PORT_CHANGED               (0x03)
> +#define MPI26_EVENT_PCIE_TOPO_PS_NO_CHANGE                  (0x04)
> +#define MPI26_EVENT_PCIE_TOPO_PS_DELAY_NOT_RESPONDING       (0x05)
> +
> +/*PCIe Topology Change List Event data defines for CurrentPortInfo and
> + *PreviousPortInfo
> + */
> +#define MPI26_EVENT_PCIE_TOPO_PI_LANE_MASK                  (0xF0)
> +#define MPI26_EVENT_PCIE_TOPO_PI_LANES_UNKNOWN              (0x00)
> +#define MPI26_EVENT_PCIE_TOPO_PI_1_LANE                     (0x10)
> +#define MPI26_EVENT_PCIE_TOPO_PI_2_LANES                    (0x20)
> +#define MPI26_EVENT_PCIE_TOPO_PI_4_LANES                    (0x30)
> +#define MPI26_EVENT_PCIE_TOPO_PI_8_LANES                    (0x40)
> +
> +#define MPI26_EVENT_PCIE_TOPO_PI_RATE_MASK                  (0x0F)
> +#define MPI26_EVENT_PCIE_TOPO_PI_RATE_UNKNOWN               (0x00)
> +#define MPI26_EVENT_PCIE_TOPO_PI_RATE_DISABLED              (0x01)
> +#define MPI26_EVENT_PCIE_TOPO_PI_RATE_2_5                   (0x02)
> +#define MPI26_EVENT_PCIE_TOPO_PI_RATE_5_0                   (0x03)
> +#define MPI26_EVENT_PCIE_TOPO_PI_RATE_8_0                   (0x04)
> +#define MPI26_EVENT_PCIE_TOPO_PI_RATE_16_0                  (0x05)
> +
> +typedef struct _MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST {
> +	U16
> +		EnclosureHandle;        /*0x00 */
> +	U16
> +		SwitchDevHandle;        /*0x02 */
> +	U8
> +		NumPorts;               /*0x04 */
> +	U8
> +		Reserved1;              /*0x05 */
> +	U16
> +		Reserved2;              /*0x06 */
> +	U8
> +		NumEntries;             /*0x08 */
> +	U8
> +		StartPortNum;           /*0x09 */
> +	U8
> +		SwitchStatus;           /*0x0A */
> +	U8
> +		PhysicalPort;           /*0x0B */
> +	MPI26_EVENT_PCIE_TOPO_PORT_ENTRY
> +		PortEntry[MPI26_EVENT_PCIE_TOPO_PORT_COUNT]; /*0x0C */
> +} MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST,
> +	*PTR_MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST,
> +	Mpi26EventDataPCIeTopologyChangeList_t,
> +	*pMpi26EventDataPCIeTopologyChangeList_t;
> +
> +/*PCIe Topology Change List Event data SwitchStatus values */
> +#define MPI26_EVENT_PCIE_TOPO_SS_NO_PCIE_SWITCH             (0x00)
> +#define MPI26_EVENT_PCIE_TOPO_SS_ADDED                      (0x01)
> +#define MPI26_EVENT_PCIE_TOPO_SS_NOT_RESPONDING             (0x02)
> +#define MPI26_EVENT_PCIE_TOPO_SS_RESPONDING                 (0x03)
> +#define MPI26_EVENT_PCIE_TOPO_SS_DELAY_NOT_RESPONDING       (0x04)
> +
> +/*PCIe Link Counter Event data (MPI v2.6 and later) */
> +
> +typedef struct _MPI26_EVENT_DATA_PCIE_LINK_COUNTER {
> +	U64
> +		TimeStamp;          /*0x00 */
> +	U32
> +		Reserved1;          /*0x08 */
> +	U8
> +		LinkEventCode;      /*0x0C */
> +	U8
> +		LinkNum;            /*0x0D */
> +	U16
> +		Reserved2;          /*0x0E */
> +	U32
> +		LinkEventInfo;      /*0x10 */
> +	U8
> +		CounterType;        /*0x14 */
> +	U8
> +		ThresholdWindow;    /*0x15 */
> +	U8
> +		TimeUnits;          /*0x16 */
> +	U8
> +		Reserved3;          /*0x17 */
> +	U32
> +		EventThreshold;     /*0x18 */
> +	U16
> +		ThresholdFlags;     /*0x1C */
> +	U16
> +		Reserved4;          /*0x1E */
> +} MPI26_EVENT_DATA_PCIE_LINK_COUNTER,
> +	*PTR_MPI26_EVENT_DATA_PCIE_LINK_COUNTER,
> +	Mpi26EventDataPcieLinkCounter_t, *pMpi26EventDataPcieLinkCounter_t;
> +
> +
> +/*use MPI26_PCIELINK3_EVTCODE_ values from mpi2_cnfg.h for the LinkEventCode
> + *field
> + */
> +
> +/*use MPI26_PCIELINK3_COUNTER_TYPE_ values from mpi2_cnfg.h for the CounterType
> + *field
> + */
> +
> +/*use MPI26_PCIELINK3_TIME_UNITS_ values from mpi2_cnfg.h for the TimeUnits
> + *field
> + */
> +
> +/*use MPI26_PCIELINK3_TFLAGS_ values from mpi2_cnfg.h for the ThresholdFlags
> + *field
> + */
> +
>  /****************************************************************************
>  * EventAck message
>  ****************************************************************************/
> @@ -1190,6 +1485,14 @@ typedef struct _MPI2_FW_DOWNLOAD_REQUEST {
>  #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_CBB_BACKUP           (0x0D)
> +#define MPI2_FW_DOWNLOAD_ITYPE_SBR                  (0x0E)
> +#define MPI2_FW_DOWNLOAD_ITYPE_SBR_BACKUP           (0x0F)
> +#define MPI2_FW_DOWNLOAD_ITYPE_HIIM                 (0x10)
> +#define MPI2_FW_DOWNLOAD_ITYPE_HIIA                 (0x11)
> +#define MPI2_FW_DOWNLOAD_ITYPE_CTLR                 (0x12)
> +#define MPI2_FW_DOWNLOAD_ITYPE_IMR_FIRMWARE         (0x13)
> +#define MPI2_FW_DOWNLOAD_ITYPE_MR_NVDATA            (0x14)
>  #define MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC (0xF0)
>  
>  /*MPI v2.0 FWDownload TransactionContext Element */
> @@ -1276,6 +1579,14 @@ typedef struct _MPI2_FW_UPLOAD_REQUEST {
>  #define MPI2_FW_UPLOAD_ITYPE_COMPLETE           (0x0A)
>  #define MPI2_FW_UPLOAD_ITYPE_COMMON_BOOT_BLOCK  (0x0B)
>  #define MPI2_FW_UPLOAD_ITYPE_CBB_BACKUP         (0x0D)
> +#define MPI2_FW_UPLOAD_ITYPE_SBR                (0x0E)
> +#define MPI2_FW_UPLOAD_ITYPE_SBR_BACKUP         (0x0F)
> +#define MPI2_FW_UPLOAD_ITYPE_HIIM               (0x10)
> +#define MPI2_FW_UPLOAD_ITYPE_HIIA               (0x11)
> +#define MPI2_FW_UPLOAD_ITYPE_CTLR               (0x12)
> +#define MPI2_FW_UPLOAD_ITYPE_IMR_FIRMWARE       (0x13)
> +#define MPI2_FW_UPLOAD_ITYPE_MR_NVDATA          (0x14)
> +
>  
>  /*MPI v2.0 FWUpload TransactionContext Element */
>  typedef struct _MPI2_FW_UPLOAD_TCSGE {
> @@ -1394,10 +1705,13 @@ typedef struct _MPI2_FW_IMAGE_HEADER {
>  #define MPI26_FW_HEADER_SIGNATURE0_ARC_1        (0x00)
>  #define MPI26_FW_HEADER_SIGNATURE0_ARC_2        (0x01)
>  /* legacy (0x5AEAA55A) */
> +#define MPI26_FW_HEADER_SIGNATURE0_ARC_3        (0x02)
>  #define MPI26_FW_HEADER_SIGNATURE0 \
>  	(MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_0)
>  #define MPI26_FW_HEADER_SIGNATURE0_3516 \
>  	(MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_1)
> +#define MPI26_FW_HEADER_SIGNATURE0_4008 \
> +	(MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_3)
>  
>  /*Signature1 field */
>  #define MPI2_FW_HEADER_SIGNATURE1_OFFSET        (0x08)
> @@ -1541,6 +1855,13 @@ typedef struct _MPI2_FLASH_LAYOUT_DATA {
>  #define MPI2_FLASH_REGION_COMMON_BOOT_BLOCK     (0x0A)
>  #define MPI2_FLASH_REGION_INIT (MPI2_FLASH_REGION_COMMON_BOOT_BLOCK)
>  #define MPI2_FLASH_REGION_CBB_BACKUP            (0x0D)
> +#define MPI2_FLASH_REGION_SBR                   (0x0E)
> +#define MPI2_FLASH_REGION_SBR_BACKUP            (0x0F)
> +#define MPI2_FLASH_REGION_HIIM                  (0x10)
> +#define MPI2_FLASH_REGION_HIIA                  (0x11)
> +#define MPI2_FLASH_REGION_CTLR                  (0x12)
> +#define MPI2_FLASH_REGION_IMR_FIRMWARE          (0x13)
> +#define MPI2_FLASH_REGION_MR_NVDATA             (0x14)
>  
>  /*ImageRevision */
>  #define MPI2_FLASH_LAYOUT_IMAGE_REVISION        (0x00)
> @@ -1825,6 +2146,8 @@ typedef struct _MPI26_IOUNIT_CONTROL_REQUEST {
>  #define MPI26_CTRL_OP_DEV_ENABLE_PERSIST_CONNECTION     (0x17)
>  #define MPI26_CTRL_OP_DEV_DISABLE_PERSIST_CONNECTION    (0x18)
>  #define MPI26_CTRL_OP_DEV_CLOSE_PERSIST_CONNECTION      (0x19)
> +#define MPI26_CTRL_OP_ENABLE_NVME_SGL_FORMAT            (0x1A)
> +#define MPI26_CTRL_OP_DISABLE_NVME_SGL_FORMAT           (0x1B)
>  #define MPI26_CTRL_OP_PRODUCT_SPECIFIC_MIN              (0x80)
>  
>  /* values for the PrimFlags field */
> diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_pci.h b/drivers/scsi/mpt3sas/mpi/mpi2_pci.h
> new file mode 100644
> index 0000000..52ea213
> --- /dev/null
> +++ b/drivers/scsi/mpt3sas/mpi/mpi2_pci.h
> @@ -0,0 +1,142 @@
> +/*
> + * Copyright 2012-2015 Avago Technologies.  All rights reserved.
> + *
> + *
> + *          Name:  mpi2_pci.h
> + *         Title:  MPI PCIe Attached Devices structures and definitions.
> + * Creation Date:  October 9, 2012
> + *
> + * mpi2_pci.h Version:  02.00.02
> + *
> + * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
> + *       prefix are for use only on MPI v2.5 products, and must not be used
> + *       with MPI v2.0 products. Unless otherwise noted, names beginning with
> + *       MPI2 or Mpi2 are for use with both MPI v2.0 and MPI v2.5 products.
> + *
> + * Version History
> + * ---------------
> + *
> + * Date      Version   Description
> + * --------  --------  ------------------------------------------------------
> + * 03-16-15  02.00.00  Initial version.
> + * 02-17-16  02.00.01  Removed AHCI support.
> + *                     Removed SOP support.
> + * 07-01-16  02.00.02  Added MPI26_NVME_FLAGS_FORCE_ADMIN_ERR_RESP to
> + *                     NVME Encapsulated Request.
> + * --------------------------------------------------------------------------
> + */
> +
> +#ifndef MPI2_PCI_H
> +#define MPI2_PCI_H
> +
> +
> +/*
> + *Values for the PCIe DeviceInfo field used in PCIe Device Status Change Event
> + *data and PCIe Configuration pages.
> + */
> +#define MPI26_PCIE_DEVINFO_DIRECT_ATTACH        (0x00000010)
> +
> +#define MPI26_PCIE_DEVINFO_MASK_DEVICE_TYPE     (0x0000000F)
> +#define MPI26_PCIE_DEVINFO_NO_DEVICE            (0x00000000)
> +#define MPI26_PCIE_DEVINFO_PCI_SWITCH           (0x00000001)
> +#define MPI26_PCIE_DEVINFO_NVME                 (0x00000003)
> +
> +
> +/****************************************************************************
> +*  NVMe Encapsulated message
> +****************************************************************************/
> +
> +/*NVME Encapsulated Request Message */
> +typedef struct _MPI26_NVME_ENCAPSULATED_REQUEST {
> +	U16
> +		DevHandle;                      /*0x00 */
> +	U8
> +		ChainOffset;                    /*0x02 */
> +	U8
> +		Function;                       /*0x03 */
> +	U16
> +		EncapsulatedCommandLength;      /*0x04 */
> +	U8
> +		Reserved1;                      /*0x06 */
> +	U8
> +		MsgFlags;                       /*0x07 */
> +	U8
> +		VP_ID;                          /*0x08 */
> +	U8
> +		VF_ID;                          /*0x09 */
> +	U16
> +		Reserved2;                      /*0x0A */
> +	U32
> +		Reserved3;                      /*0x0C */
> +	U64
> +		ErrorResponseBaseAddress;       /*0x10 */
> +	U16
> +		ErrorResponseAllocationLength;  /*0x18 */
> +	U16
> +		Flags;                          /*0x1A */
> +	U32
> +		DataLength;                     /*0x1C */
> +	U8
> +		NVMe_Command[4];                /*0x20 */
> +
> +} MPI26_NVME_ENCAPSULATED_REQUEST, *PTR_MPI26_NVME_ENCAPSULATED_REQUEST,
> +	Mpi26NVMeEncapsulatedRequest_t, *pMpi26NVMeEncapsulatedRequest_t;
> +
> +/*defines for the Flags field */
> +#define MPI26_NVME_FLAGS_FORCE_ADMIN_ERR_RESP       (0x0020)
> +/*Submission Queue Type*/
> +#define MPI26_NVME_FLAGS_SUBMISSIONQ_MASK           (0x0010)
> +#define MPI26_NVME_FLAGS_SUBMISSIONQ_IO             (0x0000)
> +#define MPI26_NVME_FLAGS_SUBMISSIONQ_ADMIN          (0x0010)
> +/*Error Response Address Space */
> +#define MPI26_NVME_FLAGS_MASK_ERROR_RSP_ADDR        (0x000C)
> +#define MPI26_NVME_FLAGS_SYSTEM_RSP_ADDR            (0x0000)
> +#define MPI26_NVME_FLAGS_IOCPLB_RSP_ADDR            (0x0008)
> +#define MPI26_NVME_FLAGS_IOCPLBNTA_RSP_ADDR         (0x000C)
> +/*Data Direction*/
> +#define MPI26_NVME_FLAGS_DATADIRECTION_MASK         (0x0003)
> +#define MPI26_NVME_FLAGS_NODATATRANSFER             (0x0000)
> +#define MPI26_NVME_FLAGS_WRITE                      (0x0001)
> +#define MPI26_NVME_FLAGS_READ                       (0x0002)
> +#define MPI26_NVME_FLAGS_BIDIRECTIONAL              (0x0003)
> +
> +
> +/*NVMe Encapuslated Reply Message */
> +typedef struct _MPI26_NVME_ENCAPSULATED_ERROR_REPLY {
> +	U16
> +		DevHandle;                      /*0x00 */
> +	U8
> +		MsgLength;                      /*0x02 */
> +	U8
> +		Function;                       /*0x03 */
> +	U16
> +		EncapsulatedCommandLength;      /*0x04 */
> +	U8
> +		Reserved1;                      /*0x06 */
> +	U8
> +		MsgFlags;                       /*0x07 */
> +	U8
> +		VP_ID;                          /*0x08 */
> +	U8
> +		VF_ID;                          /*0x09 */
> +	U16
> +		Reserved2;                      /*0x0A */
> +	U16
> +		Reserved3;                      /*0x0C */
> +	U16
> +		IOCStatus;                      /*0x0E */
> +	U32
> +		IOCLogInfo;                     /*0x10 */
> +	U16
> +		ErrorResponseCount;             /*0x14 */
> +	U16
> +		Reserved4;                      /*0x16 */
> +} MPI26_NVME_ENCAPSULATED_ERROR_REPLY,
> +	*PTR_MPI26_NVME_ENCAPSULATED_ERROR_REPLY,
> +	Mpi26NVMeEncapsulatedErrorReply_t,
> +	*pMpi26NVMeEncapsulatedErrorReply_t;
> +
> +
> +#endif
> +
> +
Very odd indentation.
Please reformat to have type and variable on one line.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 02/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe
  2017-07-14 13:22 ` [PATCH v2 02/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe Suganath Prabu S
@ 2017-08-03  6:27   ` Hannes Reinecke
  2017-08-03 10:09     ` Sreekanth Reddy
  0 siblings, 1 reply; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-03  6:27 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
> 1) Added support for probing pcie device and adding NVMe drives to
> SML and driver's internal list pcie_device_list.
> 
> 2) Added support for determing NVMe as boot device.
> 
> 3) Added nvme device support for call back functions scan_finished
> target_alloc,slave_alloc,target destroy and slave destroy.
> 
>  a) During scan, pcie devices are probed and added to SML to drivers
> internal list.
> 
>  b) target_alloc & slave alloc API's allocates resources for
> (MPT3SAS_TARGET & MPT3SAS_DEVICE) private datas and holds
> information like handle, target_id etc.
> 
>  c) slave_destroy & target_destroy are called when driver unregisters
> or removes device. Also frees allocated resources and info.
> 
> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
> ---
>  drivers/scsi/mpt3sas/mpt3sas_base.h  |  110 ++++++++-
>  drivers/scsi/mpt3sas/mpt3sas_scsih.c |  431 +++++++++++++++++++++++++++++++---
>  2 files changed, 507 insertions(+), 34 deletions(-)
> 
Have you considered using 'scan_start()/scan_finished()' SCSI midlayer
callbacks here?
Seeing that you are enumerating the devices internally already that
should give you better control about the scanning process.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 04/13] mpt3sas: Added support for nvme encapsulated request message.
  2017-07-14 13:22 ` [PATCH v2 04/13] mpt3sas: Added support for nvme encapsulated request message Suganath Prabu S
@ 2017-08-03  6:33   ` Hannes Reinecke
  0 siblings, 0 replies; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-03  6:33 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
> * Mpt3sas driver uses the NVMe Encapsulated Request message to
> send an NVMe command to an NVMe device attached to the IOC.
> 
> * Normal I/O commands like reads and writes are passed to the
> controller as SCSI commands and the controller has the ability
> to translate the commands to NVMe equivalent.
> 
> * This encapsulated NVMe command is used by applications to send
> direct NVMe commands to NVMe drives or for handling unmap where
> the translation at controller/firmware level is having
> performance issues.
> 
> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
> ---
>  drivers/scsi/mpt3sas/mpt3sas_base.c |   56 ++++++++++++++++++++++++++++-
>  drivers/scsi/mpt3sas/mpt3sas_base.h |    1 +
>  drivers/scsi/mpt3sas/mpt3sas_ctl.c  |   69 ++++++++++++++++++++++++++++++++---
>  3 files changed, 119 insertions(+), 7 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 05/13] mpt3sas: API 's to support NVMe drive addition to SML
  2017-07-14 13:22 ` [PATCH v2 05/13] mpt3sas: API 's to support NVMe drive addition to SML Suganath Prabu S
@ 2017-08-03  6:35   ` Hannes Reinecke
  0 siblings, 0 replies; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-03  6:35 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
> Below Functions are added in various paths to support NVMe
> drive addition.
> 
> _scsih_pcie_add_device
> _scsih_pcie_device_add
> _scsih_pcie_device_init_add
> _scsih_check_pcie_access_status
> _scsih_pcie_check_device
> 
> mpt3sas_get_pdev_by_handle
> 
> mpt3sas_config_get_pcie_device_pg0
> mpt3sas_config_get_pcie_device_pg2
> 
> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
> ---
>  drivers/scsi/mpt3sas/mpt3sas_base.h   |   10 +
>  drivers/scsi/mpt3sas/mpt3sas_config.c |  100 +++++++
>  drivers/scsi/mpt3sas/mpt3sas_scsih.c  |  473 ++++++++++++++++++++++++++++++++-
>  3 files changed, 575 insertions(+), 8 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 06/13] mpt3sas: API's to remove nvme drive from sml
  2017-07-14 13:22 ` [PATCH v2 06/13] mpt3sas: API's to remove nvme drive from sml Suganath Prabu S
@ 2017-08-03  6:36   ` Hannes Reinecke
  0 siblings, 0 replies; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-03  6:36 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
> Below API's are included in nvme drive remove path.
> _scsih_pcie_device_remove_by_handle
> _scsih_pcie_device_remove_from_sml
> 
> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
> ---
>  drivers/scsi/mpt3sas/mpt3sas_scsih.c |  148 +++++++++++++++++++++++++++++++++-
>  1 files changed, 145 insertions(+), 3 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 07/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware.
  2017-07-14 13:22 ` [PATCH v2 07/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware Suganath Prabu S
@ 2017-08-03  6:38   ` Hannes Reinecke
  0 siblings, 0 replies; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-03  6:38 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
> * The controller firmware sends separate events for NVMe devices and
> PCIe switches similar to existing SAS events.
> 
> * NVMe device detection, addition and removal are reported by the
> firmware through PCIe Topology Change list events.
> 
> * The PCIe device state change events are sent when the firmware
> detects any abnormal conditions with a NVMe device or switch.
> 
> * The enumeration event are sent when the firmware starts PCIe device
> enumeration and stops.
> 
> * This patch has the code change to handle the events and add/remove
> NVMe devices in driver's inventory.
> 
> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
> ---
>  drivers/scsi/mpt3sas/mpt3sas_base.c  |   30 ++-
>  drivers/scsi/mpt3sas/mpt3sas_scsih.c |  471 +++++++++++++++++++++++++++++++++-
>  2 files changed, 495 insertions(+), 6 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 08/13] mpt3sas: Set NVMe device queue depth as 128
  2017-07-14 13:22 ` [PATCH v2 08/13] mpt3sas: Set NVMe device queue depth as 128 Suganath Prabu S
@ 2017-08-03  6:39   ` Hannes Reinecke
  2017-08-03  9:52     ` Sreekanth Reddy
  0 siblings, 1 reply; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-03  6:39 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
> Sets nvme device queue depth, name and displays device capabilities
> 
> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
> ---
>  drivers/scsi/mpt3sas/mpt3sas_base.h  |    2 +-
>  drivers/scsi/mpt3sas/mpt3sas_scsih.c |   40 ++++++++++++++++++++++++++++++++++
>  2 files changed, 41 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
> index 0a8187e..b7855c8 100644
> --- a/drivers/scsi/mpt3sas/mpt3sas_base.h
> +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
> @@ -115,7 +115,7 @@
>  
>  #define MPT3SAS_RAID_MAX_SECTORS	8192
>  #define MPT3SAS_HOST_PAGE_SIZE_4K	12
> -
> +#define MPT3SAS_NVME_QUEUE_DEPTH	128
>  #define MPT_NAME_LENGTH			32	/* generic length of strings */
>  #define MPT_STRING_LENGTH		64
>  
> diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> index 1dd9674..c5a131f 100644
> --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> @@ -2290,6 +2290,7 @@ scsih_slave_configure(struct scsi_device *sdev)
>  	struct MPT3SAS_DEVICE *sas_device_priv_data;
>  	struct MPT3SAS_TARGET *sas_target_priv_data;
>  	struct _sas_device *sas_device;
> +	struct _pcie_device *pcie_device;
>  	struct _raid_device *raid_device;
>  	unsigned long flags;
>  	int qdepth;
> @@ -2420,6 +2421,45 @@ scsih_slave_configure(struct scsi_device *sdev)
>  		}
>  	}
>  
> +	/* PCIe handling */
> +	if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
> +		spin_lock_irqsave(&ioc->pcie_device_lock, flags);
> +		pcie_device = __mpt3sas_get_pdev_by_wwid(ioc,
> +				sas_device_priv_data->sas_target->sas_address);
> +		if (!pcie_device) {
> +			spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
> +			dfailprintk(ioc, pr_warn(MPT3SAS_FMT
> +				"failure at %s:%d/%s()!\n", ioc->name, __FILE__,
> +				__LINE__, __func__));
> +			return 1;
> +		}
> +
> +		/*TODO-right Queue Depth?*/
> +		qdepth = MPT3SAS_NVME_QUEUE_DEPTH;
> +		ds = "NVMe";
> +		/*TODO-Add device name when defined*/
> +		sdev_printk(KERN_INFO, sdev,
> +			"%s: handle(0x%04x), wwid(0x%016llx), port(%d)\n",
> +			ds, handle, (unsigned long long)pcie_device->wwid,
> +			pcie_device->port_num);
> +		if (pcie_device->enclosure_handle != 0)
> +			sdev_printk(KERN_INFO, sdev,
> +			"%s: enclosure logical id(0x%016llx), slot(%d)\n",
> +			ds,
> +			(unsigned long long)pcie_device->enclosure_logical_id,
> +			pcie_device->slot);
> +		if (pcie_device->connector_name[0] != '\0')
> +			sdev_printk(KERN_INFO, sdev,
> +				"%s: enclosure level(0x%04x),"
> +				"connector name( %s)\n", ds,
> +				pcie_device->enclosure_level,
> +				pcie_device->connector_name);
> +		pcie_device_put(pcie_device);
> +		spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
> +		scsih_change_queue_depth(sdev, qdepth);
> +		return 0;
> +	}
> +
>  	spin_lock_irqsave(&ioc->sas_device_lock, flags);
>  	sas_device = __mpt3sas_get_sdev_by_addr(ioc,
>  	   sas_device_priv_data->sas_target->sas_address);
> 
Well; what are these TODOs doing here?
If you know things are not correct, why not doing them correctly?
If you cannot do them correctly, why?

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 09/13] mpt3sas: scan and add nvme device after controller reset
  2017-07-14 13:22 ` [PATCH v2 09/13] mpt3sas: scan and add nvme device after controller reset Suganath Prabu S
@ 2017-08-03  6:40   ` Hannes Reinecke
  2017-08-03 10:19     ` Sreekanth Reddy
  0 siblings, 1 reply; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-03  6:40 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
> After Controller reset, Scan and add nvme device back to the topology.
> 
> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
> ---
>  drivers/scsi/mpt3sas/mpt3sas_scsih.c |  194 +++++++++++++++++++++++++++++++++-
>  1 files changed, 190 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> index c5a131f..e3e803c 100644
> --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> @@ -4869,6 +4869,7 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
>  	char *desc_scsi_state = ioc->tmp_string;
>  	u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
>  	struct _sas_device *sas_device = NULL;
> +	struct _pcie_device *pcie_device = NULL;
>  	struct scsi_target *starget = scmd->device->sdev_target;
>  	struct MPT3SAS_TARGET *priv_target = starget->hostdata;
>  	char *device_str = NULL;
> @@ -5001,6 +5002,28 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
>  	if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
>  		pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
>  		    device_str, (unsigned long long)priv_target->sas_address);
> +	} else if (priv_target->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
> +		pcie_device = mpt3sas_get_pdev_from_target(ioc, priv_target);
> +		if (pcie_device) {
> +			pr_info(MPT3SAS_FMT "\twwid(0x%016llx), port(%d)\n",
> +			    ioc->name,
> +			    (unsigned long long)pcie_device->wwid,
> +			    pcie_device->port_num);
> +			if (pcie_device->enclosure_handle != 0)
> +				pr_info(MPT3SAS_FMT
> +				    "\tenclosure logical id(0x%016llx), "
> +				    "slot(%d)\n", ioc->name,
> +				    (unsigned long long)
> +				    pcie_device->enclosure_logical_id,
> +				    pcie_device->slot);
> +			if (pcie_device->connector_name[0])
> +				pr_info(MPT3SAS_FMT
> +				    "\tenclosure level(0x%04x),"
> +				    "connector name( %s)\n",
> +				    ioc->name, pcie_device->enclosure_level,
> +				    pcie_device->connector_name);
> +			pcie_device_put(pcie_device);
> +		}
>  	} else {
>  		sas_device = mpt3sas_get_sdev_from_target(ioc, priv_target);
>  		if (sas_device) {
> @@ -5047,11 +5070,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
>  		struct sense_info data;
>  		_scsih_normalize_sense(scmd->sense_buffer, &data);
>  		pr_warn(MPT3SAS_FMT
> -			"\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
> -			ioc->name, data.skey,
> -		    data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
> +		  "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
> +		  ioc->name, data.skey,
> +		  data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
>  	}
> -
>  	if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
>  		response_info = le32_to_cpu(mpi_reply->ResponseInfo);
>  		response_bytes = (u8 *)&response_info;
> @@ -8512,6 +8534,130 @@ _scsih_search_responding_sas_devices(struct MPT3SAS_ADAPTER *ioc)
>  }
>  
>  /**
> + * _scsih_mark_responding_pcie_device - mark a pcie_device as responding
> + * @ioc: per adapter object
> + * @pcie_device_pg0: PCIe Device page 0
> + *
> + * After host reset, find out whether devices are still responding.
> + * Used in _scsih_remove_unresponding_devices.
> + *
> + * Return nothing.
> + */
> +static void
> +_scsih_mark_responding_pcie_device(struct MPT3SAS_ADAPTER *ioc,
> +	Mpi26PCIeDevicePage0_t *pcie_device_pg0)
> +{
> +	struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
> +	struct scsi_target *starget;
> +	struct _pcie_device *pcie_device;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&ioc->pcie_device_lock, flags);
> +	list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
> +		if ((pcie_device->wwid == pcie_device_pg0->WWID) &&
> +		    (pcie_device->slot == pcie_device_pg0->Slot)) {
> +			pcie_device->responding = 1;
> +			starget = pcie_device->starget;
> +			if (starget && starget->hostdata) {
> +				sas_target_priv_data = starget->hostdata;
> +				sas_target_priv_data->tm_busy = 0;
> +				sas_target_priv_data->deleted = 0;
> +			} else
> +				sas_target_priv_data = NULL;
> +			if (starget) {
> +				starget_printk(KERN_INFO, starget,
> +				    "handle(0x%04x), wwid(0x%016llx) ",
> +				    pcie_device->handle,
> +				    (unsigned long long)pcie_device->wwid);
> +				if (pcie_device->enclosure_handle != 0)
> +					starget_printk(KERN_INFO, starget,
> +					    "enclosure logical id(0x%016llx), "
> +					    "slot(%d)\n",
> +					    (unsigned long long)
> +					    pcie_device->enclosure_logical_id,
> +					    pcie_device->slot);
> +			}
> +
> +			if (((le32_to_cpu(pcie_device_pg0->Flags)) &
> +			    MPI26_PCIEDEV0_FLAGS_ENCL_LEVEL_VALID) &&
> +			    (ioc->hba_mpi_version_belonged != MPI2_VERSION)) {
> +				pcie_device->enclosure_level =
> +				    pcie_device_pg0->EnclosureLevel;
> +				memcpy(&pcie_device->connector_name[0],
> +				    &pcie_device_pg0->ConnectorName[0], 4);
> +			} else {
> +				pcie_device->enclosure_level = 0;
> +				pcie_device->connector_name[0] = '\0';
> +			}
> +
> +			if (pcie_device->handle == pcie_device_pg0->DevHandle)
> +				goto out;
> +			pr_info(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
> +			    pcie_device->handle);
> +			pcie_device->handle = pcie_device_pg0->DevHandle;
> +			if (sas_target_priv_data)
> +				sas_target_priv_data->handle =
> +				    pcie_device_pg0->DevHandle;
> +			goto out;
> +		}
> +	}
> +
> + out:
> +	spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
> +}
> +
> +/**
> + * _scsih_search_responding_pcie_devices -
> + * @ioc: per adapter object
> + *
> + * After host reset, find out whether devices are still responding.
> + * If not remove.
> + *
> + * Return nothing.
> + */
> +static void
> +_scsih_search_responding_pcie_devices(struct MPT3SAS_ADAPTER *ioc)
> +{
> +	Mpi26PCIeDevicePage0_t pcie_device_pg0;
> +	Mpi2ConfigReply_t mpi_reply;
> +	u16 ioc_status;
> +	u16 handle;
> +	u32 device_info;
> +
> +	pr_info(MPT3SAS_FMT "search for end-devices: start\n", ioc->name);
> +
> +	if (list_empty(&ioc->pcie_device_list))
> +		goto out;
> +
> +	handle = 0xFFFF;
> +	while (!(mpt3sas_config_get_pcie_device_pg0(ioc, &mpi_reply,
> +		&pcie_device_pg0, MPI26_PCIE_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
> +		handle))) {
> +		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
> +		    MPI2_IOCSTATUS_MASK;
> +		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
> +			pr_info(MPT3SAS_FMT "\tbreak from %s: "
> +			    "ioc_status(0x%04x), loginfo(0x%08x)\n", ioc->name,
> +			    __func__, ioc_status,
> +			    le32_to_cpu(mpi_reply.IOCLogInfo));
> +			break;
> +		}
> +		handle = le16_to_cpu(pcie_device_pg0.DevHandle);
> +		device_info = le32_to_cpu(pcie_device_pg0.DeviceInfo);
> +		if (!(_scsih_is_nvme_device(device_info)))
> +			continue;
> +		pcie_device_pg0.WWID = le64_to_cpu(pcie_device_pg0.WWID),
> +		pcie_device_pg0.Slot = le16_to_cpu(pcie_device_pg0.Slot);
> +		pcie_device_pg0.Flags = le32_to_cpu(pcie_device_pg0.Flags);
> +		pcie_device_pg0.DevHandle = handle;
> +		_scsih_mark_responding_pcie_device(ioc, &pcie_device_pg0);
> +	}
> +out:
> +	pr_info(MPT3SAS_FMT "search for PCIe end-devices: complete\n",
> +	    ioc->name);
> +}
> +
> +/**
>   * _scsih_mark_responding_raid_device - mark a raid_device as responding
>   * @ioc: per adapter object
>   * @wwid: world wide identifier for raid volume
> @@ -8863,6 +9009,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
>  {
>  	Mpi2ExpanderPage0_t expander_pg0;
>  	Mpi2SasDevicePage0_t sas_device_pg0;
> +	Mpi26PCIeDevicePage0_t pcie_device_pg0;
>  	Mpi2RaidVolPage1_t volume_pg1;
>  	Mpi2RaidVolPage0_t volume_pg0;
>  	Mpi2RaidPhysDiskPage0_t pd_pg0;
> @@ -8873,6 +9020,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
>  	u16 handle, parent_handle;
>  	u64 sas_address;
>  	struct _sas_device *sas_device;
> +	struct _pcie_device *pcie_device;
>  	struct _sas_node *expander_device;
>  	static struct _raid_device *raid_device;
>  	u8 retry_count;
> @@ -9098,7 +9246,44 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
>  	}
>  	pr_info(MPT3SAS_FMT "\tscan devices: end devices complete\n",
>  	    ioc->name);
> +	pr_info(MPT3SAS_FMT "\tscan devices: pcie end devices start\n",
> +	    ioc->name);
>  
> +	/* pcie devices */
> +	handle = 0xFFFF;
> +	while (!(mpt3sas_config_get_pcie_device_pg0(ioc, &mpi_reply,
> +		&pcie_device_pg0, MPI26_PCIE_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
> +		handle))) {
> +		ioc_status = le16_to_cpu(mpi_reply.IOCStatus)
> +				& MPI2_IOCSTATUS_MASK;
> +		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
> +			pr_info(MPT3SAS_FMT "\tbreak from pcie end device"
> +				" scan: ioc_status(0x%04x), loginfo(0x%08x)\n",
> +				ioc->name, ioc_status,
> +				le32_to_cpu(mpi_reply.IOCLogInfo));
> +			break;
> +		}
> +		handle = le16_to_cpu(pcie_device_pg0.DevHandle);
> +		if (!(_scsih_is_nvme_device(
> +			le32_to_cpu(pcie_device_pg0.DeviceInfo))))
> +			continue;
> +		pcie_device = mpt3sas_get_pdev_by_wwid(ioc,
> +				le64_to_cpu(pcie_device_pg0.WWID));
> +		if (pcie_device) {
> +			pcie_device_put(pcie_device);
> +			continue;
> +		}
> +		retry_count = 0;
> +		parent_handle = le16_to_cpu(pcie_device_pg0.ParentDevHandle);
> +		_scsih_pcie_add_device(ioc, handle);
> +
> +		pr_info(MPT3SAS_FMT "\tAFTER adding pcie end device: "
> +			"handle (0x%04x), wwid(0x%016llx)\n", ioc->name,
> +			handle,
> +			(unsigned long long) le64_to_cpu(pcie_device_pg0.WWID));
> +	}
> +	pr_info(MPT3SAS_FMT "\tpcie devices: pcie end devices complete\n",
> +		ioc->name);
>  	pr_info(MPT3SAS_FMT "scan devices: complete\n", ioc->name);
>  }
>  /**
> @@ -9148,6 +9333,7 @@ mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
>  		    !ioc->sas_hba.num_phys)) {
>  			_scsih_prep_device_scan(ioc);
>  			_scsih_search_responding_sas_devices(ioc);
> +			_scsih_search_responding_pcie_devices(ioc);
>  			_scsih_search_responding_raid_devices(ioc);
>  			_scsih_search_responding_expanders(ioc);
>  			_scsih_error_recovery_delete_devices(ioc);
> 
Again; when using 'scan_start()/scan_finished()' callbacks this will
probably look a bit differently...

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 10/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives.
  2017-07-14 13:22 ` [PATCH v2 10/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives Suganath Prabu S
@ 2017-08-03  6:43   ` Hannes Reinecke
  0 siblings, 0 replies; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-03  6:43 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
> Added debug information for NVMe/PCIe drives in target rest path.
> 
> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
> ---
>  drivers/scsi/mpt3sas/mpt3sas_scsih.c |   83 ++++++++++++++++++++++++++++-----
>  1 files changed, 70 insertions(+), 13 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 11/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info
  2017-07-14 13:22 ` [PATCH v2 11/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info Suganath Prabu S
@ 2017-08-03  6:44   ` Hannes Reinecke
  0 siblings, 0 replies; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-03  6:44 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
> * Added debug prints for pcie devices in ioctl debug path. Which
> will be helpful for debugging.
> * Added PCIe device support for ioctl BTDHMAPPING ioctl.
> 
> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
> ---
>  drivers/scsi/mpt3sas/mpt3sas_ctl.c |   88 +++++++++++++++++++++++------------
>  1 files changed, 58 insertions(+), 30 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 12/13] mpt3sas: Fix nvme drives checking for tlr.
  2017-07-14 13:22 ` [PATCH v2 12/13] mpt3sas: Fix nvme drives checking for tlr Suganath Prabu S
@ 2017-08-03  6:44   ` Hannes Reinecke
  0 siblings, 0 replies; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-03  6:44 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
> Check for NVMe drives before enabling or checking tlr.
> 
> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
> ---
>  drivers/scsi/mpt3sas/mpt3sas_scsih.c |   22 ++++++++++++++++------
>  1 files changed, 16 insertions(+), 6 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 13/13] mpt3sas: Update mpt3sas driver version.
  2017-07-14 13:22 ` [PATCH v2 13/13] mpt3sas: Update mpt3sas driver version Suganath Prabu S
@ 2017-08-03  6:45   ` Hannes Reinecke
  0 siblings, 0 replies; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-03  6:45 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
> Updated mpt3sas driver version to 15.101.00.00
> 
> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
> ---
>  drivers/scsi/mpt3sas/mpt3sas_base.h |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
> index b7855c8..b705199 100644
> --- a/drivers/scsi/mpt3sas/mpt3sas_base.h
> +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
> @@ -74,9 +74,9 @@
>  #define MPT3SAS_DRIVER_NAME		"mpt3sas"
>  #define MPT3SAS_AUTHOR "Avago Technologies <MPT-FusionLinux.pdl@avagotech.com>"
>  #define MPT3SAS_DESCRIPTION	"LSI MPT Fusion SAS 3.0 Device Driver"
> -#define MPT3SAS_DRIVER_VERSION		"15.100.00.00"
> +#define MPT3SAS_DRIVER_VERSION		"15.101.00.00"
>  #define MPT3SAS_MAJOR_VERSION		15
> -#define MPT3SAS_MINOR_VERSION		100
> +#define MPT3SAS_MINOR_VERSION		101
>  #define MPT3SAS_BUILD_VERSION		0
>  #define MPT3SAS_RELEASE_VERSION	00
>  
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
  2017-08-02  8:14 ` Hannes Reinecke
@ 2017-08-03  6:48   ` Hannes Reinecke
  2017-08-05 13:53   ` Christoph Hellwig
  1 sibling, 0 replies; 44+ messages in thread
From: Hannes Reinecke @ 2017-08-03  6:48 UTC (permalink / raw)
  To: Suganath Prabu S, jejb, hch
  Cc: martin.petersen, linux-scsi, Sathya.Prakash, kashyap.desai,
	linux-kernel, chaitra.basappa, sreekanth.reddy, linux-nvme

On 08/02/2017 10:14 AM, Hannes Reinecke wrote:
> On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
>> Ventura Series controller are Tri-mode. The controller and
>> firmware are capable of supporting NVMe devices and
>> PCIe switches to be connected with the controller. This
>> patch set adds driver level support for NVMe devices and
>> PCIe switches.
>>
>> Suganath Prabu S (13):
>>   mpt3sas: Update MPI Header
>>   mpt3sas: Add nvme device support in slave alloc, target alloc and
>>     probe
>>   mpt3sas: SGL to PRP Translation for I/Os to NVMe  devices
>>   mpt3sas: Added support for nvme encapsulated request message.
>>   mpt3sas: API 's to support NVMe drive addition to SML
>>   mpt3sas: API's to remove nvme drive from sml
>>   mpt3sas: Handle NVMe PCIe device related events generated            
>>        from firmware.
>>   mpt3sas: Set NVMe device queue depth as 128
>>   mpt3sas: scan and add nvme device after controller reset
>>   mpt3as: Add-Task-management-debug-info-for-NVMe-drives.
>>   mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log
>>     info
>>   mpt3sas: Fix nvme drives checking for tlr.
>>   mpt3sas: Update mpt3sas driver version.
>>
>>  drivers/scsi/mpt3sas/mpi/mpi2.h          |   43 +-
>>  drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h     |  647 ++++++++++-
>>  drivers/scsi/mpt3sas/mpi/mpi2_init.h     |   11 +-
>>  drivers/scsi/mpt3sas/mpi/mpi2_ioc.h      |  331 ++++++-
>>  drivers/scsi/mpt3sas/mpi/mpi2_pci.h      |  142 +++
>>  drivers/scsi/mpt3sas/mpi/mpi2_tool.h     |   14 +-
>>  drivers/scsi/mpt3sas/mpt3sas_base.c      |  710 +++++++++++-
>>  drivers/scsi/mpt3sas/mpt3sas_base.h      |  171 +++-
>>  drivers/scsi/mpt3sas/mpt3sas_config.c    |  100 ++
>>  drivers/scsi/mpt3sas/mpt3sas_ctl.c       |  158 ++-
>>  drivers/scsi/mpt3sas/mpt3sas_scsih.c     | 1874 ++++++++++++++++++++++++++++--
>>  drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |    2 +-
>>  12 files changed, 4063 insertions(+), 140 deletions(-)
>>  create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h
>>
> I'm not happy with this approach.
> NVMe devices should _not_ appear as SCSI devices; this will just confuse
> matters _and_ will be incompatible with 'normal' NVMe devices.
> 
> Rather I would like to see the driver to hook into the existing NVMe
> framework (which essentially means to treat the mpt3sas as a weird
> NVMe-over-Fabrics HBA), and expose the NVMe devices like any other NVMe HBA.
> 
> I'm sorry that you'll have to redo your patchset (again), but this is
> the only way I see how this patchset can be brought forward.
> 
> I'd be happy to discuss implementation details with you.
> 
After discussion with Broadcom it turns out that the NVMe passthrough
functionality of the current firmware is rather limited and wouldn't be
suitable for full NVMe device support.
And one of the goals is to have intermixed NVMe and SCSI support,
possibly with RAID thrown in for good measure.
So my idea of exposing the NVMe devices directly won't work, and I'll
have to retract my above comment.

But I'll continue to bug Broadcom; maybe we'll be getting NVMe device
support eventually :-)

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 01/13] mpt3sas: Update MPI Header
  2017-08-03  6:24   ` Hannes Reinecke
@ 2017-08-03  7:55     ` Johannes Thumshirn
  2017-08-03  9:34       ` Sreekanth Reddy
  0 siblings, 1 reply; 44+ messages in thread
From: Johannes Thumshirn @ 2017-08-03  7:55 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Suganath Prabu S, jejb, hch, martin.petersen, linux-scsi,
	Sathya.Prakash, kashyap.desai, linux-kernel, chaitra.basappa,
	sreekanth.reddy, linux-nvme

On Thu, Aug 03, 2017 at 08:24:59AM +0200, Hannes Reinecke wrote:
> > +	U32
> > +		IOCLogInfo;                     /*0x10 */
> > +	U16
> > +		ErrorResponseCount;             /*0x14 */
> > +	U16
> > +		Reserved4;                      /*0x16 */
> > +} MPI26_NVME_ENCAPSULATED_ERROR_REPLY,
> > +	*PTR_MPI26_NVME_ENCAPSULATED_ERROR_REPLY,
> > +	Mpi26NVMeEncapsulatedErrorReply_t,
> > +	*pMpi26NVMeEncapsulatedErrorReply_t;
> > +
> > +
> > +#endif
> > +
> > +
> Very odd indentation.
> Please reformat to have type and variable on one line.

And use Linux types and no CamelCase and no typedefs (especially not for
pointers), you're not on Windows here.

Thanks,
	Johannes

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 01/13] mpt3sas: Update MPI Header
  2017-08-03  7:55     ` Johannes Thumshirn
@ 2017-08-03  9:34       ` Sreekanth Reddy
  0 siblings, 0 replies; 44+ messages in thread
From: Sreekanth Reddy @ 2017-08-03  9:34 UTC (permalink / raw)
  To: Johannes Thumshirn
  Cc: Hannes Reinecke, Suganath Prabu S, jejb, Christoph Hellwig,
	Martin K. Petersen, linux-scsi, Sathya Prakash, Kashyap Desai,
	linux-kernel, Chaitra Basappa, linux-nvme

On Thu, Aug 3, 2017 at 1:25 PM, Johannes Thumshirn <jthumshirn@suse.de> wrote:
> On Thu, Aug 03, 2017 at 08:24:59AM +0200, Hannes Reinecke wrote:
>> > +   U32
>> > +           IOCLogInfo;                     /*0x10 */
>> > +   U16
>> > +           ErrorResponseCount;             /*0x14 */
>> > +   U16
>> > +           Reserved4;                      /*0x16 */
>> > +} MPI26_NVME_ENCAPSULATED_ERROR_REPLY,
>> > +   *PTR_MPI26_NVME_ENCAPSULATED_ERROR_REPLY,
>> > +   Mpi26NVMeEncapsulatedErrorReply_t,
>> > +   *pMpi26NVMeEncapsulatedErrorReply_t;
>> > +
>> > +
>> > +#endif
>> > +
>> > +
>> Very odd indentation.
>> Please reformat to have type and variable on one line.
>
> And use Linux types and no CamelCase and no typedefs (especially not for
> pointers), you're not on Windows here.

We will reformat to have type and variable on one line as suggested by Hannes.

But it will be going have a huge change in the driver, if we want to
remove the CamelCase and typedefs. From legacy days onwards mpi
headers has the CamelCase type variable names and the same variables
are used in the code in large number of places. Also our MPI headers
are common across the OS platforms and so maintaining mpi headers
updates will be more difficult.

Thanks,
Sreekanth

>
> Thanks,
>         Johannes
>
> --
> Johannes Thumshirn                                          Storage
> jthumshirn@suse.de                                +49 911 74053 689
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
> Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 08/13] mpt3sas: Set NVMe device queue depth as 128
  2017-08-03  6:39   ` Hannes Reinecke
@ 2017-08-03  9:52     ` Sreekanth Reddy
  0 siblings, 0 replies; 44+ messages in thread
From: Sreekanth Reddy @ 2017-08-03  9:52 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Suganath Prabu S, jejb, Christoph Hellwig, Martin K. Petersen,
	linux-scsi, Sathya Prakash, Kashyap Desai, linux-kernel,
	Chaitra Basappa, linux-nvme

On Thu, Aug 3, 2017 at 12:09 PM, Hannes Reinecke <hare@suse.de> wrote:
> On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
>> Sets nvme device queue depth, name and displays device capabilities
>>
>> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
>> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
>> ---
>>  drivers/scsi/mpt3sas/mpt3sas_base.h  |    2 +-
>>  drivers/scsi/mpt3sas/mpt3sas_scsih.c |   40 ++++++++++++++++++++++++++++++++++
>>  2 files changed, 41 insertions(+), 1 deletions(-)
>>
>> diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
>> index 0a8187e..b7855c8 100644
>> --- a/drivers/scsi/mpt3sas/mpt3sas_base.h
>> +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
>> @@ -115,7 +115,7 @@
>>
>>  #define MPT3SAS_RAID_MAX_SECTORS     8192
>>  #define MPT3SAS_HOST_PAGE_SIZE_4K    12
>> -
>> +#define MPT3SAS_NVME_QUEUE_DEPTH     128
>>  #define MPT_NAME_LENGTH                      32      /* generic length of strings */
>>  #define MPT_STRING_LENGTH            64
>>
>> diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
>> index 1dd9674..c5a131f 100644
>> --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
>> +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
>> @@ -2290,6 +2290,7 @@ scsih_slave_configure(struct scsi_device *sdev)
>>       struct MPT3SAS_DEVICE *sas_device_priv_data;
>>       struct MPT3SAS_TARGET *sas_target_priv_data;
>>       struct _sas_device *sas_device;
>> +     struct _pcie_device *pcie_device;
>>       struct _raid_device *raid_device;
>>       unsigned long flags;
>>       int qdepth;
>> @@ -2420,6 +2421,45 @@ scsih_slave_configure(struct scsi_device *sdev)
>>               }
>>       }
>>
>> +     /* PCIe handling */
>> +     if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
>> +             spin_lock_irqsave(&ioc->pcie_device_lock, flags);
>> +             pcie_device = __mpt3sas_get_pdev_by_wwid(ioc,
>> +                             sas_device_priv_data->sas_target->sas_address);
>> +             if (!pcie_device) {
>> +                     spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
>> +                     dfailprintk(ioc, pr_warn(MPT3SAS_FMT
>> +                             "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
>> +                             __LINE__, __func__));
>> +                     return 1;
>> +             }
>> +
>> +             /*TODO-right Queue Depth?*/
>> +             qdepth = MPT3SAS_NVME_QUEUE_DEPTH;
>> +             ds = "NVMe";
>> +             /*TODO-Add device name when defined*/
>> +             sdev_printk(KERN_INFO, sdev,
>> +                     "%s: handle(0x%04x), wwid(0x%016llx), port(%d)\n",
>> +                     ds, handle, (unsigned long long)pcie_device->wwid,
>> +                     pcie_device->port_num);
>> +             if (pcie_device->enclosure_handle != 0)
>> +                     sdev_printk(KERN_INFO, sdev,
>> +                     "%s: enclosure logical id(0x%016llx), slot(%d)\n",
>> +                     ds,
>> +                     (unsigned long long)pcie_device->enclosure_logical_id,
>> +                     pcie_device->slot);
>> +             if (pcie_device->connector_name[0] != '\0')
>> +                     sdev_printk(KERN_INFO, sdev,
>> +                             "%s: enclosure level(0x%04x),"
>> +                             "connector name( %s)\n", ds,
>> +                             pcie_device->enclosure_level,
>> +                             pcie_device->connector_name);
>> +             pcie_device_put(pcie_device);
>> +             spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
>> +             scsih_change_queue_depth(sdev, qdepth);
>> +             return 0;
>> +     }
>> +
>>       spin_lock_irqsave(&ioc->sas_device_lock, flags);
>>       sas_device = __mpt3sas_get_sdev_by_addr(ioc,
>>          sas_device_priv_data->sas_target->sas_address);
>>
> Well; what are these TODOs doing here?
> If you know things are not correct, why not doing them correctly?
> If you cannot do them correctly, why?

Hannes,

These TODOs comments are added during initial development phase. We
will remove these TODO comments.

Thanks,
Sreekanth

>
> Cheers,
>
> Hannes
> --
> Dr. Hannes Reinecke                Teamlead Storage & Networking
> hare@suse.de                                   +49 911 74053 688
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
> HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 02/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe
  2017-08-03  6:27   ` Hannes Reinecke
@ 2017-08-03 10:09     ` Sreekanth Reddy
  0 siblings, 0 replies; 44+ messages in thread
From: Sreekanth Reddy @ 2017-08-03 10:09 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Suganath Prabu S, jejb, Christoph Hellwig, Martin K. Petersen,
	linux-scsi, Sathya Prakash, Kashyap Desai, linux-kernel,
	Chaitra Basappa, linux-nvme

On Thu, Aug 3, 2017 at 11:57 AM, Hannes Reinecke <hare@suse.de> wrote:
> On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
>> 1) Added support for probing pcie device and adding NVMe drives to
>> SML and driver's internal list pcie_device_list.
>>
>> 2) Added support for determing NVMe as boot device.
>>
>> 3) Added nvme device support for call back functions scan_finished
>> target_alloc,slave_alloc,target destroy and slave destroy.
>>
>>  a) During scan, pcie devices are probed and added to SML to drivers
>> internal list.
>>
>>  b) target_alloc & slave alloc API's allocates resources for
>> (MPT3SAS_TARGET & MPT3SAS_DEVICE) private datas and holds
>> information like handle, target_id etc.
>>
>>  c) slave_destroy & target_destroy are called when driver unregisters
>> or removes device. Also frees allocated resources and info.
>>
>> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
>> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
>> ---
>>  drivers/scsi/mpt3sas/mpt3sas_base.h  |  110 ++++++++-
>>  drivers/scsi/mpt3sas/mpt3sas_scsih.c |  431 +++++++++++++++++++++++++++++++---
>>  2 files changed, 507 insertions(+), 34 deletions(-)
>>
> Have you considered using 'scan_start()/scan_finished()' SCSI midlayer
> callbacks here?
> Seeing that you are enumerating the devices internally already that
> should give you better control about the scanning process.

Yes mpt3sas driver has defined scan_start() & scan_finished()
callbacks function. In the scan_start() callback function driver will
issue Port Enable request to the HBA Firmware to enable the HBA ports,
so the driver can start receiving drives (SAS/SATA/NVMe) discovery
events from firmware and add the discovered drives to the respective
drive type list. (e.g. SAS & SATA drives are added sas_device_list and
NVMe drives are added to pcie_device_list) . Once the driver receives
the Port Enable completion reply message from firmware then in the
scan_finished() callback function driver will register the SAS & SATA
devices added in the sas_device_list to SCSI Transport Layer by using
sas_rphy_add() API and NVMe devices added in the pcie_device_list are
directly added to SML by using scsi_add_device() API with channel
number set to two.

Thanks,
Sreekanth
>
> Cheers,
>
> Hannes
> --
> Dr. Hannes Reinecke                Teamlead Storage & Networking
> hare@suse.de                                   +49 911 74053 688
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
> HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 09/13] mpt3sas: scan and add nvme device after controller reset
  2017-08-03  6:40   ` Hannes Reinecke
@ 2017-08-03 10:19     ` Sreekanth Reddy
  0 siblings, 0 replies; 44+ messages in thread
From: Sreekanth Reddy @ 2017-08-03 10:19 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Suganath Prabu S, jejb, Christoph Hellwig, Martin K. Petersen,
	linux-scsi, Sathya Prakash, Kashyap Desai, linux-kernel,
	Chaitra Basappa, linux-nvme

On Thu, Aug 3, 2017 at 12:10 PM, Hannes Reinecke <hare@suse.de> wrote:
> On 07/14/2017 03:22 PM, Suganath Prabu S wrote:
>> After Controller reset, Scan and add nvme device back to the topology.
>>
>> Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
>> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
>> ---
>>  drivers/scsi/mpt3sas/mpt3sas_scsih.c |  194 +++++++++++++++++++++++++++++++++-
>>  1 files changed, 190 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
>> index c5a131f..e3e803c 100644
>> --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
>> +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
>> @@ -4869,6 +4869,7 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
>>       char *desc_scsi_state = ioc->tmp_string;
>>       u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
>>       struct _sas_device *sas_device = NULL;
>> +     struct _pcie_device *pcie_device = NULL;
>>       struct scsi_target *starget = scmd->device->sdev_target;
>>       struct MPT3SAS_TARGET *priv_target = starget->hostdata;
>>       char *device_str = NULL;
>> @@ -5001,6 +5002,28 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
>>       if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
>>               pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
>>                   device_str, (unsigned long long)priv_target->sas_address);
>> +     } else if (priv_target->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
>> +             pcie_device = mpt3sas_get_pdev_from_target(ioc, priv_target);
>> +             if (pcie_device) {
>> +                     pr_info(MPT3SAS_FMT "\twwid(0x%016llx), port(%d)\n",
>> +                         ioc->name,
>> +                         (unsigned long long)pcie_device->wwid,
>> +                         pcie_device->port_num);
>> +                     if (pcie_device->enclosure_handle != 0)
>> +                             pr_info(MPT3SAS_FMT
>> +                                 "\tenclosure logical id(0x%016llx), "
>> +                                 "slot(%d)\n", ioc->name,
>> +                                 (unsigned long long)
>> +                                 pcie_device->enclosure_logical_id,
>> +                                 pcie_device->slot);
>> +                     if (pcie_device->connector_name[0])
>> +                             pr_info(MPT3SAS_FMT
>> +                                 "\tenclosure level(0x%04x),"
>> +                                 "connector name( %s)\n",
>> +                                 ioc->name, pcie_device->enclosure_level,
>> +                                 pcie_device->connector_name);
>> +                     pcie_device_put(pcie_device);
>> +             }
>>       } else {
>>               sas_device = mpt3sas_get_sdev_from_target(ioc, priv_target);
>>               if (sas_device) {
>> @@ -5047,11 +5070,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
>>               struct sense_info data;
>>               _scsih_normalize_sense(scmd->sense_buffer, &data);
>>               pr_warn(MPT3SAS_FMT
>> -                     "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
>> -                     ioc->name, data.skey,
>> -                 data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
>> +               "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
>> +               ioc->name, data.skey,
>> +               data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
>>       }
>> -
>>       if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
>>               response_info = le32_to_cpu(mpi_reply->ResponseInfo);
>>               response_bytes = (u8 *)&response_info;
>> @@ -8512,6 +8534,130 @@ _scsih_search_responding_sas_devices(struct MPT3SAS_ADAPTER *ioc)
>>  }
>>
>>  /**
>> + * _scsih_mark_responding_pcie_device - mark a pcie_device as responding
>> + * @ioc: per adapter object
>> + * @pcie_device_pg0: PCIe Device page 0
>> + *
>> + * After host reset, find out whether devices are still responding.
>> + * Used in _scsih_remove_unresponding_devices.
>> + *
>> + * Return nothing.
>> + */
>> +static void
>> +_scsih_mark_responding_pcie_device(struct MPT3SAS_ADAPTER *ioc,
>> +     Mpi26PCIeDevicePage0_t *pcie_device_pg0)
>> +{
>> +     struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
>> +     struct scsi_target *starget;
>> +     struct _pcie_device *pcie_device;
>> +     unsigned long flags;
>> +
>> +     spin_lock_irqsave(&ioc->pcie_device_lock, flags);
>> +     list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
>> +             if ((pcie_device->wwid == pcie_device_pg0->WWID) &&
>> +                 (pcie_device->slot == pcie_device_pg0->Slot)) {
>> +                     pcie_device->responding = 1;
>> +                     starget = pcie_device->starget;
>> +                     if (starget && starget->hostdata) {
>> +                             sas_target_priv_data = starget->hostdata;
>> +                             sas_target_priv_data->tm_busy = 0;
>> +                             sas_target_priv_data->deleted = 0;
>> +                     } else
>> +                             sas_target_priv_data = NULL;
>> +                     if (starget) {
>> +                             starget_printk(KERN_INFO, starget,
>> +                                 "handle(0x%04x), wwid(0x%016llx) ",
>> +                                 pcie_device->handle,
>> +                                 (unsigned long long)pcie_device->wwid);
>> +                             if (pcie_device->enclosure_handle != 0)
>> +                                     starget_printk(KERN_INFO, starget,
>> +                                         "enclosure logical id(0x%016llx), "
>> +                                         "slot(%d)\n",
>> +                                         (unsigned long long)
>> +                                         pcie_device->enclosure_logical_id,
>> +                                         pcie_device->slot);
>> +                     }
>> +
>> +                     if (((le32_to_cpu(pcie_device_pg0->Flags)) &
>> +                         MPI26_PCIEDEV0_FLAGS_ENCL_LEVEL_VALID) &&
>> +                         (ioc->hba_mpi_version_belonged != MPI2_VERSION)) {
>> +                             pcie_device->enclosure_level =
>> +                                 pcie_device_pg0->EnclosureLevel;
>> +                             memcpy(&pcie_device->connector_name[0],
>> +                                 &pcie_device_pg0->ConnectorName[0], 4);
>> +                     } else {
>> +                             pcie_device->enclosure_level = 0;
>> +                             pcie_device->connector_name[0] = '\0';
>> +                     }
>> +
>> +                     if (pcie_device->handle == pcie_device_pg0->DevHandle)
>> +                             goto out;
>> +                     pr_info(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
>> +                         pcie_device->handle);
>> +                     pcie_device->handle = pcie_device_pg0->DevHandle;
>> +                     if (sas_target_priv_data)
>> +                             sas_target_priv_data->handle =
>> +                                 pcie_device_pg0->DevHandle;
>> +                     goto out;
>> +             }
>> +     }
>> +
>> + out:
>> +     spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
>> +}
>> +
>> +/**
>> + * _scsih_search_responding_pcie_devices -
>> + * @ioc: per adapter object
>> + *
>> + * After host reset, find out whether devices are still responding.
>> + * If not remove.
>> + *
>> + * Return nothing.
>> + */
>> +static void
>> +_scsih_search_responding_pcie_devices(struct MPT3SAS_ADAPTER *ioc)
>> +{
>> +     Mpi26PCIeDevicePage0_t pcie_device_pg0;
>> +     Mpi2ConfigReply_t mpi_reply;
>> +     u16 ioc_status;
>> +     u16 handle;
>> +     u32 device_info;
>> +
>> +     pr_info(MPT3SAS_FMT "search for end-devices: start\n", ioc->name);
>> +
>> +     if (list_empty(&ioc->pcie_device_list))
>> +             goto out;
>> +
>> +     handle = 0xFFFF;
>> +     while (!(mpt3sas_config_get_pcie_device_pg0(ioc, &mpi_reply,
>> +             &pcie_device_pg0, MPI26_PCIE_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
>> +             handle))) {
>> +             ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
>> +                 MPI2_IOCSTATUS_MASK;
>> +             if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
>> +                     pr_info(MPT3SAS_FMT "\tbreak from %s: "
>> +                         "ioc_status(0x%04x), loginfo(0x%08x)\n", ioc->name,
>> +                         __func__, ioc_status,
>> +                         le32_to_cpu(mpi_reply.IOCLogInfo));
>> +                     break;
>> +             }
>> +             handle = le16_to_cpu(pcie_device_pg0.DevHandle);
>> +             device_info = le32_to_cpu(pcie_device_pg0.DeviceInfo);
>> +             if (!(_scsih_is_nvme_device(device_info)))
>> +                     continue;
>> +             pcie_device_pg0.WWID = le64_to_cpu(pcie_device_pg0.WWID),
>> +             pcie_device_pg0.Slot = le16_to_cpu(pcie_device_pg0.Slot);
>> +             pcie_device_pg0.Flags = le32_to_cpu(pcie_device_pg0.Flags);
>> +             pcie_device_pg0.DevHandle = handle;
>> +             _scsih_mark_responding_pcie_device(ioc, &pcie_device_pg0);
>> +     }
>> +out:
>> +     pr_info(MPT3SAS_FMT "search for PCIe end-devices: complete\n",
>> +         ioc->name);
>> +}
>> +
>> +/**
>>   * _scsih_mark_responding_raid_device - mark a raid_device as responding
>>   * @ioc: per adapter object
>>   * @wwid: world wide identifier for raid volume
>> @@ -8863,6 +9009,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
>>  {
>>       Mpi2ExpanderPage0_t expander_pg0;
>>       Mpi2SasDevicePage0_t sas_device_pg0;
>> +     Mpi26PCIeDevicePage0_t pcie_device_pg0;
>>       Mpi2RaidVolPage1_t volume_pg1;
>>       Mpi2RaidVolPage0_t volume_pg0;
>>       Mpi2RaidPhysDiskPage0_t pd_pg0;
>> @@ -8873,6 +9020,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
>>       u16 handle, parent_handle;
>>       u64 sas_address;
>>       struct _sas_device *sas_device;
>> +     struct _pcie_device *pcie_device;
>>       struct _sas_node *expander_device;
>>       static struct _raid_device *raid_device;
>>       u8 retry_count;
>> @@ -9098,7 +9246,44 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
>>       }
>>       pr_info(MPT3SAS_FMT "\tscan devices: end devices complete\n",
>>           ioc->name);
>> +     pr_info(MPT3SAS_FMT "\tscan devices: pcie end devices start\n",
>> +         ioc->name);
>>
>> +     /* pcie devices */
>> +     handle = 0xFFFF;
>> +     while (!(mpt3sas_config_get_pcie_device_pg0(ioc, &mpi_reply,
>> +             &pcie_device_pg0, MPI26_PCIE_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
>> +             handle))) {
>> +             ioc_status = le16_to_cpu(mpi_reply.IOCStatus)
>> +                             & MPI2_IOCSTATUS_MASK;
>> +             if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
>> +                     pr_info(MPT3SAS_FMT "\tbreak from pcie end device"
>> +                             " scan: ioc_status(0x%04x), loginfo(0x%08x)\n",
>> +                             ioc->name, ioc_status,
>> +                             le32_to_cpu(mpi_reply.IOCLogInfo));
>> +                     break;
>> +             }
>> +             handle = le16_to_cpu(pcie_device_pg0.DevHandle);
>> +             if (!(_scsih_is_nvme_device(
>> +                     le32_to_cpu(pcie_device_pg0.DeviceInfo))))
>> +                     continue;
>> +             pcie_device = mpt3sas_get_pdev_by_wwid(ioc,
>> +                             le64_to_cpu(pcie_device_pg0.WWID));
>> +             if (pcie_device) {
>> +                     pcie_device_put(pcie_device);
>> +                     continue;
>> +             }
>> +             retry_count = 0;
>> +             parent_handle = le16_to_cpu(pcie_device_pg0.ParentDevHandle);
>> +             _scsih_pcie_add_device(ioc, handle);
>> +
>> +             pr_info(MPT3SAS_FMT "\tAFTER adding pcie end device: "
>> +                     "handle (0x%04x), wwid(0x%016llx)\n", ioc->name,
>> +                     handle,
>> +                     (unsigned long long) le64_to_cpu(pcie_device_pg0.WWID));
>> +     }
>> +     pr_info(MPT3SAS_FMT "\tpcie devices: pcie end devices complete\n",
>> +             ioc->name);
>>       pr_info(MPT3SAS_FMT "scan devices: complete\n", ioc->name);
>>  }
>>  /**
>> @@ -9148,6 +9333,7 @@ mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
>>                   !ioc->sas_hba.num_phys)) {
>>                       _scsih_prep_device_scan(ioc);
>>                       _scsih_search_responding_sas_devices(ioc);
>> +                     _scsih_search_responding_pcie_devices(ioc);
>>                       _scsih_search_responding_raid_devices(ioc);
>>                       _scsih_search_responding_expanders(ioc);
>>                       _scsih_error_recovery_delete_devices(ioc);
>>
> Again; when using 'scan_start()/scan_finished()' callbacks this will
> probably look a bit differently...

During controller reset, mpt3sas driver won't call scsi_scan_host()
API. Our driver internally determines whether drives (which are
attached to the HBA before HBA reset) are still responding or not. If
the drives are not responding (e.g. if someone pulls out the drive
during HBA reset) then it will un-register the UN-responding drive
from the SML after the HBA reset operation.

Thanks,
Sreekanth

>
> Cheers,
>
> Hannes
> --
> Dr. Hannes Reinecke                Teamlead Storage & Networking
> hare@suse.de                                   +49 911 74053 688
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
> HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
  2017-08-02  8:14 ` Hannes Reinecke
  2017-08-03  6:48   ` Hannes Reinecke
@ 2017-08-05 13:53   ` Christoph Hellwig
  2017-08-05 14:42     ` James Bottomley
  1 sibling, 1 reply; 44+ messages in thread
From: Christoph Hellwig @ 2017-08-05 13:53 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Suganath Prabu S, jejb, hch, martin.petersen, linux-scsi,
	Sathya.Prakash, kashyap.desai, linux-kernel, chaitra.basappa,
	sreekanth.reddy, linux-nvme

On Wed, Aug 02, 2017 at 10:14:40AM +0200, Hannes Reinecke wrote:
> I'm not happy with this approach.
> NVMe devices should _not_ appear as SCSI devices; this will just confuse
> matters _and_ will be incompatible with 'normal' NVMe devices.
> 
> Rather I would like to see the driver to hook into the existing NVMe
> framework (which essentially means to treat the mpt3sas as a weird
> NVMe-over-Fabrics HBA), and expose the NVMe devices like any other NVMe HBA.

That doesn't make any sense.  The devices behind the mpt adapter don't
look like NVMe devices at all for the hosts - there are no NVMe commands
or queues involved at all, they hide behind the same somewhat leaky
scsi abstraction as other devices behind the mpt controller.

The only additional leak is that the controller now supports NVMe-like
PRPs in additions to its existing two SGL formats.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
  2017-08-05 13:53   ` Christoph Hellwig
@ 2017-08-05 14:42     ` James Bottomley
  2017-08-07 13:56       ` Kashyap Desai
  0 siblings, 1 reply; 44+ messages in thread
From: James Bottomley @ 2017-08-05 14:42 UTC (permalink / raw)
  To: Christoph Hellwig, Hannes Reinecke
  Cc: Suganath Prabu S, martin.petersen, linux-scsi, Sathya.Prakash,
	kashyap.desai, linux-kernel, chaitra.basappa, sreekanth.reddy,
	linux-nvme

On Sat, 2017-08-05 at 06:53 -0700, Christoph Hellwig wrote:
> On Wed, Aug 02, 2017 at 10:14:40AM +0200, Hannes Reinecke wrote:
> > 
> > I'm not happy with this approach.
> > NVMe devices should _not_ appear as SCSI devices; this will just
> > confuse matters _and_ will be incompatible with 'normal' NVMe
> > devices.
> > 
> > Rather I would like to see the driver to hook into the existing
> > NVMe framework (which essentially means to treat the mpt3sas as a
> > weird NVMe-over-Fabrics HBA), and expose the NVMe devices like any
> > other NVMe HBA.
> 
> That doesn't make any sense.  The devices behind the mpt adapter
> don't look like NVMe devices at all for the hosts - there are no NVMe
> commands or queues involved at all, they hide behind the same
> somewhat leaky scsi abstraction as other devices behind the mpt
> controller.

You might think about what we did for SAS: split the generic handler
into two pieces, libsas for driving the devices, which mpt didn't need
because of the fat firmware and the SAS transport class so mpt could at
least show the same sysfs files as everything else for SAS devices.

Fortunately for NVMe it's very simple at the moment its just a couple
of host files and wwid on the devices.

James


> The only additional leak is that the controller now supports NVMe-
> like PRPs in additions to its existing two SGL formats.
> 

^ permalink raw reply	[flat|nested] 44+ messages in thread

* RE: [PATCH v2 00/13] mpt3sas driver NVMe support:
  2017-08-05 14:42     ` James Bottomley
@ 2017-08-07 13:56       ` Kashyap Desai
  2017-08-07 14:18         ` James Bottomley
  0 siblings, 1 reply; 44+ messages in thread
From: Kashyap Desai @ 2017-08-07 13:56 UTC (permalink / raw)
  To: James Bottomley, Christoph Hellwig, Hannes Reinecke
  Cc: Suganath Prabu Subramani, martin.petersen, linux-scsi,
	Sathya Prakash Veerichetty, linux-kernel, Chaitra Basappa,
	Sreekanth Reddy, linux-nvme

> -----Original Message-----
> From: James Bottomley [mailto:James.Bottomley@HansenPartnership.com]
> Sent: Saturday, August 05, 2017 8:12 PM
> To: Christoph Hellwig; Hannes Reinecke
> Cc: Suganath Prabu S; martin.petersen@oracle.com; linux-
> scsi@vger.kernel.org; Sathya.Prakash@broadcom.com;
> kashyap.desai@broadcom.com; linux-kernel@vger.kernel.org;
> chaitra.basappa@broadcom.com; sreekanth.reddy@broadcom.com; linux-
> nvme@lists.infradead.org
> Subject: Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
>
> On Sat, 2017-08-05 at 06:53 -0700, Christoph Hellwig wrote:
> > On Wed, Aug 02, 2017 at 10:14:40AM +0200, Hannes Reinecke wrote:
> > >
> > > I'm not happy with this approach.
> > > NVMe devices should _not_ appear as SCSI devices; this will just
> > > confuse matters _and_ will be incompatible with 'normal' NVMe
> > > devices.
> > >
> > > Rather I would like to see the driver to hook into the existing NVMe
> > > framework (which essentially means to treat the mpt3sas as a weird
> > > NVMe-over-Fabrics HBA), and expose the NVMe devices like any other
> > > NVMe HBA.
> >
> > That doesn't make any sense.  The devices behind the mpt adapter don't
> > look like NVMe devices at all for the hosts - there are no NVMe
> > commands or queues involved at all, they hide behind the same somewhat
> > leaky scsi abstraction as other devices behind the mpt controller.
>
> You might think about what we did for SAS: split the generic handler into
> two
> pieces, libsas for driving the devices, which mpt didn't need because of
> the fat
> firmware and the SAS transport class so mpt could at least show the same
> sysfs
> files as everything else for SAS devices.

 Ventura generation of controllers are adding connectivity of NVME
 drives seamlessly and protocol handling is in Firmware.
 Same as SCSI to ATA translation done in firmware, Ventura controller
 is doing SCSI to NVME translation and for end user protocol handling
 is abstracted.

 This product handles new Transport protocol (NVME) same as ATA and
 transport is abstracted for end user.

NVME pass-through related driver code, it is just a big tunnel for user
space application.
It is just a basic framework like SATA PASS-Through in existing mpt3sas
driver.

>
> Fortunately for NVMe it's very simple at the moment its just a couple of
> host
> files and wwid on the devices.
>
> James
>
>
> > The only additional leak is that the controller now supports NVMe-
> > like PRPs in additions to its existing two SGL formats.
> >

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
  2017-08-07 13:56       ` Kashyap Desai
@ 2017-08-07 14:18         ` James Bottomley
  2017-08-07 14:31           ` Kashyap Desai
  0 siblings, 1 reply; 44+ messages in thread
From: James Bottomley @ 2017-08-07 14:18 UTC (permalink / raw)
  To: Kashyap Desai, Christoph Hellwig, Hannes Reinecke
  Cc: Suganath Prabu Subramani, martin.petersen, linux-scsi,
	Sathya Prakash Veerichetty, linux-kernel, Chaitra Basappa,
	Sreekanth Reddy, linux-nvme

On Mon, 2017-08-07 at 19:26 +0530, Kashyap Desai wrote:
> > 
> > -----Original Message-----
> > From: James Bottomley [mailto:James.Bottomley@HansenPartnership.com
> > ]
> > Sent: Saturday, August 05, 2017 8:12 PM
> > To: Christoph Hellwig; Hannes Reinecke
> > Cc: Suganath Prabu S; martin.petersen@oracle.com; linux-
> > scsi@vger.kernel.org; Sathya.Prakash@broadcom.com;
> > kashyap.desai@broadcom.com; linux-kernel@vger.kernel.org;
> > chaitra.basappa@broadcom.com; sreekanth.reddy@broadcom.com; linux-
> > nvme@lists.infradead.org
> > Subject: Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
> > 
> > On Sat, 2017-08-05 at 06:53 -0700, Christoph Hellwig wrote:
> > > 
> > > On Wed, Aug 02, 2017 at 10:14:40AM +0200, Hannes Reinecke wrote:
> > > > 
> > > > 
> > > > I'm not happy with this approach.
> > > > NVMe devices should _not_ appear as SCSI devices; this will
> > > > just
> > > > confuse matters _and_ will be incompatible with 'normal' NVMe
> > > > devices.
> > > > 
> > > > Rather I would like to see the driver to hook into the existing
> > > > NVMe
> > > > framework (which essentially means to treat the mpt3sas as a
> > > > weird
> > > > NVMe-over-Fabrics HBA), and expose the NVMe devices like any
> > > > other
> > > > NVMe HBA.
> > > 
> > > That doesn't make any sense.  The devices behind the mpt adapter
> > > don't
> > > look like NVMe devices at all for the hosts - there are no NVMe
> > > commands or queues involved at all, they hide behind the same
> > > somewhat
> > > leaky scsi abstraction as other devices behind the mpt
> > > controller.
> > 
> > You might think about what we did for SAS: split the generic
> > handler into
> > two
> > pieces, libsas for driving the devices, which mpt didn't need
> > because of
> > the fat
> > firmware and the SAS transport class so mpt could at least show the
> > same
> > sysfs
> > files as everything else for SAS devices.
> 
>  Ventura generation of controllers are adding connectivity of NVME
>  drives seamlessly and protocol handling is in Firmware.
>  Same as SCSI to ATA translation done in firmware, Ventura controller
>  is doing SCSI to NVME translation and for end user protocol handling
>  is abstracted.
> 
>  This product handles new Transport protocol (NVME) same as ATA and
>  transport is abstracted for end user.
> 
> NVME pass-through related driver code, it is just a big tunnel for
> user space application. It is just a basic framework like SATA PASS-
> Through in existing mpt3sas driver.

I know how it works ... and I'm on record as not liking your SATL
approach because we keep tripping across bugs in the SATL that we have
to fix in the driver.

However, at least for bot SAS and SATA they appear to the system as
SCSI devices regardless of HBA, so we've largely smoothed over any
problems if you transfer from mp3sas to another SAS/SATA controller.

I believe your current proposal is to have NVMe devices appear as SCSI,
which isn't how the native NVMe driver handles them at all.  This is
going to have to be special cased in any tool designed to handle nvme
devices and it's going to cause big problems if someone changes
controller (or moves the device).  What's the proposal for making this
as painless as possible?

James

^ permalink raw reply	[flat|nested] 44+ messages in thread

* RE: [PATCH v2 00/13] mpt3sas driver NVMe support:
  2017-08-07 14:18         ` James Bottomley
@ 2017-08-07 14:31           ` Kashyap Desai
  2017-08-07 15:45             ` James Bottomley
  0 siblings, 1 reply; 44+ messages in thread
From: Kashyap Desai @ 2017-08-07 14:31 UTC (permalink / raw)
  To: James Bottomley, Christoph Hellwig, Hannes Reinecke
  Cc: Suganath Prabu Subramani, martin.petersen, linux-scsi,
	Sathya Prakash Veerichetty, linux-kernel, Chaitra Basappa,
	Sreekanth Reddy, linux-nvme

> -----Original Message-----
> From: James Bottomley [mailto:James.Bottomley@HansenPartnership.com]
> Sent: Monday, August 07, 2017 7:48 PM
> To: Kashyap Desai; Christoph Hellwig; Hannes Reinecke
> Cc: Suganath Prabu Subramani; martin.petersen@oracle.com; linux-
> scsi@vger.kernel.org; Sathya Prakash Veerichetty; linux-
> kernel@vger.kernel.org; Chaitra Basappa; Sreekanth Reddy; linux-
> nvme@lists.infradead.org
> Subject: Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
>
> On Mon, 2017-08-07 at 19:26 +0530, Kashyap Desai wrote:
> > >
> > > -----Original Message-----
> > > From: James Bottomley [mailto:James.Bottomley@HansenPartnership.com
> > > ]
> > > Sent: Saturday, August 05, 2017 8:12 PM
> > > To: Christoph Hellwig; Hannes Reinecke
> > > Cc: Suganath Prabu S; martin.petersen@oracle.com; linux-
> > > scsi@vger.kernel.org; Sathya.Prakash@broadcom.com;
> > > kashyap.desai@broadcom.com; linux-kernel@vger.kernel.org;
> > > chaitra.basappa@broadcom.com; sreekanth.reddy@broadcom.com; linux-
> > > nvme@lists.infradead.org
> > > Subject: Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
> > >
> > > On Sat, 2017-08-05 at 06:53 -0700, Christoph Hellwig wrote:
> > > >
> > > > On Wed, Aug 02, 2017 at 10:14:40AM +0200, Hannes Reinecke wrote:
> > > > >
> > > > >
> > > > > I'm not happy with this approach.
> > > > > NVMe devices should _not_ appear as SCSI devices; this will just
> > > > > confuse matters _and_ will be incompatible with 'normal' NVMe
> > > > > devices.
> > > > >
> > > > > Rather I would like to see the driver to hook into the existing
> > > > > NVMe framework (which essentially means to treat the mpt3sas as
> > > > > a weird NVMe-over-Fabrics HBA), and expose the NVMe devices like
> > > > > any other NVMe HBA.
> > > >
> > > > That doesn't make any sense.  The devices behind the mpt adapter
> > > > don't look like NVMe devices at all for the hosts - there are no
> > > > NVMe commands or queues involved at all, they hide behind the same
> > > > somewhat leaky scsi abstraction as other devices behind the mpt
> > > > controller.
> > >
> > > You might think about what we did for SAS: split the generic handler
> > > into two pieces, libsas for driving the devices, which mpt didn't
> > > need because of the fat firmware and the SAS transport class so mpt
> > > could at least show the same sysfs files as everything else for SAS
> > > devices.
> >
> >  Ventura generation of controllers are adding connectivity of NVME
> >  drives seamlessly and protocol handling is in Firmware.
> >  Same as SCSI to ATA translation done in firmware, Ventura controller
> >  is doing SCSI to NVME translation and for end user protocol handling
> >  is abstracted.
> >
> >  This product handles new Transport protocol (NVME) same as ATA and
> >  transport is abstracted for end user.
> >
> > NVME pass-through related driver code, it is just a big tunnel for
> > user space application. It is just a basic framework like SATA PASS-
> > Through in existing mpt3sas driver.
>
> I know how it works ... and I'm on record as not liking your SATL approach
> because we keep tripping across bugs in the SATL that we have to fix in
> the
> driver.

We discussed about NVME device support behind <mpt3sas> to Hannes and
he suggested to describe to product behavior to wider audience to be aware.
Just wanted to share the notes.

>
> However, at least for bot SAS and SATA they appear to the system as SCSI
> devices regardless of HBA, so we've largely smoothed over any problems if
> you
> transfer from mp3sas to another SAS/SATA controller.
>
> I believe your current proposal is to have NVMe devices appear as SCSI,
> which
> isn't how the native NVMe driver handles them at all.  This is going to
> have to
> be special cased in any tool designed to handle nvme devices and it's
> going to
> cause big problems if someone changes controller (or moves the
> device).  What's the proposal for making this as painless as possible?

We have to attempt this use case and see how it behaves. I have not tried
this, so not sure if things are really bad or just some tuning may be
helpful. I will revert back to you on this.

I understood request as -  We need some udev rules to be working well for
*same* NVME drives if it is behind <mpt3sas> or native <nvme>.
Example - If user has OS installed on NVME drive which is behind <mpt3sas>
driver as SCSI disk should be able to boot if he/she hooked same NVME drive
which is detected by native <nvme> driver (and vice versa.)

>
> James

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
  2017-08-07 14:31           ` Kashyap Desai
@ 2017-08-07 15:45             ` James Bottomley
  2017-08-08  4:04               ` Keith Busch
  0 siblings, 1 reply; 44+ messages in thread
From: James Bottomley @ 2017-08-07 15:45 UTC (permalink / raw)
  To: Kashyap Desai, Christoph Hellwig, Hannes Reinecke
  Cc: Suganath Prabu Subramani, martin.petersen, linux-scsi,
	Sathya Prakash Veerichetty, linux-kernel, Chaitra Basappa,
	Sreekanth Reddy, linux-nvme

On Mon, 2017-08-07 at 20:01 +0530, Kashyap Desai wrote:
> > 
> > -----Original Message-----
> > From: James Bottomley [mailto:James.Bottomley@HansenPartnership.com
> > ]
> > Sent: Monday, August 07, 2017 7:48 PM
> > To: Kashyap Desai; Christoph Hellwig; Hannes Reinecke
> > Cc: Suganath Prabu Subramani; martin.petersen@oracle.com; linux-
> > scsi@vger.kernel.org; Sathya Prakash Veerichetty; linux-
> > kernel@vger.kernel.org; Chaitra Basappa; Sreekanth Reddy; linux-
> > nvme@lists.infradead.org
> > Subject: Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
> > 
> > On Mon, 2017-08-07 at 19:26 +0530, Kashyap Desai wrote:
> > > 
> > > > 
> > > > 
> > > > -----Original Message-----
> > > > From: James Bottomley [mailto:James.Bottomley@HansenPartnership
> > > > .com
> > > > ]
> > > > Sent: Saturday, August 05, 2017 8:12 PM
> > > > To: Christoph Hellwig; Hannes Reinecke
> > > > Cc: Suganath Prabu S; martin.petersen@oracle.com; linux-
> > > > scsi@vger.kernel.org; Sathya.Prakash@broadcom.com;
> > > > kashyap.desai@broadcom.com; linux-kernel@vger.kernel.org;
> > > > chaitra.basappa@broadcom.com; sreekanth.reddy@broadcom.com;
> > > > linux-
> > > > nvme@lists.infradead.org
> > > > Subject: Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
> > > > 
> > > > On Sat, 2017-08-05 at 06:53 -0700, Christoph Hellwig wrote:
> > > > > 
> > > > > 
> > > > > On Wed, Aug 02, 2017 at 10:14:40AM +0200, Hannes Reinecke
> > > > > wrote:
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > > I'm not happy with this approach.
> > > > > > NVMe devices should _not_ appear as SCSI devices; this will
> > > > > > just
> > > > > > confuse matters _and_ will be incompatible with 'normal'
> > > > > > NVMe
> > > > > > devices.
> > > > > > 
> > > > > > Rather I would like to see the driver to hook into the
> > > > > > existing
> > > > > > NVMe framework (which essentially means to treat the
> > > > > > mpt3sas as
> > > > > > a weird NVMe-over-Fabrics HBA), and expose the NVMe devices
> > > > > > like
> > > > > > any other NVMe HBA.
> > > > > 
> > > > > That doesn't make any sense.  The devices behind the mpt
> > > > > adapter
> > > > > don't look like NVMe devices at all for the hosts - there are
> > > > > no
> > > > > NVMe commands or queues involved at all, they hide behind the
> > > > > same
> > > > > somewhat leaky scsi abstraction as other devices behind the
> > > > > mpt
> > > > > controller.
> > > > 
> > > > You might think about what we did for SAS: split the generic
> > > > handler
> > > > into two pieces, libsas for driving the devices, which mpt
> > > > didn't
> > > > need because of the fat firmware and the SAS transport class so
> > > > mpt
> > > > could at least show the same sysfs files as everything else for
> > > > SAS
> > > > devices.
> > > 
> > >  Ventura generation of controllers are adding connectivity of
> > > NVME
> > >  drives seamlessly and protocol handling is in Firmware.
> > >  Same as SCSI to ATA translation done in firmware, Ventura
> > > controller
> > >  is doing SCSI to NVME translation and for end user protocol
> > > handling
> > >  is abstracted.
> > > 
> > >  This product handles new Transport protocol (NVME) same as ATA
> > > and
> > >  transport is abstracted for end user.
> > > 
> > > NVME pass-through related driver code, it is just a big tunnel
> > > for
> > > user space application. It is just a basic framework like SATA
> > > PASS-
> > > Through in existing mpt3sas driver.
> > 
> > I know how it works ... and I'm on record as not liking your SATL
> > approach
> > because we keep tripping across bugs in the SATL that we have to
> > fix in
> > the
> > driver.
> 
> We discussed about NVME device support behind <mpt3sas> to Hannes and
> he suggested to describe to product behavior to wider audience to be
> aware. Just wanted to share the notes.

Great, thanks! it's certainly better than releasing the product and
having us have to support it.

> > However, at least for bot SAS and SATA they appear to the system as
> > SCSI
> > devices regardless of HBA, so we've largely smoothed over any
> > problems if
> > you
> > transfer from mp3sas to another SAS/SATA controller.
> > 
> > I believe your current proposal is to have NVMe devices appear as
> > SCSI,
> > which
> > isn't how the native NVMe driver handles them at all.  This is
> > going to
> > have to
> > be special cased in any tool designed to handle nvme devices and
> > it's
> > going to
> > cause big problems if someone changes controller (or moves the
> > device).  What's the proposal for making this as painless as
> > possible?
> 
> We have to attempt this use case and see how it behaves. I have not
> tried this, so not sure if things are really bad or just some tuning
> may be helpful. I will revert back to you on this.
> 
> I understood request as -  We need some udev rules to be working well
> for *same* NVME drives if it is behind <mpt3sas> or native <nvme>.
> Example - If user has OS installed on NVME drive which is behind
> <mpt3sas> driver as SCSI disk should be able to boot if he/she hooked
> same NVME drive which is detected by native <nvme> driver (and vice
> versa.)

It's not just the udev rules, it's the tools as well; possibly things
like that nvme-cli toolkit Intel is doing.

James

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
  2017-08-07 15:45             ` James Bottomley
@ 2017-08-08  4:04               ` Keith Busch
  2017-08-08  7:03                 ` Sreekanth Reddy
  0 siblings, 1 reply; 44+ messages in thread
From: Keith Busch @ 2017-08-08  4:04 UTC (permalink / raw)
  To: James Bottomley
  Cc: Kashyap Desai, Christoph Hellwig, Hannes Reinecke,
	Sreekanth Reddy, linux-scsi, Chaitra Basappa,
	Suganath Prabu Subramani, Sathya Prakash Veerichetty,
	linux-kernel, linux-nvme, martin.petersen

On Mon, Aug 07, 2017 at 08:45:25AM -0700, James Bottomley wrote:
> On Mon, 2017-08-07 at 20:01 +0530, Kashyap Desai wrote:
> > 
> > We have to attempt this use case and see how it behaves. I have not
> > tried this, so not sure if things are really bad or just some tuning
> > may be helpful. I will revert back to you on this.
> > 
> > I understood request as -  We need some udev rules to be working well
> > for *same* NVME drives if it is behind <mpt3sas> or native <nvme>.
> > Example - If user has OS installed on NVME drive which is behind
> > <mpt3sas> driver as SCSI disk should be able to boot if he/she hooked
> > same NVME drive which is detected by native <nvme> driver (and vice
> > versa.)
> 
> It's not just the udev rules, it's the tools as well; possibly things
> like that nvme-cli toolkit Intel is doing.

It looks like they can make existing nvme tooling work with little
effort if they have the driver implement NVME_IOCTL_ADMIN_COMMAND, and
then have their driver build the MPI NVMe Encapsulated Request from that.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
  2017-08-08  4:04               ` Keith Busch
@ 2017-08-08  7:03                 ` Sreekanth Reddy
  2017-08-08  7:29                   ` Keith Busch
  0 siblings, 1 reply; 44+ messages in thread
From: Sreekanth Reddy @ 2017-08-08  7:03 UTC (permalink / raw)
  To: Keith Busch
  Cc: James Bottomley, Kashyap Desai, Christoph Hellwig,
	Hannes Reinecke, linux-scsi, Chaitra Basappa,
	Suganath Prabu Subramani, Sathya Prakash Veerichetty,
	linux-kernel, linux-nvme, Martin K. Petersen

On Tue, Aug 8, 2017 at 9:34 AM, Keith Busch <keith.busch@intel.com> wrote:
> On Mon, Aug 07, 2017 at 08:45:25AM -0700, James Bottomley wrote:
>> On Mon, 2017-08-07 at 20:01 +0530, Kashyap Desai wrote:
>> >
>> > We have to attempt this use case and see how it behaves. I have not
>> > tried this, so not sure if things are really bad or just some tuning
>> > may be helpful. I will revert back to you on this.
>> >
>> > I understood request as -  We need some udev rules to be working well
>> > for *same* NVME drives if it is behind <mpt3sas> or native <nvme>.
>> > Example - If user has OS installed on NVME drive which is behind
>> > <mpt3sas> driver as SCSI disk should be able to boot if he/she hooked
>> > same NVME drive which is detected by native <nvme> driver (and vice
>> > versa.)
>>
>> It's not just the udev rules, it's the tools as well; possibly things
>> like that nvme-cli toolkit Intel is doing.
>
> It looks like they can make existing nvme tooling work with little
> effort if they have the driver implement NVME_IOCTL_ADMIN_COMMAND, and

Precisely, I was thinking on the same line and you clarified. I will
spend sometime on this and get back to you.

> then have their driver build the MPI NVMe Encapsulated Request from that.

Hi Everyone,

Thanks for the discussion and feedback.  We have noted this (i.e. will
Encapsulate NVME_IOCTL_ADMIN_CMD received from nvme cli in to MPI NVMe
Encapsulated Request message and will issue this request to firmware)
as our next to-do item and I will post possible options (this may need
some discussion with our FW group, so need time to get back with all
the details).

We will be posting next version of patch set i.e. v3, which will a
accommodate below changes suggested by Hannes and Martin over v2 patch
set.

1. In the MPI header files, we have reformatted headers to have type
and variable on one line as suggested by Hannes,
2. As suggested by Martin, started using blk_queue_virt_boundary() API
for NVMe drives and simplified the PRP formation.
3. Removed 'TODO' comments

Thanks,
Sreekanth

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 00/13] mpt3sas driver NVMe support:
  2017-08-08  7:03                 ` Sreekanth Reddy
@ 2017-08-08  7:29                   ` Keith Busch
  0 siblings, 0 replies; 44+ messages in thread
From: Keith Busch @ 2017-08-08  7:29 UTC (permalink / raw)
  To: Sreekanth Reddy
  Cc: James Bottomley, Kashyap Desai, Christoph Hellwig,
	Hannes Reinecke, linux-scsi, Chaitra Basappa,
	Suganath Prabu Subramani, Sathya Prakash Veerichetty,
	linux-kernel, linux-nvme, Martin K. Petersen

On Tue, Aug 08, 2017 at 12:33:40PM +0530, Sreekanth Reddy wrote:
> On Tue, Aug 8, 2017 at 9:34 AM, Keith Busch <keith.busch@intel.com> wrote:
> >
> > It looks like they can make existing nvme tooling work with little
> > effort if they have the driver implement NVME_IOCTL_ADMIN_COMMAND, and
> 
> Precisely, I was thinking on the same line and you clarified. I will
> spend sometime on this and get back to you.

Sounds good. Just note that while the majority of NVMe management should
be reachable with just that IOCTL, some tooling features may not work
correctly since they look for /dev/nvmeX, and I assume this driver will
create /dev/sdX instead.

^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2017-08-08  7:23 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-14 13:22 [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu S
2017-07-14 13:22 ` [PATCH v2 01/13] mpt3sas: Update MPI Header Suganath Prabu S
2017-08-03  6:24   ` Hannes Reinecke
2017-08-03  7:55     ` Johannes Thumshirn
2017-08-03  9:34       ` Sreekanth Reddy
2017-07-14 13:22 ` [PATCH v2 02/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe Suganath Prabu S
2017-08-03  6:27   ` Hannes Reinecke
2017-08-03 10:09     ` Sreekanth Reddy
2017-07-14 13:22 ` [PATCH v2 03/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe devices Suganath Prabu S
2017-07-27 13:26   ` Martin K. Petersen
2017-07-14 13:22 ` [PATCH v2 04/13] mpt3sas: Added support for nvme encapsulated request message Suganath Prabu S
2017-08-03  6:33   ` Hannes Reinecke
2017-07-14 13:22 ` [PATCH v2 05/13] mpt3sas: API 's to support NVMe drive addition to SML Suganath Prabu S
2017-08-03  6:35   ` Hannes Reinecke
2017-07-14 13:22 ` [PATCH v2 06/13] mpt3sas: API's to remove nvme drive from sml Suganath Prabu S
2017-08-03  6:36   ` Hannes Reinecke
2017-07-14 13:22 ` [PATCH v2 07/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware Suganath Prabu S
2017-08-03  6:38   ` Hannes Reinecke
2017-07-14 13:22 ` [PATCH v2 08/13] mpt3sas: Set NVMe device queue depth as 128 Suganath Prabu S
2017-08-03  6:39   ` Hannes Reinecke
2017-08-03  9:52     ` Sreekanth Reddy
2017-07-14 13:22 ` [PATCH v2 09/13] mpt3sas: scan and add nvme device after controller reset Suganath Prabu S
2017-08-03  6:40   ` Hannes Reinecke
2017-08-03 10:19     ` Sreekanth Reddy
2017-07-14 13:22 ` [PATCH v2 10/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives Suganath Prabu S
2017-08-03  6:43   ` Hannes Reinecke
2017-07-14 13:22 ` [PATCH v2 11/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info Suganath Prabu S
2017-08-03  6:44   ` Hannes Reinecke
2017-07-14 13:22 ` [PATCH v2 12/13] mpt3sas: Fix nvme drives checking for tlr Suganath Prabu S
2017-08-03  6:44   ` Hannes Reinecke
2017-07-14 13:22 ` [PATCH v2 13/13] mpt3sas: Update mpt3sas driver version Suganath Prabu S
2017-08-03  6:45   ` Hannes Reinecke
2017-07-25  5:20 ` [PATCH v2 00/13] mpt3sas driver NVMe support: Suganath Prabu Subramani
2017-08-02  8:14 ` Hannes Reinecke
2017-08-03  6:48   ` Hannes Reinecke
2017-08-05 13:53   ` Christoph Hellwig
2017-08-05 14:42     ` James Bottomley
2017-08-07 13:56       ` Kashyap Desai
2017-08-07 14:18         ` James Bottomley
2017-08-07 14:31           ` Kashyap Desai
2017-08-07 15:45             ` James Bottomley
2017-08-08  4:04               ` Keith Busch
2017-08-08  7:03                 ` Sreekanth Reddy
2017-08-08  7:29                   ` Keith Busch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).