[PATCH v4 04/14] mpt3sas: Added support for nvme encapsulated request message.

2017-08-21 Thread Suganath Prabu S
From: root 

* 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 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 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 1e9086a..2ffcac2 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))) {
@@ -3057,6 +3064,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.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, >chip->RequestDescriptorPostLow,
+   >scsi_lookup_lock);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * @ioc: per adapter object
  * @smid: system request message index
@@ -3147,6 +3178,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.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), >chip->AtomicRequestDescriptorPost);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * use Atomic Request Descriptor
  * @ioc: per adapter object
@@ -5979,11 +6031,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;
+   

[PATCH v4 04/14] mpt3sas: Added support for nvme encapsulated request message.

2017-08-21 Thread Suganath Prabu S
From: root 

* 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 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 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 1e9086a..2ffcac2 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))) {
@@ -3057,6 +3064,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.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, >chip->RequestDescriptorPostLow,
+   >scsi_lookup_lock);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * @ioc: per adapter object
  * @smid: system request message index
@@ -3147,6 +3178,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.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), >chip->AtomicRequestDescriptorPost);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * use Atomic Request Descriptor
  * @ioc: per adapter object
@@ -5979,11 +6031,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