[PATCH v3 12/13] mpt3sas: Fix nvme drives checking for tlr.

2017-08-08 Thread Suganath Prabu S
Check for NVMe drives before enabling or checking tlr.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 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 ff77850..49e1943 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
@@ -4818,8 +4826,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(>device->sdev_gendev)
-   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
+   if (((!ioc->is_warpdrive && !scsih_is_raid(>device->sdev_gendev))
+   && !scsih_is_nvme(>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);
@@ -4864,8 +4873,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) {
@@ -5413,9 +5422,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(>device->sdev_gendev) &&
-   sas_is_tlr_enabled(scmd->device) &&
+   !scsih_is_nvme(>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



[PATCH v3 10/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives.

2017-08-08 Thread Suganath Prabu S
Added debug information for NVMe/PCIe drives in target rest path.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
Reviewed-by: Hannes Reinecke <h...@suse.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 2242edb..ff77850 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2900,6 +2900,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;
 
@@ -2916,6 +2917,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(>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(>pcie_device_lock, flags);
+
} else {
spin_lock_irqsave(>sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
@@ -3659,6 +3685,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;
@@ -3701,24 +3728,52 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
sas_address = sas_device->sas_address;
}
spin_unlock_irqrestore(>sas_device_lock, flags);
-
+   if (!sas_device) {
+   spin_lock_irqsave(>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(>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')
- 

[PATCH v3 10/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives.

2017-08-08 Thread Suganath Prabu S
Added debug information for NVMe/PCIe drives in target rest path.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 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 2242edb..ff77850 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2900,6 +2900,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;
 
@@ -2916,6 +2917,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(>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(>pcie_device_lock, flags);
+
} else {
spin_lock_irqsave(>sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
@@ -3659,6 +3685,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;
@@ -3701,24 +3728,52 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
sas_address = sas_device->sas_address;
}
spin_unlock_irqrestore(>sas_device_lock, flags);
-
+   if (!sas_device) {
+   spin_lock_irqsave(>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(>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 f

[PATCH v3 13/13] mpt3sas: Update mpt3sas driver version.

2017-08-08 Thread Suganath Prabu S
Updated mpt3sas driver version to 15.101.00.00

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
Reviewed-by: Hannes Reinecke <h...@suse.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 51d2668..2cd1550 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@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_VERSION00
 
-- 
1.7.1



[PATCH v3 13/13] mpt3sas: Update mpt3sas driver version.

2017-08-08 Thread Suganath Prabu S
Updated mpt3sas driver version to 15.101.00.00

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 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 51d2668..2cd1550 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 "
 #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_VERSION00
 
-- 
1.7.1



[PATCH v3 07/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware.

2017-08-08 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
Reviewed-by: Hannes Reinecke <h...@suse.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 27fe074..f8ed98c 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)
@@ -6232,8 +6252,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 710ea63..344f946 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_

[PATCH v3 07/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware.

2017-08-08 Thread Suganath Prabu S
* 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 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 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 27fe074..f8ed98c 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)
@@ -6232,8 +6252,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 710ea63..344f946 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)

[PATCH v3 11/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info

2017-08-08 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
Reviewed-by: Hannes Reinecke <h...@suse.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, >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(>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(>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(>pcie_device_list))
+   return rc;
+
+   spin_lock_irqsave(>pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, >pcie_device_list, list) {
+   if (btdh->bus == 0x && btdh->id == 0x &&
+  btdh->handle == pcie_device->handle) {
+   btdh->bus = pcie_device->channel;
+   btdh->id = pcie_device->id;
+   rc = 1;
+   

[PATCH v3 09/13] mpt3sas: scan and add nvme device after controller reset

2017-08-08 Thread Suganath Prabu S
After Controller reset, Scan and add nvme device back to the topology.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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 35b472f..2242edb 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4876,6 +4876,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;
@@ -5008,6 +5009,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) {
@@ -5054,11 +5077,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd,
struct sense_info data;
_scsih_normalize_sense(scmd->sense_buffer, );
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 *)_info;
@@ -8519,6 +8541,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(>pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, >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) {
+

[PATCH v3 11/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info

2017-08-08 Thread Suganath Prabu S
* 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 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 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, >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(>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(>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(>pcie_device_list))
+   return rc;
+
+   spin_lock_irqsave(>pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, >pcie_device_list, list) {
+   if (btdh->bus == 0x && btdh->id == 0x &&
+  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

[PATCH v3 09/13] mpt3sas: scan and add nvme device after controller reset

2017-08-08 Thread Suganath Prabu S
After Controller reset, Scan and add nvme device back to the topology.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 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 35b472f..2242edb 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4876,6 +4876,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;
@@ -5008,6 +5009,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) {
@@ -5054,11 +5077,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd,
struct sense_info data;
_scsih_normalize_sense(scmd->sense_buffer, );
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 *)_info;
@@ -8519,6 +8541,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(>pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, >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_pr

[PATCH v3 08/13] mpt3sas: Set NVMe device queue depth as 128

2017-08-08 Thread Suganath Prabu S
Sets nvme device queue depth, name and displays device capabilities

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 09ad823..51d2668 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_LENGTH32  /* 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 344f946..35b472f 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,52 @@ scsih_slave_configure(struct scsi_device *sdev)
}
}
 
+   /* PCIe handling */
+   if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   spin_lock_irqsave(>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(>pcie_device_lock, flags);
+   dfailprintk(ioc, pr_warn(MPT3SAS_FMT
+   "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
+   __LINE__, __func__));
+   return 1;
+   }
+
+   qdepth = MPT3SAS_NVME_QUEUE_DEPTH;
+   ds = "NVMe";
+   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(>pcie_device_lock, flags);
+   scsih_change_queue_depth(sdev, qdepth);
+
+   /* Enable QUEUE_FLAG_NOMERGES flag, so that IOs won't be
+** merged and can eliminate holes created during merging
+** operation.
+**/
+   queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES,
+   sdev->request_queue);
+   blk_queue_virt_boundary(sdev->request_queue,
+   ioc->page_size - 1);
+   return 0;
+   }
+
spin_lock_irqsave(>sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
   sas_device_priv_data->sas_target->sas_address);
-- 
1.7.1



[PATCH v3 08/13] mpt3sas: Set NVMe device queue depth as 128

2017-08-08 Thread Suganath Prabu S
Sets nvme device queue depth, name and displays device capabilities

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |2 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   47 ++
 2 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 09ad823..51d2668 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_LENGTH32  /* 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 344f946..35b472f 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,52 @@ scsih_slave_configure(struct scsi_device *sdev)
}
}
 
+   /* PCIe handling */
+   if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   spin_lock_irqsave(>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(>pcie_device_lock, flags);
+   dfailprintk(ioc, pr_warn(MPT3SAS_FMT
+   "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
+   __LINE__, __func__));
+   return 1;
+   }
+
+   qdepth = MPT3SAS_NVME_QUEUE_DEPTH;
+   ds = "NVMe";
+   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(>pcie_device_lock, flags);
+   scsih_change_queue_depth(sdev, qdepth);
+
+   /* Enable QUEUE_FLAG_NOMERGES flag, so that IOs won't be
+** merged and can eliminate holes created during merging
+** operation.
+**/
+   queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES,
+   sdev->request_queue);
+   blk_queue_virt_boundary(sdev->request_queue,
+   ioc->page_size - 1);
+   return 0;
+   }
+
spin_lock_irqsave(>sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
   sas_device_priv_data->sas_target->sas_address);
-- 
1.7.1



[PATCH v3 05/13] mpt3sas: API 's to support NVMe drive addition to SML

2017-08-08 Thread Suganath Prabu S
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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
Reviewed-by: Hannes Reinecke <h...@suse.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 c4be9ad..09ad823 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(_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, _request.PageBufferSGE);
+   r = _config_request(ioc, _request, mpi_reply,
+   MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+   if (r)
+   goto out;
+
+   mpi_request.PageAddress = cpu_to_le32(f

[PATCH v3 05/13] mpt3sas: API 's to support NVMe drive addition to SML

2017-08-08 Thread Suganath Prabu S
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 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 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 c4be9ad..09ad823 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(_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, _request.PageBufferSGE);
+   r = _config_request(ioc, _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_ACTIO

[PATCH v3 01/13] mpt3sas: Update MPI Header

2017-08-08 Thread Suganath Prabu S
Update MPI Files for NVMe support

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpi/mpi2.h  |   43 +++-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  564 --
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |   11 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |  282 +-
 drivers/scsi/mpt3sas/mpi/mpi2_pci.h  |  112 +++
 drivers/scsi/mpt3sas/mpi/mpi2_tool.h |   14 +-
 6 files changed, 992 insertions(+), 34 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(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -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(0x

[PATCH v3 02/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe

2017-08-08 Thread Suganath Prabu S
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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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_VOLUME0x02
 #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(>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(>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(>refcount, pcie_device_free);
+}
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -556,12 +642,13 @@ struct _raid_device {
 
 /**
  * struc

[PATCH v3 01/13] mpt3sas: Update MPI Header

2017-08-08 Thread Suganath Prabu S
Update MPI Files for NVMe support

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2.h  |   43 +++-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  564 --
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |   11 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |  282 +-
 drivers/scsi/mpt3sas/mpi/mpi2_pci.h  |  112 +++
 drivers/scsi/mpt3sas/mpi/mpi2_tool.h |   14 +-
 6 files changed, 992 insertions(+), 34 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(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -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

[PATCH v3 02/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe

2017-08-08 Thread Suganath Prabu S
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 
Signed-off-by: Suganath Prabu S 
---
 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_VOLUME0x02
 #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(>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(>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(>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 

[PATCH v3 03/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe devices

2017-08-08 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  668 +-
 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, 713 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 18039bb..d48f176 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include /* To get host page size per arch */
 #include 
 
 
@@ -1347,6 +1348,547 @@ _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;

[PATCH v3 03/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe devices

2017-08-08 Thread Suganath Prabu S
* 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 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  668 +-
 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, 713 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 18039bb..d48f176 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include /* To get host page size per arch */
 #include 
 
 
@@ -1347,6 +1348,547 @@ _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

[PATCH v3 00/13] mpt3sas driver NVMe support:

2017-08-08 Thread Suganath Prabu S
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.

mpt3sas v3 patset:
Posting version v3. This accommodates below changes
over v2 patch.

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

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 |  564 +-
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |   11 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |  282 +-
 drivers/scsi/mpt3sas/mpi/mpi2_pci.h  |  112 ++
 drivers/scsi/mpt3sas/mpi/mpi2_tool.h |   14 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  754 -
 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 | 1881 --
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 12 files changed, 3929 insertions(+), 163 deletions(-)
 create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h

Thanks,
Suganath Prabu S


[PATCH v3 00/13] mpt3sas driver NVMe support:

2017-08-08 Thread Suganath Prabu S
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.

mpt3sas v3 patset:
Posting version v3. This accommodates below changes
over v2 patch.

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

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 |  564 +-
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |   11 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |  282 +-
 drivers/scsi/mpt3sas/mpi/mpi2_pci.h  |  112 ++
 drivers/scsi/mpt3sas/mpi/mpi2_tool.h |   14 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  754 -
 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 | 1881 --
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 12 files changed, 3929 insertions(+), 163 deletions(-)
 create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h

Thanks,
Suganath Prabu S


[PATCH v2 01/13] mpt3sas: Update MPI Header

2017-07-14 Thread Suganath Prabu S
Update MPI Files for NVMe support

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -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(0x

[PATCH v2 01/13] mpt3sas: Update MPI Header

2017-07-14 Thread Suganath Prabu S
Update MPI Files for NVMe support

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 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(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -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

[PATCH v2 06/13] mpt3sas: API's to remove nvme drive from sml

2017-07-14 Thread Suganath Prabu S
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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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(>pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device) {
+   if (!list_empty(_device->list)) {
+   list_del_init(_device->list);
+   was_on_pcie_device_list = 1;
+   pcie_device_put(pcie_device);
+   }
+   }
+   spin_unlock_irqrestore(>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)

[PATCH v2 06/13] mpt3sas: API's to remove nvme drive from sml

2017-07-14 Thread Suganath Prabu S
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 
Signed-off-by: Suganath Prabu S 
---
 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(>pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device) {
+   if (!list_empty(_device->list)) {
+   list_del_init(_device->list);
+   was_on_pcie_device_list = 1;
+   pcie_device_put(pcie_device);
+   }
+   }
+   spin_unlock_irqrestore(>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,
+ 

[PATCH v2 05/13] mpt3sas: API 's to support NVMe drive addition to SML

2017-07-14 Thread Suganath Prabu S
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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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(_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, _request.PageBufferSGE);
+   r = _config_request(ioc, _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_

[PATCH v2 05/13] mpt3sas: API 's to support NVMe drive addition to SML

2017-07-14 Thread Suganath Prabu S
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 
Signed-off-by: Suganath Prabu S 
---
 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(_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, _request.PageBufferSGE);
+   r = _config_request(ioc, _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, _request, mpi_rep

[PATCH v2 08/13] mpt3sas: Set NVMe device queue depth as 128

2017-07-14 Thread Suganath Prabu S
Sets nvme device queue depth, name and displays device capabilities

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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_LENGTH32  /* 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(>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(>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(>pcie_device_lock, flags);
+   scsih_change_queue_depth(sdev, qdepth);
+   return 0;
+   }
+
spin_lock_irqsave(>sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
   sas_device_priv_data->sas_target->sas_address);
-- 
1.7.1



[PATCH v2 08/13] mpt3sas: Set NVMe device queue depth as 128

2017-07-14 Thread Suganath Prabu S
Sets nvme device queue depth, name and displays device capabilities

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 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_LENGTH32  /* 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(>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(>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(>pcie_device_lock, flags);
+   scsih_change_queue_depth(sdev, qdepth);
+   return 0;
+   }
+
spin_lock_irqsave(>sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
   sas_device_priv_data->sas_target->sas_address);
-- 
1.7.1



[PATCH v2 10/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives.

2017-07-14 Thread Suganath Prabu S
Added debug information for NVMe/PCIe drives in target rest path.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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(>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(>pcie_device_lock, flags);
+
} else {
spin_lock_irqsave(>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(>sas_device_lock, flags);
-
+   if (!sas_device) {
+   spin_lock_irqsave(>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(>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, p

[PATCH v2 10/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives.

2017-07-14 Thread Suganath Prabu S
Added debug information for NVMe/PCIe drives in target rest path.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 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(>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(>pcie_device_lock, flags);
+
} else {
spin_lock_irqsave(>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(>sas_device_lock, flags);
-
+   if (!sas_device) {
+   spin_lock_irqsave(>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(>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),"

[PATCH v2 13/13] mpt3sas: Update mpt3sas driver version.

2017-07-14 Thread Suganath Prabu S
Updated mpt3sas driver version to 15.101.00.00

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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@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_VERSION00
 
-- 
1.7.1



[PATCH v2 13/13] mpt3sas: Update mpt3sas driver version.

2017-07-14 Thread Suganath Prabu S
Updated mpt3sas driver version to 15.101.00.00

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 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 "
 #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_VERSION00
 
-- 
1.7.1



[PATCH v2 12/13] mpt3sas: Fix nvme drives checking for tlr.

2017-07-14 Thread Suganath Prabu S
Check for NVMe drives before enabling or checking tlr.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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(>device->sdev_gendev)
-   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
+   if (((!ioc->is_warpdrive && !scsih_is_raid(>device->sdev_gendev))
+   && !scsih_is_nvme(>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(>device->sdev_gendev) &&
-   sas_is_tlr_enabled(scmd->device) &&
+   !scsih_is_nvme(>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



[PATCH v2 12/13] mpt3sas: Fix nvme drives checking for tlr.

2017-07-14 Thread Suganath Prabu S
Check for NVMe drives before enabling or checking tlr.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 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(>device->sdev_gendev)
-   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
+   if (((!ioc->is_warpdrive && !scsih_is_raid(>device->sdev_gendev))
+   && !scsih_is_nvme(>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(>device->sdev_gendev) &&
-   sas_is_tlr_enabled(scmd->device) &&
+   !scsih_is_nvme(>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



[PATCH v2 11/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info

2017-07-14 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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, >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(>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(>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(>pcie_device_list))
+   return rc;
+
+   spin_lock_irqsave(>pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, >pcie_device_list, list) {
+   if (btdh->bus == 0x && btdh->id == 0x &&
+  btdh->handle == pcie_device->handle) {
+   btdh->bus = pcie_device->channel;
+   btdh->id = pcie_device->id;
+   rc = 1;
+   goto out;
+   } else if (btdh->bu

[PATCH v2 11/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info

2017-07-14 Thread Suganath Prabu S
* 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 
Signed-off-by: Suganath Prabu S 
---
 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, >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(>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(>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(>pcie_device_list))
+   return rc;
+
+   spin_lock_irqsave(>pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, >pcie_device_list, list) {
+   if (btdh->bus == 0x && btdh->id == 0x &&
+  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 ==
+  

[PATCH v2 09/13] mpt3sas: scan and add nvme device after controller reset

2017-07-14 Thread Suganath Prabu S
After Controller reset, Scan and add nvme device back to the topology.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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, );
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 *)_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(>pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, >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) {
+

[PATCH v2 07/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware.

2017-07-14 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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);
   

[PATCH v2 09/13] mpt3sas: scan and add nvme device after controller reset

2017-07-14 Thread Suganath Prabu S
After Controller reset, Scan and add nvme device back to the topology.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 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, );
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 *)_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(>pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, >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_pr

[PATCH v2 07/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware.

2017-07-14 Thread Suganath Prabu S
* 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 
Signed-off-by: Suganath Prabu S 
---
 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_d

[PATCH v2 04/13] mpt3sas: Added support for nvme encapsulated request message.

2017-07-14 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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.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
@@ -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.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
@@ -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_h

[PATCH v2 04/13] mpt3sas: Added support for nvme encapsulated request message.

2017-07-14 Thread Suganath Prabu S
* 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 
---
 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.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
@@ -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.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
@@ -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_nv

[PATCH v2 03/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe devices

2017-07-14 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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 
 #include 
 #include 
+#include /* To get host page size per arch */
 #include 
 
 
@@ -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;

[PATCH v2 03/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe devices

2017-07-14 Thread Suganath Prabu S
* 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 
Signed-off-by: Suganath Prabu S 
---
 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 
 #include 
 #include 
+#include /* To get host page size per arch */
 #include 
 
 
@@ -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

[PATCH v2 02/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe

2017-07-14 Thread Suganath Prabu S
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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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_VOLUME0x02
 #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(>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(>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(>refcount, pcie_device_free);
+}
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -556,12 +642,13 @@ struct _raid_device {
 
 /**
  * struc

[PATCH v2 02/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe

2017-07-14 Thread Suganath Prabu S
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 
Signed-off-by: Suganath Prabu S 
---
 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_VOLUME0x02
 #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(>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(>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(>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 

[PATCH v2 00/13] mpt3sas driver NVMe support:

2017-07-14 Thread Suganath Prabu S
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


[PATCH v2 00/13] mpt3sas driver NVMe support:

2017-07-14 Thread Suganath Prabu S
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


[PATCH 08/13] mpt3sas: scan and add nvme device after controller reset

2017-07-11 Thread Suganath Prabu S
After Controller reset, Scan and add nvme device back to the topology.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  196 +-
 1 files changed, 191 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 68aa102..7100ee8 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4867,6 +4867,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;
@@ -4999,6 +5000,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) {
@@ -5045,11 +5068,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd,
struct sense_info data;
_scsih_normalize_sense(scmd->sense_buffer, );
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 *)_info;
@@ -6931,7 +6953,7 @@ _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
pcie_device_pg0.AccessStatus))
return 0;
 
-   if (!(_scsih_is_nvme_device(pcie_device_pg0.DeviceInfo)))
+   if (!(_scsih_is_nvme_device(le32_to_cpu(pcie_device_pg0.DeviceInfo
return 0;
 
pcie_device = mpt3sas_get_pdev_by_wwid(ioc, wwid);
@@ -8510,6 +8532,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(>pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, >pcie_device_list, list) {

[PATCH 05/13] mpt3sas: Set NVMe device queue depth as 128

2017-07-11 Thread Suganath Prabu S
Sets nvme device queue depth, name and displays device capabilities.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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 26239ec..0f07b16 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_LENGTH32  /* 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 2a6a8e6..e4e35c1 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1962,6 +1962,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;
@@ -2092,6 +2093,45 @@ scsih_slave_configure(struct scsi_device *sdev)
}
}
 
+   /* PCIe handling */
+   if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   spin_lock_irqsave(>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(>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(>pcie_device_lock, flags);
+   scsih_change_queue_depth(sdev, qdepth);
+   return 0;
+   }
+
spin_lock_irqsave(>sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
   sas_device_priv_data->sas_target->sas_address);
-- 
1.7.1



[PATCH 08/13] mpt3sas: scan and add nvme device after controller reset

2017-07-11 Thread Suganath Prabu S
After Controller reset, Scan and add nvme device back to the topology.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  196 +-
 1 files changed, 191 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 68aa102..7100ee8 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4867,6 +4867,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;
@@ -4999,6 +5000,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) {
@@ -5045,11 +5068,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd,
struct sense_info data;
_scsih_normalize_sense(scmd->sense_buffer, );
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 *)_info;
@@ -6931,7 +6953,7 @@ _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
pcie_device_pg0.AccessStatus))
return 0;
 
-   if (!(_scsih_is_nvme_device(pcie_device_pg0.DeviceInfo)))
+   if (!(_scsih_is_nvme_device(le32_to_cpu(pcie_device_pg0.DeviceInfo
return 0;
 
pcie_device = mpt3sas_get_pdev_by_wwid(ioc, wwid);
@@ -8510,6 +8532,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(>pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, >pcie_device_list, list) {
+   if ((pcie_device->wwid == pcie_device_pg0->WW

[PATCH 05/13] mpt3sas: Set NVMe device queue depth as 128

2017-07-11 Thread Suganath Prabu S
Sets nvme device queue depth, name and displays device capabilities.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 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 26239ec..0f07b16 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_LENGTH32  /* 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 2a6a8e6..e4e35c1 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1962,6 +1962,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;
@@ -2092,6 +2093,45 @@ scsih_slave_configure(struct scsi_device *sdev)
}
}
 
+   /* PCIe handling */
+   if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   spin_lock_irqsave(>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(>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(>pcie_device_lock, flags);
+   scsih_change_queue_depth(sdev, qdepth);
+   return 0;
+   }
+
spin_lock_irqsave(>sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
   sas_device_priv_data->sas_target->sas_address);
-- 
1.7.1



[PATCH 10/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info

2017-07-11 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |3 +-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |   88 --
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 3 files changed, 61 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 063977a..ea6e607 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -452,6 +452,7 @@ struct _internal_cmd {
struct completion done;
void*reply;
void*sense;
+   u64 *nvme_error_response;
u16 status;
u16 smid;
 };
@@ -1615,7 +1616,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 35e5c30..269c753 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, >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(>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(>sas_device_lock, flags);
if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)
pr_info(MPT3SAS_FMT
"\tscsi_state(0x%02x), scsi_status"
@@ -1375,6 +1365,42 @@ _ctl_btdh_search_sas_device(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _ctl_btdh_sea

[PATCH 10/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info

2017-07-11 Thread Suganath Prabu S
* 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 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |3 +-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |   88 --
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 3 files changed, 61 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 063977a..ea6e607 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -452,6 +452,7 @@ struct _internal_cmd {
struct completion done;
void*reply;
void*sense;
+   u64 *nvme_error_response;
u16 status;
u16 smid;
 };
@@ -1615,7 +1616,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 35e5c30..269c753 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, >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(>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(>sas_device_lock, flags);
if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)
pr_info(MPT3SAS_FMT
"\tscsi_state(0x%02x), scsi_status"
@@ -1375,6 +1365,42 @@ _ctl_btdh_search_sas_device(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _ctl_btdh_search_pcie_device - searching for pcie device
+ * @ioc: per adapter obje

[PATCH 13/13] mpt3sas: Update mpt3sas driver version.

2017-07-11 Thread Suganath Prabu S
Updated mpt3sas driver version to 15.101.00.00

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index ea6e607..835d6da 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -74,11 +74,11 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies <mpt-fusionlinux@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_VERSION00
+#define MPT3SAS_RELEASE_VERSION0
 
 #define MPT2SAS_DRIVER_NAME"mpt2sas"
 #define MPT2SAS_DESCRIPTION"LSI MPT Fusion SAS 2.0 Device Driver"
-- 
1.7.1



[PATCH 13/13] mpt3sas: Update mpt3sas driver version.

2017-07-11 Thread Suganath Prabu S
Updated mpt3sas driver version to 15.101.00.00

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index ea6e607..835d6da 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -74,11 +74,11 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies "
 #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_VERSION00
+#define MPT3SAS_RELEASE_VERSION0
 
 #define MPT2SAS_DRIVER_NAME"mpt2sas"
 #define MPT2SAS_DESCRIPTION"LSI MPT Fusion SAS 2.0 Device Driver"
-- 
1.7.1



[PATCH 12/13] mpt3sas: Update MPI Header

2017-07-11 Thread Suganath Prabu S
Update MPI Files for NVMe support

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -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(0x

[PATCH 07/13] mpt3sas: API's to remove nvme drive from sml

2017-07-11 Thread Suganath Prabu S
Below API's are included in nvme drive remove path.
_scsih_pcie_device_remove
_scsih_pcie_device_remove_by_handle
_scsih_pcie_device_remove_from_sml

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index e52bebe..68aa102 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -73,7 +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 */
@@ -1048,6 +1049,86 @@ mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc, 
u16 handle)
 
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(>pcie_device_lock, flags);
+   if (!list_empty(_device->list)) {
+   list_del_init(_device->list);
+   was_on_pcie_device_list = 1;
+   }
+   spin_unlock_irqrestore(>pcie_device_lock, flags);
+   if (was_on_pcie_device_list) {
+   kfree(pcie_device->serial_number);
+   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(>pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device) {
+   if (!list_empty(_device->list)) {
+   list_del_init(_device->list);
+   was_on_pcie_device_list = 1;
+   pcie_device_put(pcie_device);
+   }
+   }
+   spin_unlock_irqrestore(>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
@@ -6630,6 +6711,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)
+   

[PATCH 12/13] mpt3sas: Update MPI Header

2017-07-11 Thread Suganath Prabu S
Update MPI Files for NVMe support

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 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(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -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

[PATCH 07/13] mpt3sas: API's to remove nvme drive from sml

2017-07-11 Thread Suganath Prabu S
Below API's are included in nvme drive remove path.
_scsih_pcie_device_remove
_scsih_pcie_device_remove_by_handle
_scsih_pcie_device_remove_from_sml

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  190 +-
 1 files changed, 188 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index e52bebe..68aa102 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -73,7 +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 */
@@ -1048,6 +1049,86 @@ mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc, 
u16 handle)
 
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(>pcie_device_lock, flags);
+   if (!list_empty(_device->list)) {
+   list_del_init(_device->list);
+   was_on_pcie_device_list = 1;
+   }
+   spin_unlock_irqrestore(>pcie_device_lock, flags);
+   if (was_on_pcie_device_list) {
+   kfree(pcie_device->serial_number);
+   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(>pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device) {
+   if (!list_empty(_device->list)) {
+   list_del_init(_device->list);
+   was_on_pcie_device_list = 1;
+   pcie_device_put(pcie_device);
+   }
+   }
+   spin_unlock_irqrestore(>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
@@ -6630,6 +6711,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)
+

[PATCH 11/13] mpt3sas: Fix nvme drives checking for tlr.

2017-07-11 Thread Suganath Prabu S
Check for NVMe drives before enabling or checking tlr.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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 b96da33..4d71ef7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2013,6 +2013,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
@@ -4810,8 +4818,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(>device->sdev_gendev)
-   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
+   if (((!ioc->is_warpdrive && !scsih_is_raid(>device->sdev_gendev))
+   && !scsih_is_nvme(>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);
@@ -4856,8 +4865,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) {
@@ -5405,9 +5414,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(>device->sdev_gendev) &&
-   sas_is_tlr_enabled(scmd->device) &&
+   !scsih_is_nvme(>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



[PATCH 11/13] mpt3sas: Fix nvme drives checking for tlr.

2017-07-11 Thread Suganath Prabu S
Check for NVMe drives before enabling or checking tlr.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 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 b96da33..4d71ef7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2013,6 +2013,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
@@ -4810,8 +4818,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(>device->sdev_gendev)
-   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
+   if (((!ioc->is_warpdrive && !scsih_is_raid(>device->sdev_gendev))
+   && !scsih_is_nvme(>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);
@@ -4856,8 +4865,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) {
@@ -5405,9 +5414,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(>device->sdev_gendev) &&
-   sas_is_tlr_enabled(scmd->device) &&
+   !scsih_is_nvme(>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



[PATCH 09/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives.

2017-07-11 Thread Suganath Prabu S
Added debug information for NVMe/PCIe drives in target rest path.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   86 --
 1 files changed, 72 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 7100ee8..b96da33 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -690,7 +690,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;
@@ -1208,6 +1208,7 @@ _scsih_pcie_device_init_add(struct MPT3SAS_ADAPTER *ioc,
_scsih_determine_boot_device(ioc, pcie_device, PCIE_CHANNEL);
spin_unlock_irqrestore(>pcie_device_lock, flags);
 }
+
 /**
  * _scsih_raid_device_find_by_id - raid device search
  * @ioc: per adapter object
@@ -2891,6 +2892,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;
 
@@ -2907,6 +2909,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(>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(>pcie_device_lock, flags);
+
} else {
spin_lock_irqsave(>sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
@@ -3650,6 +3677,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;
@@ -3692,24 +3720,52 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
sas_address = sas_device->sas_address;
}
spin_unlock_irqrestore(>sas_device_lock, flags);
-
+   if (!sas_device) {
+   spin_lock_irqsave(>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(>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, ha

[PATCH 09/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives.

2017-07-11 Thread Suganath Prabu S
Added debug information for NVMe/PCIe drives in target rest path.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   86 --
 1 files changed, 72 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 7100ee8..b96da33 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -690,7 +690,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;
@@ -1208,6 +1208,7 @@ _scsih_pcie_device_init_add(struct MPT3SAS_ADAPTER *ioc,
_scsih_determine_boot_device(ioc, pcie_device, PCIE_CHANNEL);
spin_unlock_irqrestore(>pcie_device_lock, flags);
 }
+
 /**
  * _scsih_raid_device_find_by_id - raid device search
  * @ioc: per adapter object
@@ -2891,6 +2892,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;
 
@@ -2907,6 +2909,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(>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(>pcie_device_lock, flags);
+
} else {
spin_lock_irqsave(>sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
@@ -3650,6 +3677,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;
@@ -3692,24 +3720,52 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
sas_address = sas_device->sas_address;
}
spin_unlock_irqrestore(>sas_device_lock, flags);
-
+   if (!sas_device) {
+   spin_lock_irqsave(>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(>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

[PATCH 06/13] mpt3sas: API 's to support NVMe drive addition to SML

2017-07-11 Thread Suganath Prabu S
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_wwid
mpt3sas_get_pdev_by_idchannel
mpt3sas_get_pdev_by_handle

mpt3sas_config_get_pcie_device_pg0
mpt3sas_config_get_pcie_device_pg2

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h   |   53 +++
 drivers/scsi/mpt3sas/mpt3sas_config.c |  100 ++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c  |  568 -
 3 files changed, 714 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 0f07b16..063977a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -563,6 +563,49 @@ struct _pcie_device {
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(>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(>refcount, pcie_device_free);
+}
+
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -1417,6 +1460,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 *
@@ -1455,6 +1502,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 
*io

[PATCH 01/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe

2017-07-11 Thread Suganath Prabu S
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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |   68 +++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  291 ++
 2 files changed, 325 insertions(+), 34 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 099ab4c..60fa7b6 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -357,7 +357,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 +369,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 +510,48 @@ static inline void sas_device_put(struct _sas_device *s)
kref_put(>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;
+};
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -556,12 +600,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 +870,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 +935,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 PD

[PATCH 06/13] mpt3sas: API 's to support NVMe drive addition to SML

2017-07-11 Thread Suganath Prabu S
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_wwid
mpt3sas_get_pdev_by_idchannel
mpt3sas_get_pdev_by_handle

mpt3sas_config_get_pcie_device_pg0
mpt3sas_config_get_pcie_device_pg2

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h   |   53 +++
 drivers/scsi/mpt3sas/mpt3sas_config.c |  100 ++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c  |  568 -
 3 files changed, 714 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 0f07b16..063977a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -563,6 +563,49 @@ struct _pcie_device {
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(>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(>refcount, pcie_device_free);
+}
+
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -1417,6 +1460,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 *
@@ -1455,6 +1502,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

[PATCH 01/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe

2017-07-11 Thread Suganath Prabu S
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 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |   68 +++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  291 ++
 2 files changed, 325 insertions(+), 34 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 099ab4c..60fa7b6 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -357,7 +357,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 +369,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 +510,48 @@ static inline void sas_device_put(struct _sas_device *s)
kref_put(>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;
+};
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -556,12 +600,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 +870,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 +935,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_i

[PATCH 04/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware.

2017-07-11 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |   30 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  468 +-
 2 files changed, 492 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index a64cfce..09fecd0 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)
@@ -6187,8 +6207,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 45b8d94..2a6a8e6 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3132,8 +3132,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;
@@ -3143,7 +3141,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,
@@ -3154,7 +3152,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);
 }
 
 /**
@@ -3238,6 +3237,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
+_scs

[PATCH 03/13] mpt3sas: Added support for nvme encapsulated request message.

2017-07-11 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c |   56 +++-
 drivers/scsi/mpt3sas/mpt3sas_base.h |1 +
 drivers/scsi/mpt3sas/mpt3sas_ctl.c  |   81 ++-
 3 files changed, 136 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index b67212c..a64cfce 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))) {
@@ -3079,6 +3086,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
@@ -3169,6 +3200,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
@@ -6001,11 +6053,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_h

[PATCH 04/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware.

2017-07-11 Thread Suganath Prabu S
* 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 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |   30 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  468 +-
 2 files changed, 492 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index a64cfce..09fecd0 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)
@@ -6187,8 +6207,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 45b8d94..2a6a8e6 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3132,8 +3132,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;
@@ -3143,7 +3141,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,
@@ -3154,7 +3152,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);
 }
 
 /**
@@ -3238,6 +3237,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,

[PATCH 03/13] mpt3sas: Added support for nvme encapsulated request message.

2017-07-11 Thread Suganath Prabu S
* 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 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c |   56 +++-
 drivers/scsi/mpt3sas/mpt3sas_base.h |1 +
 drivers/scsi/mpt3sas/mpt3sas_ctl.c  |   81 ++-
 3 files changed, 136 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index b67212c..a64cfce 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))) {
@@ -3079,6 +3086,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
@@ -3169,6 +3200,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
@@ -6001,11 +6053,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_nv

[PATCH 02/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe devices

2017-07-11 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  623 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |   43 +++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   12 +-
 4 files changed, 666 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 18039bb..b67212c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include /* To get host page size per arch */
 #include 
 
 
@@ -1347,6 +1348,502 @@ _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;

[PATCH 02/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe devices

2017-07-11 Thread Suganath Prabu S
* 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 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  623 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |   43 +++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   12 +-
 4 files changed, 666 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 18039bb..b67212c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include /* To get host page size per arch */
 #include 
 
 
@@ -1347,6 +1348,502 @@ _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

[PATCH 00/13]mpt3sas driver NVMe support:

2017-07-11 Thread Suganath Prabu S
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: 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: Handle NVMe PCIe device related events generated
from firmware.
  mpt3sas: Set NVMe device queue depth as 128
  mpt3sas: API 's to support NVMe drive addition to SML
  mpt3sas: API's to remove nvme drive from sml
  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 MPI Header
  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  |  709 +++-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  176 +++-
 drivers/scsi/mpt3sas/mpt3sas_config.c|  100 ++
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  170 +++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 1871 --
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 12 files changed, 4081 insertions(+), 135 deletions(-)
 create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h

Thanks,
Suganath Prabu S


[PATCH 00/13]mpt3sas driver NVMe support:

2017-07-11 Thread Suganath Prabu S
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: 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: Handle NVMe PCIe device related events generated
from firmware.
  mpt3sas: Set NVMe device queue depth as 128
  mpt3sas: API 's to support NVMe drive addition to SML
  mpt3sas: API's to remove nvme drive from sml
  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 MPI Header
  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  |  709 +++-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  176 +++-
 drivers/scsi/mpt3sas/mpt3sas_config.c|  100 ++
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  170 +++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 1871 --
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 12 files changed, 4081 insertions(+), 135 deletions(-)
 create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h

Thanks,
Suganath Prabu S


[PATCH 03/13] mpt3sas: Added support for nvme encapsulated request message.

2017-06-29 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c |   56 +++-
 drivers/scsi/mpt3sas/mpt3sas_base.h |1 +
 drivers/scsi/mpt3sas/mpt3sas_ctl.c  |   81 ++-
 3 files changed, 136 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index b67212c..a64cfce 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))) {
@@ -3079,6 +3086,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
@@ -3169,6 +3200,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
@@ -6001,11 +6053,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_h

[PATCH 03/13] mpt3sas: Added support for nvme encapsulated request message.

2017-06-29 Thread Suganath Prabu S
* 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 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c |   56 +++-
 drivers/scsi/mpt3sas/mpt3sas_base.h |1 +
 drivers/scsi/mpt3sas/mpt3sas_ctl.c  |   81 ++-
 3 files changed, 136 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index b67212c..a64cfce 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))) {
@@ -3079,6 +3086,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
@@ -3169,6 +3200,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
@@ -6001,11 +6053,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_nv

[PATCH 08/13] mpt3sas: scan and add nvme device after controller reset

2017-06-29 Thread Suganath Prabu S
After Controller reset, Scan and add nvme device back to the topology.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  196 +-
 1 files changed, 191 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 68aa102..7100ee8 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4867,6 +4867,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;
@@ -4999,6 +5000,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) {
@@ -5045,11 +5068,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd,
struct sense_info data;
_scsih_normalize_sense(scmd->sense_buffer, );
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 *)_info;
@@ -6931,7 +6953,7 @@ _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
pcie_device_pg0.AccessStatus))
return 0;
 
-   if (!(_scsih_is_nvme_device(pcie_device_pg0.DeviceInfo)))
+   if (!(_scsih_is_nvme_device(le32_to_cpu(pcie_device_pg0.DeviceInfo
return 0;
 
pcie_device = mpt3sas_get_pdev_by_wwid(ioc, wwid);
@@ -8510,6 +8532,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(>pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, >pcie_device_list, list) {

[PATCH 08/13] mpt3sas: scan and add nvme device after controller reset

2017-06-29 Thread Suganath Prabu S
After Controller reset, Scan and add nvme device back to the topology.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  196 +-
 1 files changed, 191 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 68aa102..7100ee8 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4867,6 +4867,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;
@@ -4999,6 +5000,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) {
@@ -5045,11 +5068,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd,
struct sense_info data;
_scsih_normalize_sense(scmd->sense_buffer, );
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 *)_info;
@@ -6931,7 +6953,7 @@ _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
pcie_device_pg0.AccessStatus))
return 0;
 
-   if (!(_scsih_is_nvme_device(pcie_device_pg0.DeviceInfo)))
+   if (!(_scsih_is_nvme_device(le32_to_cpu(pcie_device_pg0.DeviceInfo
return 0;
 
pcie_device = mpt3sas_get_pdev_by_wwid(ioc, wwid);
@@ -8510,6 +8532,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(>pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, >pcie_device_list, list) {
+   if ((pcie_device->wwid == pcie_device_pg0->WW

[PATCH 09/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives.

2017-06-29 Thread Suganath Prabu S
Added debug information for NVMe/PCIe drives in target rest path.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   86 --
 1 files changed, 72 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 7100ee8..b96da33 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -690,7 +690,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;
@@ -1208,6 +1208,7 @@ _scsih_pcie_device_init_add(struct MPT3SAS_ADAPTER *ioc,
_scsih_determine_boot_device(ioc, pcie_device, PCIE_CHANNEL);
spin_unlock_irqrestore(>pcie_device_lock, flags);
 }
+
 /**
  * _scsih_raid_device_find_by_id - raid device search
  * @ioc: per adapter object
@@ -2891,6 +2892,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;
 
@@ -2907,6 +2909,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(>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(>pcie_device_lock, flags);
+
} else {
spin_lock_irqsave(>sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
@@ -3650,6 +3677,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;
@@ -3692,24 +3720,52 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
sas_address = sas_device->sas_address;
}
spin_unlock_irqrestore(>sas_device_lock, flags);
-
+   if (!sas_device) {
+   spin_lock_irqsave(>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(>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, ha

[PATCH 09/13] mpt3as: Add-Task-management-debug-info-for-NVMe-drives.

2017-06-29 Thread Suganath Prabu S
Added debug information for NVMe/PCIe drives in target rest path.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   86 --
 1 files changed, 72 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 7100ee8..b96da33 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -690,7 +690,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;
@@ -1208,6 +1208,7 @@ _scsih_pcie_device_init_add(struct MPT3SAS_ADAPTER *ioc,
_scsih_determine_boot_device(ioc, pcie_device, PCIE_CHANNEL);
spin_unlock_irqrestore(>pcie_device_lock, flags);
 }
+
 /**
  * _scsih_raid_device_find_by_id - raid device search
  * @ioc: per adapter object
@@ -2891,6 +2892,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;
 
@@ -2907,6 +2909,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(>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(>pcie_device_lock, flags);
+
} else {
spin_lock_irqsave(>sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
@@ -3650,6 +3677,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;
@@ -3692,24 +3720,52 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
sas_address = sas_device->sas_address;
}
spin_unlock_irqrestore(>sas_device_lock, flags);
-
+   if (!sas_device) {
+   spin_lock_irqsave(>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(>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

[PATCH 13/13] mpt3sas: Update mpt3sas driver version.

2017-06-29 Thread Suganath Prabu S
Updated mpt3sas driver version to 15.101.00.00

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index ea6e607..835d6da 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -74,11 +74,11 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies <mpt-fusionlinux@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_VERSION00
+#define MPT3SAS_RELEASE_VERSION0
 
 #define MPT2SAS_DRIVER_NAME"mpt2sas"
 #define MPT2SAS_DESCRIPTION"LSI MPT Fusion SAS 2.0 Device Driver"
-- 
1.7.1



[PATCH 13/13] mpt3sas: Update mpt3sas driver version.

2017-06-29 Thread Suganath Prabu S
Updated mpt3sas driver version to 15.101.00.00

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index ea6e607..835d6da 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -74,11 +74,11 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies "
 #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_VERSION00
+#define MPT3SAS_RELEASE_VERSION0
 
 #define MPT2SAS_DRIVER_NAME"mpt2sas"
 #define MPT2SAS_DESCRIPTION"LSI MPT Fusion SAS 2.0 Device Driver"
-- 
1.7.1



[PATCH 12/13] mpt3sas: Update MPI Header

2017-06-29 Thread Suganath Prabu S
Update MPI Files for NVMe support

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -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(0x

[PATCH 12/13] mpt3sas: Update MPI Header

2017-06-29 Thread Suganath Prabu S
Update MPI Files for NVMe support

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 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(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -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

[PATCH 11/13] mpt3sas: Fix nvme drives checking for tlr.

2017-06-29 Thread Suganath Prabu S
Check for NVMe drives before enabling or checking tlr.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@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 b96da33..4d71ef7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2013,6 +2013,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
@@ -4810,8 +4818,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(>device->sdev_gendev)
-   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
+   if (((!ioc->is_warpdrive && !scsih_is_raid(>device->sdev_gendev))
+   && !scsih_is_nvme(>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);
@@ -4856,8 +4865,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) {
@@ -5405,9 +5414,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(>device->sdev_gendev) &&
-   sas_is_tlr_enabled(scmd->device) &&
+   !scsih_is_nvme(>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



[PATCH 11/13] mpt3sas: Fix nvme drives checking for tlr.

2017-06-29 Thread Suganath Prabu S
Check for NVMe drives before enabling or checking tlr.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 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 b96da33..4d71ef7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2013,6 +2013,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
@@ -4810,8 +4818,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(>device->sdev_gendev)
-   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
+   if (((!ioc->is_warpdrive && !scsih_is_raid(>device->sdev_gendev))
+   && !scsih_is_nvme(>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);
@@ -4856,8 +4865,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) {
@@ -5405,9 +5414,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(>device->sdev_gendev) &&
-   sas_is_tlr_enabled(scmd->device) &&
+   !scsih_is_nvme(>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



[PATCH 10/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info

2017-06-29 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |3 +-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |   88 --
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 3 files changed, 61 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 063977a..ea6e607 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -452,6 +452,7 @@ struct _internal_cmd {
struct completion done;
void*reply;
void*sense;
+   u64 *nvme_error_response;
u16 status;
u16 smid;
 };
@@ -1615,7 +1616,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 35e5c30..269c753 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, >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(>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(>sas_device_lock, flags);
if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)
pr_info(MPT3SAS_FMT
"\tscsi_state(0x%02x), scsi_status"
@@ -1375,6 +1365,42 @@ _ctl_btdh_search_sas_device(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _ctl_btdh_sea

[PATCH 10/13] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info

2017-06-29 Thread Suganath Prabu S
* 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 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |3 +-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |   88 --
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 3 files changed, 61 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 063977a..ea6e607 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -452,6 +452,7 @@ struct _internal_cmd {
struct completion done;
void*reply;
void*sense;
+   u64 *nvme_error_response;
u16 status;
u16 smid;
 };
@@ -1615,7 +1616,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 35e5c30..269c753 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, >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(>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(>sas_device_lock, flags);
if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)
pr_info(MPT3SAS_FMT
"\tscsi_state(0x%02x), scsi_status"
@@ -1375,6 +1365,42 @@ _ctl_btdh_search_sas_device(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _ctl_btdh_search_pcie_device - searching for pcie device
+ * @ioc: per adapter obje

[PATCH 07/13] mpt3sas: API's to remove nvme drive from sml

2017-06-29 Thread Suganath Prabu S
Below API's are included in nvme drive remove path.
_scsih_pcie_device_remove
_scsih_pcie_device_remove_by_handle
_scsih_pcie_device_remove_from_sml

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index e52bebe..68aa102 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -73,7 +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 */
@@ -1048,6 +1049,86 @@ mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc, 
u16 handle)
 
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(>pcie_device_lock, flags);
+   if (!list_empty(_device->list)) {
+   list_del_init(_device->list);
+   was_on_pcie_device_list = 1;
+   }
+   spin_unlock_irqrestore(>pcie_device_lock, flags);
+   if (was_on_pcie_device_list) {
+   kfree(pcie_device->serial_number);
+   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(>pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device) {
+   if (!list_empty(_device->list)) {
+   list_del_init(_device->list);
+   was_on_pcie_device_list = 1;
+   pcie_device_put(pcie_device);
+   }
+   }
+   spin_unlock_irqrestore(>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
@@ -6630,6 +6711,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)
+   

[PATCH 07/13] mpt3sas: API's to remove nvme drive from sml

2017-06-29 Thread Suganath Prabu S
Below API's are included in nvme drive remove path.
_scsih_pcie_device_remove
_scsih_pcie_device_remove_by_handle
_scsih_pcie_device_remove_from_sml

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  190 +-
 1 files changed, 188 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index e52bebe..68aa102 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -73,7 +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 */
@@ -1048,6 +1049,86 @@ mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc, 
u16 handle)
 
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(>pcie_device_lock, flags);
+   if (!list_empty(_device->list)) {
+   list_del_init(_device->list);
+   was_on_pcie_device_list = 1;
+   }
+   spin_unlock_irqrestore(>pcie_device_lock, flags);
+   if (was_on_pcie_device_list) {
+   kfree(pcie_device->serial_number);
+   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(>pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device) {
+   if (!list_empty(_device->list)) {
+   list_del_init(_device->list);
+   was_on_pcie_device_list = 1;
+   pcie_device_put(pcie_device);
+   }
+   }
+   spin_unlock_irqrestore(>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
@@ -6630,6 +6711,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)
+

[PATCH 02/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe devices

2017-06-29 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  623 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |   43 +++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   12 +-
 4 files changed, 666 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 18039bb..b67212c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include /* To get host page size per arch */
 #include 
 
 
@@ -1347,6 +1348,502 @@ _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;

[PATCH 02/13] mpt3sas: SGL to PRP Translation for I/Os to NVMe devices

2017-06-29 Thread Suganath Prabu S
* 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 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  623 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |   43 +++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   12 +-
 4 files changed, 666 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 18039bb..b67212c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include /* To get host page size per arch */
 #include 
 
 
@@ -1347,6 +1348,502 @@ _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

[PATCH 04/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware.

2017-06-29 Thread Suganath Prabu S
* 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.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |   30 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  468 +-
 2 files changed, 492 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index a64cfce..09fecd0 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)
@@ -6187,8 +6207,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 45b8d94..2a6a8e6 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3132,8 +3132,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;
@@ -3143,7 +3141,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,
@@ -3154,7 +3152,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);
 }
 
 /**
@@ -3238,6 +3237,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
+_scs

[PATCH 06/13] mpt3sas: API 's to support NVMe drive addition to SML

2017-06-29 Thread Suganath Prabu S
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_wwid
mpt3sas_get_pdev_by_idchannel
mpt3sas_get_pdev_by_handle

mpt3sas_config_get_pcie_device_pg0
mpt3sas_config_get_pcie_device_pg2

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h   |   53 +++
 drivers/scsi/mpt3sas/mpt3sas_config.c |  100 ++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c  |  568 -
 3 files changed, 714 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 0f07b16..063977a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -563,6 +563,49 @@ struct _pcie_device {
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(>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(>refcount, pcie_device_free);
+}
+
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -1417,6 +1460,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 *
@@ -1455,6 +1502,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 
*io

[PATCH 04/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware.

2017-06-29 Thread Suganath Prabu S
* 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 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |   30 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  468 +-
 2 files changed, 492 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index a64cfce..09fecd0 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)
@@ -6187,8 +6207,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 45b8d94..2a6a8e6 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3132,8 +3132,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;
@@ -3143,7 +3141,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,
@@ -3154,7 +3152,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);
 }
 
 /**
@@ -3238,6 +3237,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,

<    1   2   3   >