[PATCH 00/10] mpt3sas driver Enhancements and

2016-10-20 Thread Suganath Prabu S
Here is the change list:
Posting 10 patches for mpt3sas driver enhancements and few fixes.
  * Added Device ID's for SAS35 devices and updated MPI Header.
  * Support "EEDP Escape flag" for SAS35 devices.
  * fixed improper printk statement.
  * Regardless of whether RDPQ disabled card is enumerated
first or RDPQ enabled card is enumerated first, MSIX vectors
depends on the cards capability.
  * device_remove_in_progress bit check has been added in IOCTL path. If
bit is set, then IOCTL will be failed printing failure message.
  * Started using the Atomic Request Descriptors for
SAS35 devices.
  * For SAS35 devices MSIX vectors are inceased to 128 from 96.
  * Fixing Endianness issue.
  * Updated driver version to 14.100.00.00

Suganath Prabu S (10):
  mpt3sas: Fix for improper info displayed in var log,  while
blocking or  unblocking the device.
  mpt3sas: Fix for incorrect numbers for MSIX vectors  enabled when 
non RDPQ card is enumerated first.
  mpt3sas: Implement device_remove_in_progress check in  IOCTL path
  mpt3sas: Removing unused macro "MPT_DEVICE_TLR_ON"
  mpt3sas: Bump driver version as "14.100.00.00"
  mpt3sas: Added Device ID's for SAS35 devices and  updated MPI
header.
  mpt3sas: Increased/Additional MSIX support for SAS35  devices.
  mpt3sas: set EEDP-escape-flags for SAS35 devices.
  mpt3sas: Use the new MPI 2.6 32-bit Atomic Request  Descriptors
for SAS35 devices.
  mpt3sas: Fix for Endianness issue.

 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |   7 ++
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 186 ++-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  37 +++---
 drivers/scsi/mpt3sas/mpt3sas_config.c|   2 +-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  69 +---
 drivers/scsi/mpt3sas/mpt3sas_ctl.h   |   1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 113 +++
 drivers/scsi/mpt3sas/mpt3sas_transport.c |   8 +-
 8 files changed, 333 insertions(+), 90 deletions(-)

Thanks,
Suganath prabu S 
-- 
1.8.3.1



[PATCH 03/10] mpt3sas: Implement device_remove_in_progress check in IOCTL path

2016-10-20 Thread Suganath Prabu S
When device missing event arrives, device_remove_in_progress bit will be
set and hence driver has to stop sending IOCTL commands.Now the check has
been added in IOCTL path to test device_remove_in_progress bit is set, if
so then IOCTL will be failed printing failure message.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 19 +++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  5 
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 46 ++--
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 24 ++-
 4 files changed, 86 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 4ea81e1..9ad7f7c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -5334,6 +5334,21 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
goto out_free_resources;
}
 
+   /* allocate memory for pending OS device add list */
+   ioc->pend_os_device_add_sz = (ioc->facts.MaxDevHandle / 8);
+   if (ioc->facts.MaxDevHandle % 8)
+   ioc->pend_os_device_add_sz++;
+   ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz,
+   GFP_KERNEL);
+   if (!ioc->pend_os_device_add)
+   goto out_free_resources;
+
+   ioc->device_remove_in_progress_sz = ioc->pend_os_device_add_sz;
+   ioc->device_remove_in_progress =
+   kzalloc(ioc->device_remove_in_progress_sz, GFP_KERNEL);
+   if (!ioc->device_remove_in_progress)
+   goto out_free_resources;
+
ioc->fwfault_debug = mpt3sas_fwfault_debug;
 
/* base internal command bits */
@@ -5416,6 +5431,8 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
kfree(ioc->reply_post_host_index);
kfree(ioc->pd_handles);
kfree(ioc->blocking_handles);
+   kfree(ioc->device_remove_in_progress);
+   kfree(ioc->pend_os_device_add);
kfree(ioc->tm_cmds.reply);
kfree(ioc->transport_cmds.reply);
kfree(ioc->scsih_cmds.reply);
@@ -5457,6 +5474,8 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc)
kfree(ioc->reply_post_host_index);
kfree(ioc->pd_handles);
kfree(ioc->blocking_handles);
+   kfree(ioc->device_remove_in_progress);
+   kfree(ioc->pend_os_device_add);
kfree(ioc->pfacts);
kfree(ioc->ctl_cmds.reply);
kfree(ioc->ctl_cmds.sense);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 3e71bc1..4221a4d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1079,6 +1079,9 @@ struct MPT3SAS_ADAPTER {
void*pd_handles;
u16 pd_handles_sz;
 
+   void*pend_os_device_add;
+   u16 pend_os_device_add_sz;
+
/* config page */
u16 config_page_sz;
void*config_page;
@@ -1187,6 +1190,8 @@ struct MPT3SAS_ADAPTER {
struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event;
struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi;
struct SL_WH_MPI_TRIGGERS_T diag_trigger_mpi;
+   void*device_remove_in_progress;
+   u16 device_remove_in_progress_sz;
 };
 
 typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index,
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 26cdc12..f204ce1 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -654,6 +654,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct 
mpt3_ioctl_command karg,
size_t data_in_sz = 0;
long ret;
u16 wait_state_count;
+   u16 device_handle = MPT3SAS_INVALID_DEVICE_HANDLE;
 
issue_reset = 0;
 
@@ -738,10 +739,13 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct 
mpt3_ioctl_command karg,
data_in_sz = karg.data_in_size;
 
if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
-   mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
-   if (!le16_to_cpu(mpi_request->FunctionDependent1) ||
-   le16_to_cpu(mpi_request->FunctionDependent1) >
-   ioc->facts.MaxDevHandle) {
+   mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH ||
+   mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT ||
+   mpi_request->Function == MPI2_FUNCTION_SATA_PASSTHROUGH) {
+
+   device_handle = le16_to_cpu(mpi_request->FunctionDependent1);
+

[PATCH 05/10] mpt3sas: Bump driver version as "14.100.00.00"

2016-10-20 Thread Suganath Prabu S
Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index e923c91..6f03a86 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -73,8 +73,8 @@
 #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 "13.100.00.00"
-#define MPT3SAS_MAJOR_VERSION  13
+#define MPT3SAS_DRIVER_VERSION "14.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  14
 #define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
-- 
1.8.3.1



[PATCH 02/10] mpt3sas: Fix for incorrect numbers for MSIX vectors enabled when non RDPQ card is enumerated first.

2016-10-20 Thread Suganath Prabu S
No. of MSIX vectors supported = min (Total no. of CPU cores,
MSIX vectors supported by card)

when RDPQ is disabled "max_msix_vectors" module parameter which was
declared as global was set to '8' and hence if there are more than one card
in system among which if RDPQ disabled card is enumerated first then only 8
MSIX vectors was getting enabled for all the cards(including RDPQ enabled
card,which can support more than 8 MSIX vectors).

Used local variable instead of global variable ,if RDPQ is disabled this
local variable is set to '8' else it is set to "max_msix_vectors" (by
default this is set to -1, whose value can be set by user during driver
load time).So now regardless of whether RDPQ disabled card is enumerated
first or RDPQ enabled card is enumerated first , MSIX vectors enabled
depends on the cards capability.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index a1a5ceb..4ea81e1 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1959,7 +1959,7 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc)
 {
struct msix_entry *entries, *a;
int r;
-   int i;
+   int i, local_max_msix_vectors;
u8 try_msix = 0;
 
if (msix_disable == -1 || msix_disable == 0)
@@ -1979,13 +1979,15 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc)
  ioc->cpu_count, max_msix_vectors);
 
if (!ioc->rdpq_array_enable && max_msix_vectors == -1)
-   max_msix_vectors = 8;
+   local_max_msix_vectors = 8;
+   else
+   local_max_msix_vectors = max_msix_vectors;
 
-   if (max_msix_vectors > 0) {
-   ioc->reply_queue_count = min_t(int, max_msix_vectors,
+   if (local_max_msix_vectors > 0) {
+   ioc->reply_queue_count = min_t(int, local_max_msix_vectors,
ioc->reply_queue_count);
ioc->msix_vector_count = ioc->reply_queue_count;
-   } else if (max_msix_vectors == 0)
+   } else if (local_max_msix_vectors == 0)
goto try_ioapic;
 
if (ioc->msix_vector_count < ioc->cpu_count)
-- 
1.8.3.1



[PATCH 04/10] mpt3sas: Removing unused macro "MPT_DEVICE_TLR_ON"

2016-10-20 Thread Suganath Prabu S
Removing macro "MPT_DEVICE_TLR_ON" defined in header file as its unused

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 4221a4d..e923c91 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -375,7 +375,6 @@ struct MPT3SAS_TARGET {
  * per device private data
  */
 #define MPT_DEVICE_FLAGS_INIT  0x01
-#define MPT_DEVICE_TLR_ON  0x02
 
 #define MFG_PAGE10_HIDE_SSDS_MASK  (0x0003)
 #define MFG_PAGE10_HIDE_ALL_DISKS  (0x00)
-- 
1.8.3.1



[PATCH 06/10] mpt3sas: Added Device ID's for SAS35 devices and updated MPI header.

2016-10-20 Thread Suganath Prabu S
Added Device ID's for SAS35 devices (Ventura, Crusader, Harpoon &
Tomcat) and updated mpi header file for the same. Also added
"is_gen35_ioc" to MPT3SAS_ADAPTER structure for identifying SAS35 adapters.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  7 +++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  1 +
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  5 -
 drivers/scsi/mpt3sas/mpt3sas_ctl.h   |  1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 31 +++
 5 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
index 95356a8..fa61baf 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
@@ -478,6 +478,13 @@ typedef struct _MPI2_CONFIG_REPLY {
 #define MPI26_MFGPAGE_DEVID_SAS3324_3   (0x00C2)
 #define MPI26_MFGPAGE_DEVID_SAS3324_4   (0x00C3)
 
+#define MPI26_MFGPAGE_DEVID_SAS3516 (0x00AA)
+#define MPI26_MFGPAGE_DEVID_SAS3516_1   (0x00AB)
+#define MPI26_MFGPAGE_DEVID_SAS3416 (0x00AC)
+#define MPI26_MFGPAGE_DEVID_SAS3508 (0x00AD)
+#define MPI26_MFGPAGE_DEVID_SAS3508_1   (0x00AE)
+#define MPI26_MFGPAGE_DEVID_SAS3408 (0x00AF)
+
 /*Manufacturing Page 0 */
 
 typedef struct _MPI2_CONFIG_PAGE_MAN_0 {
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 6f03a86..3d75c57 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1191,6 +1191,7 @@ struct MPT3SAS_ADAPTER {
struct SL_WH_MPI_TRIGGERS_T diag_trigger_mpi;
void*device_remove_in_progress;
u16 device_remove_in_progress_sz;
+   u8  is_gen35_ioc;
 };
 
 typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index,
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index f204ce1..62be7d4 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -1096,7 +1096,10 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user 
*arg)
break;
case MPI25_VERSION:
case MPI26_VERSION:
-   karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3;
+   if (ioc->is_gen35_ioc)
+   karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS35;
+   else
+   karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3;
strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION);
break;
}
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
index 8940835..f3e17a8 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
@@ -143,6 +143,7 @@ struct mpt3_ioctl_pci_info {
 #define MPT2_IOCTL_INTERFACE_SAS2  (0x04)
 #define MPT2_IOCTL_INTERFACE_SAS2_SSS6200  (0x05)
 #define MPT3_IOCTL_INTERFACE_SAS3  (0x06)
+#define MPT3_IOCTL_INTERFACE_SAS35 (0x07)
 #define MPT2_IOCTL_VERSION_LENGTH  (32)
 
 /**
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 9584d6b..521849d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -8660,6 +8660,12 @@ _scsih_determine_hba_mpi_version(struct pci_dev *pdev)
case MPI26_MFGPAGE_DEVID_SAS3324_2:
case MPI26_MFGPAGE_DEVID_SAS3324_3:
case MPI26_MFGPAGE_DEVID_SAS3324_4:
+   case MPI26_MFGPAGE_DEVID_SAS3508:
+   case MPI26_MFGPAGE_DEVID_SAS3508_1:
+   case MPI26_MFGPAGE_DEVID_SAS3408:
+   case MPI26_MFGPAGE_DEVID_SAS3516:
+   case MPI26_MFGPAGE_DEVID_SAS3516_1:
+   case MPI26_MFGPAGE_DEVID_SAS3416:
return MPI26_VERSION;
}
return 0;
@@ -8728,6 +8734,18 @@ _scsih_probe(struct pci_dev *pdev, const struct 
pci_device_id *id)
ioc->hba_mpi_version_belonged = hba_mpi_version;
ioc->id = mpt3_ids++;
sprintf(ioc->driver_name, "%s", MPT3SAS_DRIVER_NAME);
+   switch (pdev->device) {
+   case MPI26_MFGPAGE_DEVID_SAS3508:
+   case MPI26_MFGPAGE_DEVID_SAS3508_1:
+   case MPI26_MFGPAGE_DEVID_SAS3408:
+   case MPI26_MFGPAGE_DEVID_SAS3516:
+   case MPI26_MFGPAGE_DEVID_SAS3516_1:
+   case MPI26_MFGPAGE_DEVID_SAS3416:
+   ioc->is_gen35_ioc = 1;
+   break;
+   default:
+   ioc->is_gen35_ioc = 0;
+   }
if ((ioc->hba_mpi_version_belonged == MPI25_VERSION &&
pdev

[PATCH 01/10] mpt3sas: Fix for improper info displayed in var log, while blocking or unblocking the device.

2016-10-20 Thread Suganath Prabu S
Return value and Device_handle Arguments passed in correct order
 to match with its format string.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 209a969..282ca40 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2837,7 +2837,7 @@ _scsih_internal_device_block(struct scsi_device *sdev,
if (r == -EINVAL)
sdev_printk(KERN_WARNING, sdev,
"device_block failed with return(%d) for handle(0x%04x)\n",
-   sas_device_priv_data->sas_target->handle, r);
+   r, sas_device_priv_data->sas_target->handle);
 }
 
 /**
@@ -2867,20 +2867,20 @@ _scsih_internal_device_unblock(struct scsi_device *sdev,
sdev_printk(KERN_WARNING, sdev,
"device_unblock failed with return(%d) for handle(0x%04x) "
"performing a block followed by an unblock\n",
-   sas_device_priv_data->sas_target->handle, r);
+   r, sas_device_priv_data->sas_target->handle);
sas_device_priv_data->block = 1;
r = scsi_internal_device_block(sdev);
if (r)
sdev_printk(KERN_WARNING, sdev, "retried device_block "
"failed with return(%d) for handle(0x%04x)\n",
-   sas_device_priv_data->sas_target->handle, r);
+   r, sas_device_priv_data->sas_target->handle);
 
sas_device_priv_data->block = 0;
r = scsi_internal_device_unblock(sdev, SDEV_RUNNING);
if (r)
sdev_printk(KERN_WARNING, sdev, "retried device_unblock"
" failed with return(%d) for handle(0x%04x)\n",
-   sas_device_priv_data->sas_target->handle, r);
+   r, sas_device_priv_data->sas_target->handle);
}
 }
 
-- 
1.8.3.1



[PATCH 10/10] mpt3sas: Fix for Endianness issue.

2016-10-20 Thread Suganath Prabu S
Use le16_to_cpu only for accessing two byte data provided by controller.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 6d17f66..981be7b 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -5384,10 +5384,10 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc,
sas_device->handle, handle);
sas_target_priv_data->handle = handle;
sas_device->handle = handle;
-   if (sas_device_pg0.Flags &
+   if (le16_to_cpu(sas_device_pg0.Flags) &
 MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) {
sas_device->enclosure_level =
-   le16_to_cpu(sas_device_pg0.EnclosureLevel);
+   sas_device_pg0.EnclosureLevel;
memcpy(sas_device->connector_name,
sas_device_pg0.ConnectorName, 4);
sas_device->connector_name[4] = '\0';
@@ -5516,9 +5516,10 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle, u8 phy_num,
sas_device->fast_path = (le16_to_cpu(sas_device_pg0.Flags) &
MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) ? 1 : 0;
 
-   if (sas_device_pg0.Flags & MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) {
+   if (le16_to_cpu(sas_device_pg0.Flags)
+   & MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) {
sas_device->enclosure_level =
-   le16_to_cpu(sas_device_pg0.EnclosureLevel);
+   sas_device_pg0.EnclosureLevel;
memcpy(sas_device->connector_name,
sas_device_pg0.ConnectorName, 4);
sas_device->connector_name[4] = '\0';
@@ -7056,7 +7057,7 @@ Mpi2SasDevicePage0_t *sas_device_pg0)
if (sas_device_pg0->Flags &
  MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) {
sas_device->enclosure_level =
-  le16_to_cpu(sas_device_pg0->EnclosureLevel);
+  sas_device_pg0->EnclosureLevel;
memcpy(_device->connector_name[0],
_device_pg0->ConnectorName[0], 4);
} else {
@@ -7118,6 +7119,7 @@ _scsih_search_responding_sas_devices(struct 
MPT3SAS_ADAPTER *ioc)
sas_device_pg0.SASAddress =
le64_to_cpu(sas_device_pg0.SASAddress);
sas_device_pg0.Slot = le16_to_cpu(sas_device_pg0.Slot);
+   sas_device_pg0.Flags = le16_to_cpu(sas_device_pg0.Flags);
_scsih_mark_responding_sas_device(ioc, _device_pg0);
}
 
-- 
1.8.3.1



[PATCH 07/10] mpt3sas: Increased/Additional MSIX support for SAS35 devices.

2016-10-20 Thread Suganath Prabu S
For SAS35 devices MSIX vectors are inceased to 128 from 96. To support this
Reply post host index register count is increased to 16. Also variable
msix96_vector is replaced with combined_reply_queue and variable
combined_reply_index_count is added to set different values for SAS3 and
SAS35 devices.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 14 +++---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  8 +---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 11 +--
 3 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 9ad7f7c..43cdc02 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1078,7 +1078,7 @@ _base_interrupt(int irq, void *bus_id)
 * new reply host index value in ReplyPostIndex Field and msix_index
 * value in MSIxIndex field.
 */
-   if (ioc->msix96_vector)
+   if (ioc->combined_reply_queue)
writel(reply_q->reply_post_host_index | ((msix_index  & 7) <<
MPI2_RPHI_MSIX_INDEX_SHIFT),
ioc->replyPostRegisterIndex[msix_index/8]);
@@ -2052,7 +2052,7 @@ mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc)
_base_free_irq(ioc);
_base_disable_msix(ioc);
 
-   if (ioc->msix96_vector) {
+   if (ioc->combined_reply_queue) {
kfree(ioc->replyPostRegisterIndex);
ioc->replyPostRegisterIndex = NULL;
}
@@ -2162,7 +2162,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
/* Use the Combined reply queue feature only for SAS3 C0 & higher
 * revision HBAs and also only when reply queue count is greater than 8
 */
-   if (ioc->msix96_vector && ioc->reply_queue_count > 8) {
+   if (ioc->combined_reply_queue && ioc->reply_queue_count > 8) {
/* Determine the Supplemental Reply Post Host Index Registers
 * Addresse. Supplemental Reply Post Host Index Registers
 * starts at offset MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET and
@@ -2170,7 +2170,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
 * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET from previous one.
 */
ioc->replyPostRegisterIndex = kcalloc(
-MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT,
+ioc->combined_reply_index_count,
 sizeof(resource_size_t *), GFP_KERNEL);
if (!ioc->replyPostRegisterIndex) {
dfailprintk(ioc, printk(MPT3SAS_FMT
@@ -2180,14 +2180,14 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
goto out_fail;
}
 
-   for (i = 0; i < MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT; i++) {
+   for (i = 0; i < ioc->combined_reply_index_count; i++) {
ioc->replyPostRegisterIndex[i] = (resource_size_t *)
 ((u8 *)>chip->Doorbell +
 MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET +
 (i * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET));
}
} else
-   ioc->msix96_vector = 0;
+   ioc->combined_reply_queue = 0;
 
if (ioc->is_warpdrive) {
ioc->reply_post_host_index[0] = (resource_size_t __iomem *)
@@ -5140,7 +5140,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc)
 
/* initialize reply post host index */
list_for_each_entry(reply_q, >reply_queue_list, list) {
-   if (ioc->msix96_vector)
+   if (ioc->combined_reply_queue)
writel((reply_q->msix_index & 7)<<
   MPI2_RPHI_MSIX_INDEX_SHIFT,
   ioc->replyPostRegisterIndex[reply_q->msix_index/8]);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 3d75c57..acb4106 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -300,8 +300,9 @@
  * There are twelve Supplemental Reply Post Host Index Registers
  * and each register is at offset 0x10 bytes from the previous one.
  */
-#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT 12
-#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET (0x10)
+#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G312
+#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G35   16
+#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET  (0x10)
 
 /* OEM Identifiers */
 #define MFG10_OEM_ID_INVALID   (

[PATCH 09/10] mpt3sas: Use the new MPI 2.6 32-bit Atomic Request Descriptors for SAS35 devices.

2016-10-20 Thread Suganath Prabu S
Support Atomic Request Descriptors for Ventura/SAS35 devices.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 141 +++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  18 ++--
 drivers/scsi/mpt3sas/mpt3sas_config.c|   2 +-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  22 ++---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  24 +++---
 drivers/scsi/mpt3sas/mpt3sas_transport.c |   8 +-
 6 files changed, 161 insertions(+), 54 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 43cdc02..f00ef88 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -849,7 +849,7 @@ _base_async_event(struct MPT3SAS_ADAPTER *ioc, u8 
msix_index, u32 reply)
ack_request->EventContext = mpi_reply->EventContext;
ack_request->VF_ID = 0;  /* TODO */
ack_request->VP_ID = 0;
-   mpt3sas_base_put_smid_default(ioc, smid);
+   ioc->put_smid_default(ioc, smid);
 
  out:
 
@@ -2464,15 +2464,15 @@ _base_writeq(__u64 b, volatile void __iomem *addr, 
spinlock_t *writeq_lock)
 #endif
 
 /**
- * mpt3sas_base_put_smid_scsi_io - send SCSI_IO request to firmware
+ * _base_put_smid_scsi_io - send SCSI_IO request to firmware
  * @ioc: per adapter object
  * @smid: system request message index
  * @handle: device handle
  *
  * Return nothing.
  */
-void
-mpt3sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 
handle)
+static void
+_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 handle)
 {
Mpi2RequestDescriptorUnion_t descriptor;
u64 *request = (u64 *)
@@ -2488,15 +2488,15 @@ mpt3sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER 
*ioc, u16 smid, u16 handle)
 }
 
 /**
- * mpt3sas_base_put_smid_fast_path - send fast path request to firmware
+ * _base_put_smid_fast_path - send fast path request to firmware
  * @ioc: per adapter object
  * @smid: system request message index
  * @handle: device handle
  *
  * Return nothing.
  */
-void
-mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+static void
+_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid,
u16 handle)
 {
Mpi2RequestDescriptorUnion_t descriptor;
@@ -2513,14 +2513,14 @@ mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER 
*ioc, u16 smid,
 }
 
 /**
- * mpt3sas_base_put_smid_hi_priority - send Task Managment request to firmware
+ * _base_put_smid_hi_priority - send Task Management request to firmware
  * @ioc: per adapter object
  * @smid: system request message index
  * @msix_task: msix_task will be same as msix of IO incase of task abort else 
0.
  * Return nothing.
  */
-void
-mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+static void
+_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
u16 msix_task)
 {
Mpi2RequestDescriptorUnion_t descriptor;
@@ -2537,14 +2537,14 @@ mpt3sas_base_put_smid_hi_priority(struct 
MPT3SAS_ADAPTER *ioc, u16 smid,
 }
 
 /**
- * mpt3sas_base_put_smid_default - Default, primarily used for config pages
+ * _base_put_smid_default - Default, primarily used for config pages
  * @ioc: per adapter object
  * @smid: system request message index
  *
  * Return nothing.
  */
-void
-mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+static void
+_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid)
 {
Mpi2RequestDescriptorUnion_t descriptor;
u64 *request = (u64 *)
@@ -2559,6 +2559,95 @@ mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER 
*ioc, u16 smid)
 }
 
 /**
+* _base_put_smid_scsi_io_atomic - send SCSI_IO request to firmware using
+*   Atomic Request Descriptor
+* @ioc: per adapter object
+* @smid: system request message index
+* @handle: device handle, unused in this function, for function type match
+*
+* Return nothing.
+*/
+static void
+_base_put_smid_scsi_io_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+   u16 handle)
+{
+   Mpi26AtomicRequestDescriptor_t descriptor;
+   u32 *request = (u32 *)
+
+   descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
+   descriptor.MSIxIndex = _base_get_msix_index(ioc);
+   descriptor.SMID = cpu_to_le16(smid);
+
+   writel(cpu_to_le32(*request), >chip->AtomicRequestDescriptorPost);
+}
+
+/**
+ * _base_put_smid_fast_path_atomic - send fast path request to firmware
+ * using Atomic Request Descriptor
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @handle: device handle, unused in this function, for function type match
+ * Return nothing
+ */
+static void
+_base_put_smid_fast_path_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+   u16 handle)
+{
+   Mpi26AtomicRequestDescriptor_t 

[PATCH 08/10] mpt3sas: set EEDP-escape-flags for SAS35 devices.

2016-10-20 Thread Suganath Prabu S
An UNMAP command on a PI formatted device will leave the Logical Block
Application Tag and Logical Block Reference Tag as all F's (for those LBAs
that are unmapped). To avoid IO errors if those LBAs are subsequently read
before they are written with valid tag fields, the MPI SCSI IO requests
need to set the EEDPFlags element EEDP Escape Mode field, Bits [7:6]
appropriately. A value of 2 should be set to disable all PI checks if the
Logical Block Application Tag is 0x for PI types 1 and 2.  A value
of 3 should be set to disable all PI checks if the Logical Block
Application Tag is 0x and the Logical Block Reference Tag is
0x for PI type 3.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index a1c541d..c58f326 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3989,6 +3989,9 @@ _scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct 
scsi_cmnd *scmd,
 
mpi_request_3v->EEDPBlockSize =
cpu_to_le16(scmd->device->sector_size);
+
+   if (ioc->is_gen35_ioc)
+   eedp_flags |= MPI25_SCSIIO_EEDPFLAGS_APPTAG_DISABLE_MODE;
mpi_request->EEDPFlags = cpu_to_le16(eedp_flags);
 }
 
-- 
1.8.3.1



[PATCH] mpt3sas: Fix for SATA drive in blocked state, after diag reset while ATA Passthrough command is outstanding.

2016-11-17 Thread Suganath Prabu S
While issuing any ATA Pass-through command to Firmware,
driver will block the device, it will unblock the device only if that
IO completes through ISR path. But if in-between any host reset
occurs then driver won't unblock the device and
device will be in blocked state.

Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index a250cfd..5c8f752 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3899,6 +3899,11 @@ _scsih_temp_threshold_events(struct MPT3SAS_ADAPTER *ioc,
}
 }
 
+static inline bool ata_12_16_cmd(struct scsi_cmnd *scmd)
+{
+   return (scmd->cmnd[0] == ATA_12 || scmd->cmnd[0] == ATA_16);
+}
+
 /**
  * _scsih_flush_running_cmds - completing outstanding commands.
  * @ioc: per adapter object
@@ -3920,6 +3925,9 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc)
if (!scmd)
continue;
count++;
+   if (ata_12_16_cmd(scmd))
+   scsi_internal_device_unblock(scmd->device,
+   SDEV_RUNNING);
mpt3sas_base_free_smid(ioc, smid);
scsi_dma_unmap(scmd);
if (ioc->pci_error_recovery)
@@ -4027,11 +4035,6 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 
ioc_status)
SAM_STAT_CHECK_CONDITION;
 }
 
-static inline bool ata_12_16_cmd(struct scsi_cmnd *scmd)
-{
-   return (scmd->cmnd[0] == ATA_12 || scmd->cmnd[0] == ATA_16);
-}
-
 /**
  * scsih_qcmd - main scsi request entry point
  * @scmd: pointer to scsi command object
-- 
2.4.3



[PATCH v2 06/11] mpt3sas: Added Device ID's for SAS35 devices and updated MPI header.

2016-10-26 Thread Suganath Prabu S
Added Device ID's for SAS35 devices (Ventura, Crusader, Harpoon &
Tomcat) and updated mpi header file for the same. Also added
"is_gen35_ioc" to MPT3SAS_ADAPTER structure for identifying SAS35 adapters.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
Reviewed-by: Tomas Henzl <the...@redhat.com>
---
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  7 +++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  1 +
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  5 -
 drivers/scsi/mpt3sas/mpt3sas_ctl.h   |  1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 31 +++
 5 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
index 95356a8..fa61baf 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
@@ -478,6 +478,13 @@ typedef struct _MPI2_CONFIG_REPLY {
 #define MPI26_MFGPAGE_DEVID_SAS3324_3   (0x00C2)
 #define MPI26_MFGPAGE_DEVID_SAS3324_4   (0x00C3)
 
+#define MPI26_MFGPAGE_DEVID_SAS3516 (0x00AA)
+#define MPI26_MFGPAGE_DEVID_SAS3516_1   (0x00AB)
+#define MPI26_MFGPAGE_DEVID_SAS3416 (0x00AC)
+#define MPI26_MFGPAGE_DEVID_SAS3508 (0x00AD)
+#define MPI26_MFGPAGE_DEVID_SAS3508_1   (0x00AE)
+#define MPI26_MFGPAGE_DEVID_SAS3408 (0x00AF)
+
 /*Manufacturing Page 0 */
 
 typedef struct _MPI2_CONFIG_PAGE_MAN_0 {
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 6f03a86..3d75c57 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1191,6 +1191,7 @@ struct MPT3SAS_ADAPTER {
struct SL_WH_MPI_TRIGGERS_T diag_trigger_mpi;
void*device_remove_in_progress;
u16 device_remove_in_progress_sz;
+   u8  is_gen35_ioc;
 };
 
 typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index,
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index de720c9..a287bfb 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -1096,7 +1096,10 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user 
*arg)
break;
case MPI25_VERSION:
case MPI26_VERSION:
-   karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3;
+   if (ioc->is_gen35_ioc)
+   karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS35;
+   else
+   karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3;
strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION);
break;
}
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
index 8940835..f3e17a8 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
@@ -143,6 +143,7 @@ struct mpt3_ioctl_pci_info {
 #define MPT2_IOCTL_INTERFACE_SAS2  (0x04)
 #define MPT2_IOCTL_INTERFACE_SAS2_SSS6200  (0x05)
 #define MPT3_IOCTL_INTERFACE_SAS3  (0x06)
+#define MPT3_IOCTL_INTERFACE_SAS35 (0x07)
 #define MPT2_IOCTL_VERSION_LENGTH  (32)
 
 /**
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 9584d6b..521849d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -8660,6 +8660,12 @@ _scsih_determine_hba_mpi_version(struct pci_dev *pdev)
case MPI26_MFGPAGE_DEVID_SAS3324_2:
case MPI26_MFGPAGE_DEVID_SAS3324_3:
case MPI26_MFGPAGE_DEVID_SAS3324_4:
+   case MPI26_MFGPAGE_DEVID_SAS3508:
+   case MPI26_MFGPAGE_DEVID_SAS3508_1:
+   case MPI26_MFGPAGE_DEVID_SAS3408:
+   case MPI26_MFGPAGE_DEVID_SAS3516:
+   case MPI26_MFGPAGE_DEVID_SAS3516_1:
+   case MPI26_MFGPAGE_DEVID_SAS3416:
return MPI26_VERSION;
}
return 0;
@@ -8728,6 +8734,18 @@ _scsih_probe(struct pci_dev *pdev, const struct 
pci_device_id *id)
ioc->hba_mpi_version_belonged = hba_mpi_version;
ioc->id = mpt3_ids++;
sprintf(ioc->driver_name, "%s", MPT3SAS_DRIVER_NAME);
+   switch (pdev->device) {
+   case MPI26_MFGPAGE_DEVID_SAS3508:
+   case MPI26_MFGPAGE_DEVID_SAS3508_1:
+   case MPI26_MFGPAGE_DEVID_SAS3408:
+   case MPI26_MFGPAGE_DEVID_SAS3516:
+   case MPI26_MFGPAGE_DEVID_SAS3516_1:
+   case MPI26_MFGPAGE_DEVID_SAS3416:
+   ioc->is_gen35_ioc = 1;
+   break;
+   default:
+   ioc->is_gen35_ioc = 0;
+ 

[PATCH v2 11/11] mpt3sas: Bump driver version as "14.101.00.00"

2016-10-26 Thread Suganath Prabu S
Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 5d9ae15..8de0eda 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -73,9 +73,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 "14.100.00.00"
+#define MPT3SAS_DRIVER_VERSION "14.101.00.00"
 #define MPT3SAS_MAJOR_VERSION  14
-#define MPT3SAS_MINOR_VERSION  100
+#define MPT3SAS_MINOR_VERSION  101
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
 
-- 
2.4.3



[PATCH v2 09/11] mpt3sas: Use the new MPI 2.6 32-bit Atomic Request Descriptors for SAS35 devices.

2016-10-26 Thread Suganath Prabu S
Support Atomic Request Descriptors for Ventura/SAS35 devices.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
Reviewed-by: Tomas Henzl <the...@redhat.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 141 +++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  18 ++--
 drivers/scsi/mpt3sas/mpt3sas_config.c|   2 +-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  22 ++---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  24 +++---
 drivers/scsi/mpt3sas/mpt3sas_transport.c |   8 +-
 6 files changed, 161 insertions(+), 54 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 43cdc02..f00ef88 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -849,7 +849,7 @@ _base_async_event(struct MPT3SAS_ADAPTER *ioc, u8 
msix_index, u32 reply)
ack_request->EventContext = mpi_reply->EventContext;
ack_request->VF_ID = 0;  /* TODO */
ack_request->VP_ID = 0;
-   mpt3sas_base_put_smid_default(ioc, smid);
+   ioc->put_smid_default(ioc, smid);
 
  out:
 
@@ -2464,15 +2464,15 @@ _base_writeq(__u64 b, volatile void __iomem *addr, 
spinlock_t *writeq_lock)
 #endif
 
 /**
- * mpt3sas_base_put_smid_scsi_io - send SCSI_IO request to firmware
+ * _base_put_smid_scsi_io - send SCSI_IO request to firmware
  * @ioc: per adapter object
  * @smid: system request message index
  * @handle: device handle
  *
  * Return nothing.
  */
-void
-mpt3sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 
handle)
+static void
+_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 handle)
 {
Mpi2RequestDescriptorUnion_t descriptor;
u64 *request = (u64 *)
@@ -2488,15 +2488,15 @@ mpt3sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER 
*ioc, u16 smid, u16 handle)
 }
 
 /**
- * mpt3sas_base_put_smid_fast_path - send fast path request to firmware
+ * _base_put_smid_fast_path - send fast path request to firmware
  * @ioc: per adapter object
  * @smid: system request message index
  * @handle: device handle
  *
  * Return nothing.
  */
-void
-mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+static void
+_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid,
u16 handle)
 {
Mpi2RequestDescriptorUnion_t descriptor;
@@ -2513,14 +2513,14 @@ mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER 
*ioc, u16 smid,
 }
 
 /**
- * mpt3sas_base_put_smid_hi_priority - send Task Managment request to firmware
+ * _base_put_smid_hi_priority - send Task Management request to firmware
  * @ioc: per adapter object
  * @smid: system request message index
  * @msix_task: msix_task will be same as msix of IO incase of task abort else 
0.
  * Return nothing.
  */
-void
-mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+static void
+_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid,
u16 msix_task)
 {
Mpi2RequestDescriptorUnion_t descriptor;
@@ -2537,14 +2537,14 @@ mpt3sas_base_put_smid_hi_priority(struct 
MPT3SAS_ADAPTER *ioc, u16 smid,
 }
 
 /**
- * mpt3sas_base_put_smid_default - Default, primarily used for config pages
+ * _base_put_smid_default - Default, primarily used for config pages
  * @ioc: per adapter object
  * @smid: system request message index
  *
  * Return nothing.
  */
-void
-mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+static void
+_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid)
 {
Mpi2RequestDescriptorUnion_t descriptor;
u64 *request = (u64 *)
@@ -2559,6 +2559,95 @@ mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER 
*ioc, u16 smid)
 }
 
 /**
+* _base_put_smid_scsi_io_atomic - send SCSI_IO request to firmware using
+*   Atomic Request Descriptor
+* @ioc: per adapter object
+* @smid: system request message index
+* @handle: device handle, unused in this function, for function type match
+*
+* Return nothing.
+*/
+static void
+_base_put_smid_scsi_io_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+   u16 handle)
+{
+   Mpi26AtomicRequestDescriptor_t descriptor;
+   u32 *request = (u32 *)
+
+   descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
+   descriptor.MSIxIndex = _base_get_msix_index(ioc);
+   descriptor.SMID = cpu_to_le16(smid);
+
+   writel(cpu_to_le32(*request), >chip->AtomicRequestDescriptorPost);
+}
+
+/**
+ * _base_put_smid_fast_path_atomic - send fast path request to firmware
+ * using Atomic Request Descriptor
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @handle: device handle, unused in this function, for function type match
+ * Return nothing
+ */
+static void
+_base_put_smid_fast_path_atomic(struct

[PATCH v2 10/11] mpt3sas: Fix for Endianness issue.

2016-10-26 Thread Suganath Prabu S
Use le16_to_cpu only for accessing two byte data provided by controller.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
Reviewed-by: Tomas Henzl <the...@redhat.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 6d17f66..981be7b 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -5384,10 +5384,10 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc,
sas_device->handle, handle);
sas_target_priv_data->handle = handle;
sas_device->handle = handle;
-   if (sas_device_pg0.Flags &
+   if (le16_to_cpu(sas_device_pg0.Flags) &
 MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) {
sas_device->enclosure_level =
-   le16_to_cpu(sas_device_pg0.EnclosureLevel);
+   sas_device_pg0.EnclosureLevel;
memcpy(sas_device->connector_name,
sas_device_pg0.ConnectorName, 4);
sas_device->connector_name[4] = '\0';
@@ -5516,9 +5516,10 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle, u8 phy_num,
sas_device->fast_path = (le16_to_cpu(sas_device_pg0.Flags) &
MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) ? 1 : 0;
 
-   if (sas_device_pg0.Flags & MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) {
+   if (le16_to_cpu(sas_device_pg0.Flags)
+   & MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) {
sas_device->enclosure_level =
-   le16_to_cpu(sas_device_pg0.EnclosureLevel);
+   sas_device_pg0.EnclosureLevel;
memcpy(sas_device->connector_name,
sas_device_pg0.ConnectorName, 4);
sas_device->connector_name[4] = '\0';
@@ -7056,7 +7057,7 @@ Mpi2SasDevicePage0_t *sas_device_pg0)
if (sas_device_pg0->Flags &
  MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) {
sas_device->enclosure_level =
-  le16_to_cpu(sas_device_pg0->EnclosureLevel);
+  sas_device_pg0->EnclosureLevel;
memcpy(_device->connector_name[0],
_device_pg0->ConnectorName[0], 4);
} else {
@@ -7118,6 +7119,7 @@ _scsih_search_responding_sas_devices(struct 
MPT3SAS_ADAPTER *ioc)
sas_device_pg0.SASAddress =
le64_to_cpu(sas_device_pg0.SASAddress);
sas_device_pg0.Slot = le16_to_cpu(sas_device_pg0.Slot);
+   sas_device_pg0.Flags = le16_to_cpu(sas_device_pg0.Flags);
_scsih_mark_responding_sas_device(ioc, _device_pg0);
}
 
-- 
2.4.3



[PATCH v2 04/11] mpt3sas: Removing unused macro "MPT_DEVICE_TLR_ON"

2016-10-26 Thread Suganath Prabu S
Removing macro "MPT_DEVICE_TLR_ON" defined in header file as its unused

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
Reviewed-by: Tomas Henzl <the...@redhat.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 4221a4d..e923c91 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -375,7 +375,6 @@ struct MPT3SAS_TARGET {
  * per device private data
  */
 #define MPT_DEVICE_FLAGS_INIT  0x01
-#define MPT_DEVICE_TLR_ON  0x02
 
 #define MFG_PAGE10_HIDE_SSDS_MASK  (0x0003)
 #define MFG_PAGE10_HIDE_ALL_DISKS  (0x00)
-- 
2.4.3



[PATCH v2 01/11] mpt3sas: Fix for improper info displayed in var log, while blocking or unblocking the device.

2016-10-26 Thread Suganath Prabu S
Return value and Device_handle Arguments passed in correct order
 to match with its format string.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
Reviewed-by: Tomas Henzl <the...@redhat.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 209a969..282ca40 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2837,7 +2837,7 @@ _scsih_internal_device_block(struct scsi_device *sdev,
if (r == -EINVAL)
sdev_printk(KERN_WARNING, sdev,
"device_block failed with return(%d) for handle(0x%04x)\n",
-   sas_device_priv_data->sas_target->handle, r);
+   r, sas_device_priv_data->sas_target->handle);
 }
 
 /**
@@ -2867,20 +2867,20 @@ _scsih_internal_device_unblock(struct scsi_device *sdev,
sdev_printk(KERN_WARNING, sdev,
"device_unblock failed with return(%d) for handle(0x%04x) "
"performing a block followed by an unblock\n",
-   sas_device_priv_data->sas_target->handle, r);
+   r, sas_device_priv_data->sas_target->handle);
sas_device_priv_data->block = 1;
r = scsi_internal_device_block(sdev);
if (r)
sdev_printk(KERN_WARNING, sdev, "retried device_block "
"failed with return(%d) for handle(0x%04x)\n",
-   sas_device_priv_data->sas_target->handle, r);
+   r, sas_device_priv_data->sas_target->handle);
 
sas_device_priv_data->block = 0;
r = scsi_internal_device_unblock(sdev, SDEV_RUNNING);
if (r)
sdev_printk(KERN_WARNING, sdev, "retried device_unblock"
" failed with return(%d) for handle(0x%04x)\n",
-   sas_device_priv_data->sas_target->handle, r);
+   r, sas_device_priv_data->sas_target->handle);
}
 }
 
-- 
2.4.3



[PATCH v2 03/11] mpt3sas: Implement device_remove_in_progress check in IOCTL path

2016-10-26 Thread Suganath Prabu S
When device missing event arrives, device_remove_in_progress bit will be
set and hence driver has to stop sending IOCTL commands.Now the check has
been added in IOCTL path to test device_remove_in_progress bit is set, if
so then IOCTL will be failed printing failure message.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 19 +++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  5 
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 46 ++--
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 24 ++-
 4 files changed, 86 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 4ea81e1..9ad7f7c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -5334,6 +5334,21 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
goto out_free_resources;
}
 
+   /* allocate memory for pending OS device add list */
+   ioc->pend_os_device_add_sz = (ioc->facts.MaxDevHandle / 8);
+   if (ioc->facts.MaxDevHandle % 8)
+   ioc->pend_os_device_add_sz++;
+   ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz,
+   GFP_KERNEL);
+   if (!ioc->pend_os_device_add)
+   goto out_free_resources;
+
+   ioc->device_remove_in_progress_sz = ioc->pend_os_device_add_sz;
+   ioc->device_remove_in_progress =
+   kzalloc(ioc->device_remove_in_progress_sz, GFP_KERNEL);
+   if (!ioc->device_remove_in_progress)
+   goto out_free_resources;
+
ioc->fwfault_debug = mpt3sas_fwfault_debug;
 
/* base internal command bits */
@@ -5416,6 +5431,8 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
kfree(ioc->reply_post_host_index);
kfree(ioc->pd_handles);
kfree(ioc->blocking_handles);
+   kfree(ioc->device_remove_in_progress);
+   kfree(ioc->pend_os_device_add);
kfree(ioc->tm_cmds.reply);
kfree(ioc->transport_cmds.reply);
kfree(ioc->scsih_cmds.reply);
@@ -5457,6 +5474,8 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc)
kfree(ioc->reply_post_host_index);
kfree(ioc->pd_handles);
kfree(ioc->blocking_handles);
+   kfree(ioc->device_remove_in_progress);
+   kfree(ioc->pend_os_device_add);
kfree(ioc->pfacts);
kfree(ioc->ctl_cmds.reply);
kfree(ioc->ctl_cmds.sense);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 3e71bc1..4221a4d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1079,6 +1079,9 @@ struct MPT3SAS_ADAPTER {
void*pd_handles;
u16 pd_handles_sz;
 
+   void*pend_os_device_add;
+   u16 pend_os_device_add_sz;
+
/* config page */
u16 config_page_sz;
void*config_page;
@@ -1187,6 +1190,8 @@ struct MPT3SAS_ADAPTER {
struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event;
struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi;
struct SL_WH_MPI_TRIGGERS_T diag_trigger_mpi;
+   void*device_remove_in_progress;
+   u16 device_remove_in_progress_sz;
 };
 
 typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index,
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 26cdc12..de720c9 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -654,6 +654,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct 
mpt3_ioctl_command karg,
size_t data_in_sz = 0;
long ret;
u16 wait_state_count;
+   u16 device_handle = MPT3SAS_INVALID_DEVICE_HANDLE;
 
issue_reset = 0;
 
@@ -738,10 +739,13 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct 
mpt3_ioctl_command karg,
data_in_sz = karg.data_in_size;
 
if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
-   mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
-   if (!le16_to_cpu(mpi_request->FunctionDependent1) ||
-   le16_to_cpu(mpi_request->FunctionDependent1) >
-   ioc->facts.MaxDevHandle) {
+   mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH ||
+   mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT ||
+   mpi_request->Function == MPI2_FUNCTION_SATA_PASSTHROUGH) {
+
+   device_handle = le16_to_cpu(mpi_request->FunctionDependent1);
+

[PATCH v2 08/11] mpt3sas: set EEDP-escape-flags for SAS35 devices.

2016-10-26 Thread Suganath Prabu S
An UNMAP command on a PI formatted device will leave the Logical Block
Application Tag and Logical Block Reference Tag as all F's (for those LBAs
that are unmapped). To avoid IO errors if those LBAs are subsequently read
before they are written with valid tag fields, the MPI SCSI IO requests
need to set the EEDPFlags element EEDP Escape Mode field, Bits [7:6]
appropriately. A value of 2 should be set to disable all PI checks if the
Logical Block Application Tag is 0x for PI types 1 and 2.  A value
of 3 should be set to disable all PI checks if the Logical Block
Application Tag is 0x and the Logical Block Reference Tag is
0x for PI type 3.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
Reviewed-by: Tomas Henzl <the...@redhat.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index a1c541d..c58f326 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3989,6 +3989,9 @@ _scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct 
scsi_cmnd *scmd,
 
mpi_request_3v->EEDPBlockSize =
cpu_to_le16(scmd->device->sector_size);
+
+   if (ioc->is_gen35_ioc)
+   eedp_flags |= MPI25_SCSIIO_EEDPFLAGS_APPTAG_DISABLE_MODE;
mpi_request->EEDPFlags = cpu_to_le16(eedp_flags);
 }
 
-- 
2.4.3



[PATCH v2 05/11] mpt3sas: Bump driver version as "14.100.00.00"

2016-10-26 Thread Suganath Prabu S
Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index e923c91..6f03a86 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -73,8 +73,8 @@
 #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 "13.100.00.00"
-#define MPT3SAS_MAJOR_VERSION  13
+#define MPT3SAS_DRIVER_VERSION "14.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  14
 #define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
-- 
2.4.3



[PATCH v2 07/11] mpt3sas: Increased/Additional MSIX support for SAS35 devices.

2016-10-26 Thread Suganath Prabu S
For SAS35 devices MSIX vectors are inceased to 128 from 96. To support this
Reply post host index register count is increased to 16. Also variable
msix96_vector is replaced with combined_reply_queue and variable
combined_reply_index_count is added to set different values for SAS3 and
SAS35 devices.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
Reviewed-by: Tomas Henzl <the...@redhat.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 14 +++---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  8 +---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 11 +--
 3 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 9ad7f7c..43cdc02 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1078,7 +1078,7 @@ _base_interrupt(int irq, void *bus_id)
 * new reply host index value in ReplyPostIndex Field and msix_index
 * value in MSIxIndex field.
 */
-   if (ioc->msix96_vector)
+   if (ioc->combined_reply_queue)
writel(reply_q->reply_post_host_index | ((msix_index  & 7) <<
MPI2_RPHI_MSIX_INDEX_SHIFT),
ioc->replyPostRegisterIndex[msix_index/8]);
@@ -2052,7 +2052,7 @@ mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc)
_base_free_irq(ioc);
_base_disable_msix(ioc);
 
-   if (ioc->msix96_vector) {
+   if (ioc->combined_reply_queue) {
kfree(ioc->replyPostRegisterIndex);
ioc->replyPostRegisterIndex = NULL;
}
@@ -2162,7 +2162,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
/* Use the Combined reply queue feature only for SAS3 C0 & higher
 * revision HBAs and also only when reply queue count is greater than 8
 */
-   if (ioc->msix96_vector && ioc->reply_queue_count > 8) {
+   if (ioc->combined_reply_queue && ioc->reply_queue_count > 8) {
/* Determine the Supplemental Reply Post Host Index Registers
 * Addresse. Supplemental Reply Post Host Index Registers
 * starts at offset MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET and
@@ -2170,7 +2170,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
 * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET from previous one.
 */
ioc->replyPostRegisterIndex = kcalloc(
-MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT,
+ioc->combined_reply_index_count,
 sizeof(resource_size_t *), GFP_KERNEL);
if (!ioc->replyPostRegisterIndex) {
dfailprintk(ioc, printk(MPT3SAS_FMT
@@ -2180,14 +2180,14 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
goto out_fail;
}
 
-   for (i = 0; i < MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT; i++) {
+   for (i = 0; i < ioc->combined_reply_index_count; i++) {
ioc->replyPostRegisterIndex[i] = (resource_size_t *)
 ((u8 *)>chip->Doorbell +
 MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET +
 (i * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET));
}
} else
-   ioc->msix96_vector = 0;
+   ioc->combined_reply_queue = 0;
 
if (ioc->is_warpdrive) {
ioc->reply_post_host_index[0] = (resource_size_t __iomem *)
@@ -5140,7 +5140,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc)
 
/* initialize reply post host index */
list_for_each_entry(reply_q, >reply_queue_list, list) {
-   if (ioc->msix96_vector)
+   if (ioc->combined_reply_queue)
writel((reply_q->msix_index & 7)<<
   MPI2_RPHI_MSIX_INDEX_SHIFT,
   ioc->replyPostRegisterIndex[reply_q->msix_index/8]);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 3d75c57..acb4106 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -300,8 +300,9 @@
  * There are twelve Supplemental Reply Post Host Index Registers
  * and each register is at offset 0x10 bytes from the previous one.
  */
-#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT 12
-#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET (0x10)
+#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G312
+#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G35   16
+#define MPT3_SUP_REPLY_

[PATCH v2 00/11] mpt3sas driver Enhancements and

2016-10-26 Thread Suganath Prabu S
Here is the change list:
Posting 11 patches for mpt3sas driver enhancements and few fixes.
  * Added Device ID's for SAS35 devices and updated MPI Header.
  * Support "EEDP Escape flag" for SAS35 devices.
  * fixed improper printk statement.
  * Regardless of whether RDPQ disabled card is enumerated
first or RDPQ enabled card is enumerated first, MSIX vectors
depends on the cards capability.
  * device_remove_in_progress bit check has been added in IOCTL path. If
bit is set, then IOCTL will be failed printing failure message.
  * Started using the Atomic Request Descriptors for
SAS35 devices.
  * For SAS35 devices MSIX vectors are inceased to 128 from 96.
  * Fixing Endianness issue.
  * Updated driver version to 14.100.00.00 at the end of SAS3
changes and updated driver minor version to 14.101.00.00
after SAS35 changes.

Suganath Prabu S (11):
  mpt3sas: Fix for improper info displayed in var log, while blocking or
unblocking the device.
  mpt3sas: Fix for incorrect numbers for MSIX vectors enabled when non
RDPQ card is enumerated first.
  mpt3sas: Implement device_remove_in_progress check in  IOCTL path
  mpt3sas: Removing unused macro "MPT_DEVICE_TLR_ON"
  mpt3sas: Bump driver version as "14.100.00.00"
  mpt3sas: Added Device ID's for SAS35 devices and updated MPI header.
  mpt3sas: Increased/Additional MSIX support for SAS35 devices.
  mpt3sas: set EEDP-escape-flags for SAS35 devices.
  mpt3sas: Use the new MPI 2.6 32-bit Atomic Request  Descriptors
for SAS35 devices.
  mpt3sas: Fix for Endianness issue.
  mpt3sas: Bump driver version as "14.101.00.00"

 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |   7 ++
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 186 ++-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  39 ---
 drivers/scsi/mpt3sas/mpt3sas_config.c|   2 +-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  69 +---
 drivers/scsi/mpt3sas/mpt3sas_ctl.h   |   1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 113 +++
 drivers/scsi/mpt3sas/mpt3sas_transport.c |   8 +-
 8 files changed, 334 insertions(+), 91 deletions(-)

Thanks,
Suganath prabu S 
-- 
2.4.3



[PATCH v2 02/11] mpt3sas: Fix for incorrect numbers for MSIX vectors enabled when non RDPQ card is enumerated first.

2016-10-26 Thread Suganath Prabu S
No. of MSIX vectors supported = min (Total no. of CPU cores,
MSIX vectors supported by card)

when RDPQ is disabled "max_msix_vectors" module parameter which was
declared as global was set to '8' and hence if there are more than one card
in system among which if RDPQ disabled card is enumerated first then only 8
MSIX vectors was getting enabled for all the cards(including RDPQ enabled
card,which can support more than 8 MSIX vectors).

Used local variable instead of global variable ,if RDPQ is disabled this
local variable is set to '8' else it is set to "max_msix_vectors" (by
default this is set to -1, whose value can be set by user during driver
load time).So now regardless of whether RDPQ disabled card is enumerated
first or RDPQ enabled card is enumerated first , MSIX vectors enabled
depends on the cards capability.

Signed-off-by: Chaitra P B <chaitra.basa...@broadcom.com>
Signed-off-by: Sathya Prakash <sathya.prak...@broadcom.com>
Signed-off-by: Suganath Prabu S <suganath-prabu.subram...@broadcom.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
Reviewed-by: Tomas Henzl <the...@redhat.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index a1a5ceb..4ea81e1 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1959,7 +1959,7 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc)
 {
struct msix_entry *entries, *a;
int r;
-   int i;
+   int i, local_max_msix_vectors;
u8 try_msix = 0;
 
if (msix_disable == -1 || msix_disable == 0)
@@ -1979,13 +1979,15 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc)
  ioc->cpu_count, max_msix_vectors);
 
if (!ioc->rdpq_array_enable && max_msix_vectors == -1)
-   max_msix_vectors = 8;
+   local_max_msix_vectors = 8;
+   else
+   local_max_msix_vectors = max_msix_vectors;
 
-   if (max_msix_vectors > 0) {
-   ioc->reply_queue_count = min_t(int, max_msix_vectors,
+   if (local_max_msix_vectors > 0) {
+   ioc->reply_queue_count = min_t(int, local_max_msix_vectors,
ioc->reply_queue_count);
ioc->msix_vector_count = ioc->reply_queue_count;
-   } else if (max_msix_vectors == 0)
+   } else if (local_max_msix_vectors == 0)
goto try_ioapic;
 
if (ioc->msix_vector_count < ioc->cpu_count)
-- 
2.4.3



[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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 01/13] mpt3sas: Add nvme device support in slave alloc, target alloc and probe

2017-06-29 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 00/13]mpt3sas driver NVMe support:

2017-06-29 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 05/13] mpt3sas: Set NVMe device queue depth as 128

2017-06-29 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 <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 |   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 04/13] mpt3sas: Added support for nvme encapsulated request message.

2017-08-08 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>
Reviewed-by: Hannes Reinecke <h...@suse.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 d48f176..27fe074 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))) {
@@ -3124,6 +3131,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
@@ -3214,6 +3245,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
@@ -6046,11 +6098,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;
 

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

2017-08-08 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>
Reviewed-by: Hannes Reinecke <h...@suse.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 2f257e1..710ea63 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
+   

[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 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 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 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 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 v4 07/14] mpt3sas: Handle NVMe PCIe device related events generated from firmware.

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

* 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 2ffcac2..3e571ef 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)
@@ -6165,8 +6185,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

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

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

* 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  | 601 ++-
 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, 646 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 18039bb..1e9086a 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,480 @@ _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 

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

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

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 d

[PATCH v4 09/14] mpt3sas: scan and add nvme device after controller reset

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

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>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 194 ++-
 1 file 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 

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

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

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 file 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));
-   

[PATCH v4 12/14] mpt3sas: Fix nvme drives checking for tlr.

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

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>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 22 --
 1 file 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");
-- 
2.5.5



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

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

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>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 148 ++-
 1 file changed, 145 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 2f257e1..710ea63 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

[PATCH v4 14/14] mpt3sas: Fix sparse warning

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

1) Used data type __le64/__le32 whichever required in
building NVME PRP, which is passed to LE Controller.
2) Remove unused function, Declared functions which are used only
in mpt3sas_scsih.c as static.

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  | 23 +++---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 37 +---
 2 files changed, 16 insertions(+), 44 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 3e571ef..9ec7f0e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1437,8 +1437,8 @@ _base_build_nvme_prp(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
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;
+   __le64  *prp_entry, *prp1_entry, *prp2_entry, *prp_entry_phys;
+   __le64  *prp_page, *prp_page_phys;
u32 offset, entry_len;
u32 page_mask_result, page_mask;
dma_addr_t  paddr;
@@ -1455,17 +1455,17 @@ _base_build_nvme_prp(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
 * PRP1 is located at a 24 byte offset from the start of the NVMe
 * command.  Then set the current PRP entry pointer to PRP1.
 */
-   prp1_entry = (u64 *)(nvme_encap_request->NVMe_Command +
+   prp1_entry = (__le64 *)(nvme_encap_request->NVMe_Command +
NVME_CMD_PRP1_OFFSET);
-   prp2_entry = (u64 *)(nvme_encap_request->NVMe_Command +
+   prp2_entry = (__le64 *)(nvme_encap_request->NVMe_Command +
NVME_CMD_PRP2_OFFSET);
prp_entry = prp1_entry;
/*
 * For the PRP entries, use the specially allocated buffer of
 * contiguous memory.
 */
-   prp_page = (u64 *)mpt3sas_base_get_pcie_sgl(ioc, smid);
-   prp_page_phys = (u64 *)mpt3sas_base_get_pcie_sgl_dma(ioc, smid);
+   prp_page = (__le64 *)mpt3sas_base_get_pcie_sgl(ioc, smid);
+   prp_page_phys = (__le64 *)mpt3sas_base_get_pcie_sgl_dma(ioc, smid);
 
/*
 * Check if we are within 1 entry of a page boundary we don't
@@ -1475,8 +1475,8 @@ _base_build_nvme_prp(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
page_mask_result = (uintptr_t)((u8 *)prp_page + prp_size) & page_mask;
if (!page_mask_result) {
/* Bump up to next page boundary. */
-   prp_page = (u64 *)((u8 *)prp_page + prp_size);
-   prp_page_phys = (u64 *)((u8 *)prp_page_phys + prp_size);
+   prp_page = (__le64 *)((u8 *)prp_page + prp_size);
+   prp_page_phys = (__le64 *)((u8 *)prp_page_phys + prp_size);
}
 
/*
@@ -1604,7 +1604,7 @@ _base_build_nvme_prp(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
  * Returns:true: PRPs are built
  * false: IEEE SGLs needs to be built
  */
-void
+static void
 base_make_prp_nvme(struct MPT3SAS_ADAPTER *ioc,
struct scsi_cmnd *scmd,
Mpi25SCSIIORequest_t *mpi_request,
@@ -1612,7 +1612,7 @@ base_make_prp_nvme(struct MPT3SAS_ADAPTER *ioc,
 {
int sge_len, offset, num_prp_in_chain = 0;
Mpi25IeeeSgeChain64_t *main_chain_element, *ptr_first_sgl;
-   u64 *curr_buff;
+   __le64 *curr_buff;
dma_addr_t msg_phys;
u64 sge_addr;
u32 page_mask, page_mask_result;
@@ -1736,7 +1736,6 @@ static bool
 base_is_prp_possible(struct MPT3SAS_ADAPTER *ioc,
struct _pcie_device *pcie_device, struct scsi_cmnd *scmd, int sge_count)
 {
-   u32 i;
u32 data_length = 0;
struct scatterlist *sg_scmd;
bool build_prp = false;
@@ -1746,7 +1745,7 @@ base_is_prp_possible(struct MPT3SAS_ADAPTER *ioc,
 
nvme_pg_size = max_t(u32, ioc->page_size,
NVME_PRP_PAGE_SIZE);
-   data_length = cpu_to_le32(scsi_bufflen(scmd));
+   data_length = scsi_bufflen(scmd);
sg_scmd = scsi_sglist(scmd);
 
/* Create page_mask (to get offset within page) */
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 49e1943..f8990d9 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -600,7 +600,7 @@ __mpt3sas_get_pdev_from_target(struct MPT3SAS_ADAPTER *ioc,
  *
  * This searches for pcie_device from target, then return pcie_device object.
  */
-struct _pcie_device *
+static struct _pcie_device *
 mpt3sas_get_pdev_from_target(struct MPT3SAS_ADAPTER *ioc,
struct MPT3SAS_TARGET *tgt_priv)
 {
@@ -908,7 +908,7 @@ _scsih_sas_device_init_add(struct MPT3SAS_ADAPTER *ioc,
 }
 
 
-struct _pcie

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

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

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 file 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
 
-- 
2.5.5



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

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

* 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 file 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;
+   

[PATCH v4 08/14] mpt3sas: Set NVMe device queue depth as 128

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

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 deletion(-)

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);
-- 
2.5.5



[PATCH v4 01/14] mpt3sas: Update MPI Header

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

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_A

[PATCH v4 00/14] mpt3sas driver NVMe support:

2017-08-21 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 v4 patset:

1) Removed code which detects gaps/holes in IO data buffers.
2) Added Patch 14, This has sparse warning fixes.

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 (14):
  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.
  mpt3sas: Fix sparse warning

 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  |  686 +-
 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 | 2076 +++---
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 12 files changed, 3945 insertions(+), 274 deletions(-)
 create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h

Thanks,
Suganath Prabu S

-- 
2.5.5



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

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

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)
+   got

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

2017-08-21 Thread Suganath Prabu S
From: root <r...@dhcp-135-24-192-103.dhcp.avagotech.net>

* 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>
Reviewed-by: Hannes Reinecke <h...@suse.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 1e9086a..2ffcac2 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -557,6 +557,11 @@ _base_sas_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
MPI2DefaultReply_t *mpi_reply,
frame_sz = sizeof(Mpi2SmpPassthroughRequest_t) + ioc->sge_size;
func_str = "smp_passthru";
break;
+   case MPI2_FUNCTION_NVME_ENCAPSULATED:
+   frame_sz = sizeof(Mpi26NVMeEncapsulatedRequest_t) +
+   ioc->sge_size;
+   func_str = "nvme_encapsulated";
+   break;
default:
frame_sz = 32;
func_str = "unknown";
@@ -985,7 +990,9 @@ _base_interrupt(int irq, void *bus_id)
if (request_desript_type ==
MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS ||
request_desript_type ==
-   MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
+   MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS ||
+   request_desript_type ==
+   MPI26_RPY_DESCRIPT_FLAGS_PCIE_ENCAPSULATED_SUCCESS) {
cb_idx = _base_get_cb_idx(ioc, smid);
if ((likely(cb_idx < MPT_MAX_CALLBACKS)) &&
(likely(mpt_callbacks[cb_idx] != NULL))) {
@@ -3057,6 +3064,30 @@ _base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, 
u16 smid,
 }
 
 /**
+ * _base_put_smid_nvme_encap - send NVMe encapsulated request to
+ *  firmware
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Return nothing.
+ */
+static void
+_base_put_smid_nvme_encap(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+{
+   Mpi2RequestDescriptorUnion_t descriptor;
+   u64 *request = (u64 *)
+
+   descriptor.Default.RequestFlags =
+   MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
+   descriptor.Default.MSIxIndex =  _base_get_msix_index(ioc);
+   descriptor.Default.SMID = cpu_to_le16(smid);
+   descriptor.Default.LMID = 0;
+   descriptor.Default.DescriptorTypeDependent = 0;
+   _base_writeq(*request, >chip->RequestDescriptorPostLow,
+   >scsi_lookup_lock);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * @ioc: per adapter object
  * @smid: system request message index
@@ -3147,6 +3178,27 @@ _base_put_smid_hi_priority_atomic(struct MPT3SAS_ADAPTER 
*ioc, u16 smid,
 }
 
 /**
+ * _base_put_smid_nvme_encap_atomic - send NVMe encapsulated request to
+ *   firmware using Atomic Request Descriptor
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Return nothing.
+ */
+static void
+_base_put_smid_nvme_encap_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid)
+{
+   Mpi26AtomicRequestDescriptor_t descriptor;
+   u32 *request = (u32 *)
+
+   descriptor.RequestFlags = MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
+   descriptor.MSIxIndex = _base_get_msix_index(ioc);
+   descriptor.SMID = cpu_to_le16(smid);
+
+   writel(cpu_to_le32(*request), >chip->AtomicRequestDescriptorPost);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * use Atomic Request Descriptor
  * @ioc: per adapter object
@@ -5979,11 +6031,13 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
ioc->put_smid_scsi_io = &_base_put_smid_scsi_io_atomic;
ioc->put_smid_fast_path = &_base_put_smid_fast_path_atomic;
ioc->put_smid_hi_priority = &_base_put_smid_hi_priority_atomic;
+   ioc->put_smid_nvme_encap = &_base_put_smid_nvme_encap_atomic;
} else {
ioc->put_smid_default = &_base_put_smid_default;
ioc->put_smid_scsi_io = &_base_put_smid_scsi_io;
ioc->put_smid_

[Resend v5 04/14] mpt3sas: Added support for nvme encapsulated request message.

2017-09-01 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.

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 | 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 dcf5157..9653cfa 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))) {
@@ -3046,6 +3053,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
@@ -3136,6 +3167,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
@@ -5968,11 +6020,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_enca

[v5 01/14] Update MPI Header

2017-08-30 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

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

2017-08-30 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>
Reviewed-by: Hannes Reinecke <h...@suse.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 dcf5157..9653cfa 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))) {
@@ -3046,6 +3053,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
@@ -3136,6 +3167,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
@@ -5968,11 +6020,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;
 

[v5 05/14] mpt3sas: API 's to support NVMe drive addition to SML

2017-08-30 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

[v5 02/14] mpt3sas: Add nvme device support in slave alloc, target alloc and probe

2017-08-30 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

  1   2   3   >