Re: [PATCH 7/8] mpt3sas: set an unlimited max_segment_size for SAS 3.0 HBAs

2019-06-20 Thread Suganath Prabu Subramani
Acked-by: Suganath Prabu 

On Thu, Jun 20, 2019 at 12:34 PM Suganath Prabu Subramani
 wrote:
>
> Please consider this as Acked-by: Suganath Prabu
> 
>
>
> On Tue, Jun 18, 2019 at 6:16 AM Ming Lei  wrote:
> >
> > On Mon, Jun 17, 2019 at 8:21 PM Christoph Hellwig  wrote:
> > >
> > > When using a virt_boundary_mask, as done for NVMe devices attached to
> > > mpt3sas controllers we require an unlimited max_segment_size, as the
> > > virt boundary merging code assumes that.  But we also need to propagate
> > > that to the DMA mapping layer to make dma-debug happy.  The SCSI layer
> > > takes care of that when using the per-host virt_boundary setting, but
> > > given that mpt3sas only wants to set the virt_boundary for actual
> > > NVMe devices we can't rely on that.  The DMA layer maximum segment
> > > is global to the HBA however, so we have to set it explicitly.  This
> > > patch assumes that mpt3sas does not have a segment size limitation,
> > > which seems true based on the SGL format, but will need to be verified.
> > >
> > > Signed-off-by: Christoph Hellwig 
> > > ---
> > >  drivers/scsi/mpt3sas/mpt3sas_scsih.c | 1 +
> > >  1 file changed, 1 insertion(+)
> > >
> > > diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
> > > b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> > > index 1ccfbc7eebe0..c719b807f6d8 100644
> > > --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> > > +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> > > @@ -10222,6 +10222,7 @@ static struct scsi_host_template 
> > > mpt3sas_driver_template = {
> > > .this_id= -1,
> > > .sg_tablesize   = MPT3SAS_SG_DEPTH,
> > > .max_sectors= 32767,
> > > +   .max_segment_size   = 0x,
> >
> > .max_segment_size should be aligned, either setting it here correctly or
> > forcing to make it aligned in scsi-core.
> >
> > Thanks,
> > Ming Lei


Re: [PATCH 7/8] mpt3sas: set an unlimited max_segment_size for SAS 3.0 HBAs

2019-06-19 Thread Suganath Prabu Subramani
Please consider this as Acked-by: Suganath Prabu



On Tue, Jun 18, 2019 at 6:16 AM Ming Lei  wrote:
>
> On Mon, Jun 17, 2019 at 8:21 PM Christoph Hellwig  wrote:
> >
> > When using a virt_boundary_mask, as done for NVMe devices attached to
> > mpt3sas controllers we require an unlimited max_segment_size, as the
> > virt boundary merging code assumes that.  But we also need to propagate
> > that to the DMA mapping layer to make dma-debug happy.  The SCSI layer
> > takes care of that when using the per-host virt_boundary setting, but
> > given that mpt3sas only wants to set the virt_boundary for actual
> > NVMe devices we can't rely on that.  The DMA layer maximum segment
> > is global to the HBA however, so we have to set it explicitly.  This
> > patch assumes that mpt3sas does not have a segment size limitation,
> > which seems true based on the SGL format, but will need to be verified.
> >
> > Signed-off-by: Christoph Hellwig 
> > ---
> >  drivers/scsi/mpt3sas/mpt3sas_scsih.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
> > b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> > index 1ccfbc7eebe0..c719b807f6d8 100644
> > --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> > +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> > @@ -10222,6 +10222,7 @@ static struct scsi_host_template 
> > mpt3sas_driver_template = {
> > .this_id= -1,
> > .sg_tablesize   = MPT3SAS_SG_DEPTH,
> > .max_sectors= 32767,
> > +   .max_segment_size   = 0x,
>
> .max_segment_size should be aligned, either setting it here correctly or
> forcing to make it aligned in scsi-core.
>
> Thanks,
> Ming Lei


Re: [PATCH] mpt3sas_ctl: fix double-fetch bug in _ctl_ioctl_main()

2019-05-27 Thread Suganath Prabu Subramani
Please consider this patch as Ack-by: Suganath Prabu S


Thanks,
Suganath.


On Mon, May 27, 2019 at 6:27 AM Gen Zhang  wrote:
>
> In _ctl_ioctl_main(), 'ioctl_header' is fetched the first time from
> userspace. 'ioctl_header.ioc_number' is then checked. The legal result
> is saved to 'ioc'. Then, in condition MPT3COMMAND, the whole struct is
> fetched again from the userspace. Then _ctl_do_mpt_command() is called,
> 'ioc' and 'karg' as inputs.
>
> However, a malicious user can change the 'ioc_number' between the two
> fetches, which will cause a potential security issues.  Moreover, a
> malicious user can provide a valid 'ioc_number' to pass the check in
> first fetch, and then modify it in the second fetch.
>
> To fix this, we need to recheck the 'ioc_number' in the second fetch.
>
> Signed-off-by: Gen Zhang 
> ---
> diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c 
> b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
> index b2bb47c..5181c03 100644
> --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
> +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
> @@ -2319,6 +2319,10 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, 
> void __user *arg,
> break;
> }
>
> +   if (karg.hdr.ioc_number != ioctl_header.ioc_number) {
> +   ret = -EINVAL;
> +   break;
> +   }
> if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_command)) {
> uarg = arg;
> ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf);


[PATCH 1/4] mpt3sas: Rename mpi endpoint device ID macro.

2019-01-29 Thread Suganath Prabu S
MPI Endpoint is a PCIe switch based on MPI2,
Renaming device ID macro from
MPI2_MFGPAGE_DEVID_SAS2308_MPI_EP
to MPI2_MFGPAGE_DEVID_SWITCH_MPI_EP

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 2 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
index 398fa6f..a53a758 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
@@ -548,7 +548,7 @@ typedef struct _MPI2_CONFIG_REPLY {
 #define MPI2_MFGPAGE_DEVID_SAS2308_1(0x0086)
 #define MPI2_MFGPAGE_DEVID_SAS2308_2(0x0087)
 #define MPI2_MFGPAGE_DEVID_SAS2308_3(0x006E)
-#define MPI2_MFGPAGE_DEVID_SAS2308_MPI_EP   (0x02B0)
+#define MPI2_MFGPAGE_DEVID_SWITCH_MPI_EP(0x02B0)
 
 /*MPI v2.5 SAS products */
 #define MPI25_MFGPAGE_DEVID_SAS3004 (0x0096)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 6be39dc..c3a0f70 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -10256,7 +10256,7 @@ _scsih_determine_hba_mpi_version(struct pci_dev *pdev)
case MPI2_MFGPAGE_DEVID_SAS2308_1:
case MPI2_MFGPAGE_DEVID_SAS2308_2:
case MPI2_MFGPAGE_DEVID_SAS2308_3:
-   case MPI2_MFGPAGE_DEVID_SAS2308_MPI_EP:
+   case MPI2_MFGPAGE_DEVID_SWITCH_MPI_EP:
return MPI2_VERSION;
case MPI25_MFGPAGE_DEVID_SAS3004:
case MPI25_MFGPAGE_DEVID_SAS3008:
@@ -10343,7 +10343,7 @@ _scsih_probe(struct pci_dev *pdev, const struct 
pci_device_id *id)
ioc->is_warpdrive = 1;
ioc->hide_ir_msg = 1;
break;
-   case MPI2_MFGPAGE_DEVID_SAS2308_MPI_EP:
+   case MPI2_MFGPAGE_DEVID_SWITCH_MPI_EP:
ioc->is_mcpu_endpoint = 1;
break;
default:
@@ -10783,7 +10783,7 @@ static const struct pci_device_id mpt3sas_pci_table[] = 
{
PCI_ANY_ID, PCI_ANY_ID },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3,
PCI_ANY_ID, PCI_ANY_ID },
-   { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_MPI_EP,
+   { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SWITCH_MPI_EP,
PCI_ANY_ID, PCI_ANY_ID },
/* SSS6200 */
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200,
-- 
1.8.3.1



[PATCH 3/4] mpt3sas: Add support for ATLAS PCIe switch.

2019-01-29 Thread Suganath Prabu S
Add Atlas PCIe Switch Management Port device PNPID,
Vendor Id: 0x1000
device Id: 0x00B2

This device is based on MPI 2.6 spec and it exposes one
SES device to accept management commands for the PCIe switch.

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  | 3 +++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 6 ++
 2 files changed, 9 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 8003519..db12c1b 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -193,6 +193,9 @@ struct mpt3sas_nvme_cmd {
 #define SAS2_PCI_DEVICE_B0_REVISION(0x01)
 #define SAS3_PCI_DEVICE_C0_REVISION(0x02)
 
+/* Atlas PCIe Switch Management Port */
+#define MPI26_ATLAS_PCIe_SWITCH_DEVID  (0x00B2)
+
 /*
  * Intel HBA branding
  */
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 4a73753..8bb5b8f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -10283,6 +10283,7 @@ _scsih_determine_hba_mpi_version(struct pci_dev *pdev)
case MPI26_MFGPAGE_DEVID_SAS3516_1:
case MPI26_MFGPAGE_DEVID_SAS3416:
case MPI26_MFGPAGE_DEVID_SAS3616:
+   case MPI26_ATLAS_PCIe_SWITCH_DEVID:
case MPI26_MFGPAGE_DEVID_CFG_SEC_3916:
case MPI26_MFGPAGE_DEVID_HARD_SEC_3916:
case MPI26_MFGPAGE_DEVID_CFG_SEC_3816:
@@ -10373,6 +10374,7 @@ _scsih_probe(struct pci_dev *pdev, const struct 
pci_device_id *id)
case MPI26_MFGPAGE_DEVID_SAS3516_1:
case MPI26_MFGPAGE_DEVID_SAS3416:
case MPI26_MFGPAGE_DEVID_SAS3616:
+   case MPI26_ATLAS_PCIe_SWITCH_DEVID:
ioc->is_gen35_ioc = 1;
break;
case MPI26_MFGPAGE_DEVID_CFG_SEC_3816:
@@ -10853,6 +10855,10 @@ static const struct pci_device_id mpt3sas_pci_table[] 
= {
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_HARD_SEC_3916,
PCI_ANY_ID, PCI_ANY_ID },
 
+   /* Atlas PCIe Switch Management Port */
+   { MPI2_MFGPAGE_VENDORID_LSI, MPI26_ATLAS_PCIe_SWITCH_DEVID,
+   PCI_ANY_ID, PCI_ANY_ID },
+
/* Sea SI 0x00E5 Configurable Secure
 * 0x00E6 Hard Secure
 */
-- 
1.8.3.1



[PATCH 4/4] mpt3sas: Update driver version to 27.102.00.00

2019-01-29 Thread Suganath Prabu S
Updated driver version to 27.102.00.00 from 27.101.00.00.

Signed-off-by: Suganath Prabu S 
---
 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 db12c1b..19158cb 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -75,9 +75,9 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies "
 #define MPT3SAS_DESCRIPTION"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION "27.101.00.00"
+#define MPT3SAS_DRIVER_VERSION "27.102.00.00"
 #define MPT3SAS_MAJOR_VERSION  27
-#define MPT3SAS_MINOR_VERSION  101
+#define MPT3SAS_MINOR_VERSION  102
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
 
-- 
1.8.3.1



[PATCH 2/4] mpt3sas: Add support for NVMe Switch Adapter

2019-01-29 Thread Suganath Prabu S
Added device ID for NVMe Switch Adapter (Ambrosia).
VID: 0x1000
DID: 0x02B1

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 4 
 2 files changed, 5 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
index a53a758..a2f4a55 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
@@ -549,6 +549,7 @@ typedef struct _MPI2_CONFIG_REPLY {
 #define MPI2_MFGPAGE_DEVID_SAS2308_2(0x0087)
 #define MPI2_MFGPAGE_DEVID_SAS2308_3(0x006E)
 #define MPI2_MFGPAGE_DEVID_SWITCH_MPI_EP(0x02B0)
+#define MPI2_MFGPAGE_DEVID_SWITCH_MPI_EP_1  (0x02B1)
 
 /*MPI v2.5 SAS products */
 #define MPI25_MFGPAGE_DEVID_SAS3004 (0x0096)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index c3a0f70..4a73753 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -10257,6 +10257,7 @@ _scsih_determine_hba_mpi_version(struct pci_dev *pdev)
case MPI2_MFGPAGE_DEVID_SAS2308_2:
case MPI2_MFGPAGE_DEVID_SAS2308_3:
case MPI2_MFGPAGE_DEVID_SWITCH_MPI_EP:
+   case MPI2_MFGPAGE_DEVID_SWITCH_MPI_EP_1:
return MPI2_VERSION;
case MPI25_MFGPAGE_DEVID_SAS3004:
case MPI25_MFGPAGE_DEVID_SAS3008:
@@ -10344,6 +10345,7 @@ _scsih_probe(struct pci_dev *pdev, const struct 
pci_device_id *id)
ioc->hide_ir_msg = 1;
break;
case MPI2_MFGPAGE_DEVID_SWITCH_MPI_EP:
+   case MPI2_MFGPAGE_DEVID_SWITCH_MPI_EP_1:
ioc->is_mcpu_endpoint = 1;
break;
default:
@@ -10785,6 +10787,8 @@ static const struct pci_device_id mpt3sas_pci_table[] = 
{
PCI_ANY_ID, PCI_ANY_ID },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SWITCH_MPI_EP,
PCI_ANY_ID, PCI_ANY_ID },
+   { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SWITCH_MPI_EP_1,
+   PCI_ANY_ID, PCI_ANY_ID },
/* SSS6200 */
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200,
PCI_ANY_ID, PCI_ANY_ID },
-- 
1.8.3.1



[PATCH 0/4] mpt3sas: Add Atlas and Ambrosia device support.

2019-01-29 Thread Suganath Prabu S
Posting below patches to include new devices Ambrosia,
Atlas.

* Rename macros for MPI Endpoint device which
is a PCIe switch based on MPI2.
* Added device ID 0x02B1 for NVMe Switch Adapter (Ambrosia).
* Added device ID for the Atlas PCIe Switch management port
(0x00B2). This device is based on MPI2.6 and it exposes
one SES device to accept management commands.

Suganath Prabu S (4):
  mpt3sas: Rename mpi endpoint device ID macro.
  mpt3sas: Add support for NVMe Switch Adapter
  mpt3sas: Add support for ATLAS PCIe switch.
  mpt3sas: Update driver version to 27.102.00.00

 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  3 ++-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  7 +--
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 16 +---
 3 files changed, 20 insertions(+), 6 deletions(-)

Thanks,
Suganath Prabu
-- 
1.8.3.1



Re: [PATCH 31/41] scsi: mpt3sas: mpt3sas_scsih: Mark expected switch fall-through

2018-12-19 Thread Suganath Prabu Subramani
Hi Gustavo,

This patch may not apply smoothly over 4.21/scsi-queue.
Our previous patch for Aero had some changes in this switch case.
Can you resend this patch with latest code base ?

Thanks,
Suganath prabu


On Thu, Dec 20, 2018 at 5:37 AM Gustavo A. R. Silva
 wrote:
>
> Hi,
>
> Friendly ping:
>
> Who can ack or review this patch, please?
>
> Thanks
> --
> Gustavo
>
> On 11/27/18 10:32 PM, Gustavo A. R. Silva wrote:
> > In preparation to enabling -Wimplicit-fallthrough, mark switch cases
> > where we are expecting to fall through.
> >
> > Addresses-Coverity-ID: 1475400 ("Missing break in switch")
> > Signed-off-by: Gustavo A. R. Silva 
> > ---
> >   drivers/scsi/mpt3sas/mpt3sas_scsih.c | 1 +
> >   1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
> > b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> > index 5b9806d0719e..920b80ce4748 100644
> > --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> > +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> > @@ -10370,6 +10370,7 @@ _scsih_probe(struct pci_dev *pdev, const struct 
> > pci_device_id *id)
> >   case MPI26_MFGPAGE_DEVID_CFG_SEC_3916:
> >   dev_info(&pdev->dev,
> >   "HBA is in Configurable Secure mode\n");
> > + /* fall through */
> >   case MPI26_MFGPAGE_DEVID_SAS3508:
> >   case MPI26_MFGPAGE_DEVID_SAS3508_1:
> >   case MPI26_MFGPAGE_DEVID_SAS3408:
> >


Re: [v6 0/4] mpt3sas: Hot-Plug Surprise removal support on IOC.

2018-10-29 Thread Suganath Prabu Subramani
Any update on this ?
In V6, I have posted has only defect fixes (Other than HBA Hot-Plug
Surprise remove support).

We are reworking and incorporating the suggestions from Bjorn.
And after covering tests, we ll post Hot-Plug Surprise removal patches.

Thanks,
Suganath Prabu
On Tue, Oct 23, 2018 at 3:51 PM Suganath Prabu
 wrote:
>
> v6 Change set:
> Incorporated changes as suggested by Andy.
> In Patch 1 converted while loop to do while in
> function mpt3sas_wait_for_ioc_to_operational().
> And in patch 3 removed parentheses.
>
> V5 Change set:
> V5 post has only defect fixes.
> We are reworking and incorporating the suggestions from Bjorn.
> And after covering tests, we ll be post Hot-Plug Surprise
>  removal patches.
>
> V4 Change set:
> Reframe split strings in print statement, to avoid
>
> V3 Change Set:
> Simplified function "mpt3sas_base_pci_device_is_available" and
> made inline
>
> V2 changes:
> Replaced mpt3sas_base_pci_device_is_unplugged with
> pci_device_is_present.
>
> V1 changes:
> In Patch 0001 - unlock mutex, if active reset is in progress.
> Suganath Prabu (4):
>   mpt3sas: Separate out mpt3sas_wait_for_ioc_to_operational
>   mpt3sas: Fix Sync cache command failure during driver unload
>   mpt3sas:Fix driver modifying persistent data.
>   mpt3sas: Bump driver version to 27.100.00.00.
>
>  drivers/scsi/mpt3sas/mpt3sas_base.c  | 75 
> ++--
>  drivers/scsi/mpt3sas/mpt3sas_base.h  |  8 +++-
>  drivers/scsi/mpt3sas/mpt3sas_config.c| 28 +++-
>  drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 21 ++---
>  drivers/scsi/mpt3sas/mpt3sas_scsih.c | 38 +++-
>  drivers/scsi/mpt3sas/mpt3sas_transport.c | 70 ++---
>  6 files changed, 106 insertions(+), 134 deletions(-)
>
> --
> 1.8.3.1
>


[v5 3/4] mpt3sas:Fix driver modifying persistent data.

2018-10-16 Thread Suganath Prabu
* If EEDPTagMode field in manufacturing page11 is set,
unset it. This is needed to fix a hardware bug
in SAS3/SAS2 cards, So, skipping EEDPTagMode changes
in Manufacturing page11 for SAS35 controllers.

* Fix driver modifying NVRAM/persistent data in
Manufacturing page11 along with current copy. Driver should
change only current copy of Manufacturing page11.

Signed-off-by: Suganath Prabu 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c   | 2 +-
 drivers/scsi/mpt3sas/mpt3sas_config.c | 4 
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index a6c217c..770f52b 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4062,7 +4062,7 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
 * flag unset in NVDATA.
 */
mpt3sas_config_get_manufacturing_pg11(ioc, &mpi_reply, &ioc->manu_pg11);
-   if (ioc->manu_pg11.EEDPTagMode == 0) {
+   if ((!ioc->is_gen35_ioc) && (ioc->manu_pg11.EEDPTagMode == 0)) {
pr_err("%s: overriding NVDATA EEDPTagMode setting\n",
ioc->name);
ioc->manu_pg11.EEDPTagMode &= ~0x3;
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c 
b/drivers/scsi/mpt3sas/mpt3sas_config.c
index 14a195c..aa41cb9 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -660,10 +660,6 @@ mpt3sas_config_set_manufacturing_pg11(struct 
MPT3SAS_ADAPTER *ioc,
r = _config_request(ioc, &mpi_request, mpi_reply,
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
sizeof(*config_page));
-   mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
-   r = _config_request(ioc, &mpi_request, mpi_reply,
-   MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-   sizeof(*config_page));
  out:
return r;
 }
-- 
1.8.3.1



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

2017-10-31 Thread Suganath Prabu S
1) Added support for probing pcie device and adding NVMe drives to
SML and driver's internal list pcie_device_list.

2) Added support for determing NVMe as boot device.

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

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

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  | 110 +++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 431 +--
 3 files changed, 647 insertions(+), 124 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 0fe3969..dd04a28 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -161,6 +161,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)
@@ -359,7 +360,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;
@@ -370,7 +372,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;
 };
 
 
@@ -514,6 +517,89 @@ static inline void sas_device_put(struct _sas_device *s)
kref_put(&s->refcount, sas_device_free);
 }
 
+/*
+ * struct _pcie_device - attached PCIe device information
+ * @list: pcie device list
+ * @starget: starget object
+ * @wwid: device WWID
+ * @handle: device handle
+ * @device_info: bitfield provides detailed info about the device
+ * @id: target id
+ * @channel: target channel
+ * @slot: slot number
+ * @port_num: port number
+ * @responding: used in _scsih_pcie_device_mark_responding
+ * @fast_path: fast path feature enable bit
+ * @nvme_mdts: MaximumDataTransferSize from PCIe Device Page 2 for
+ * NVMe device only
+ * @enclosure_handle: enclosure handle
+ * @enclosure_logical_id: enclosure logical identifier
+ * @enclosure_level: The level of device's enclosure from the controller
+ * @connector_name: ASCII value of the Connector's name
+ * @serial_number: pointer of serial number string allocated runtime
+ * @refcount: reference count for deletion
+ */
+struct _pcie_device {
+   struct list_head list;
+   struct scsi_target *starget;
+   u64 wwid;
+   u16 handle;
+   u32 device_info;
+   int id;
+   int channel;
+   u16 slot;
+   u8  port_num;
+   u8  responding;
+   u8  fast_path;
+   u32 nvme_mdts;
+   u16 enclosure_handle;
+   u64 enclosure_logical_id;
+   u8  enclosure_level;
+   u8  connector_name[4];
+   u8  *serial_number;
+   struct kref refcount;
+};
+/**
+ * pcie_device_get - Increment the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will increment the
+ * reference count of the pcie device for which this function called.
+ *
+ */
+static inline void pcie_device_get(struct _pcie_device *p)
+{
+   kref_get(&p->refcount);
+}
+
+/**
+ * pcie_device_free - Release the pcie device object
+ * @r - kref object
+ *
+ * Free's the pcie device object. It will be called when reference count
+ * reaches to zero.
+ */
+static inline void pcie_device_free(struct kref *r)
+{
+   kfree(container_of(r, struct _pcie_device, refcount));
+}
+
+/**
+ * pcie_device_put - Decrement the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will decrement the
+ * reference count of the pcie device for which this function called.
+ *
+ * When refernce count reaches to Zero, this will call pcie_device_free to the
+ * pcie_device object.
+ */
+static inline void pcie_device_put(struct _pcie_device *p)
+{
+   kref_put(&p->refcount, pcie_device_free);
+}
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -562,12 +648,13 @@ struct _raid_device {
 
 /**
  * struct _boot_device - boot device 

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

2017-10-31 Thread Suganath Prabu S
Below Functions are added in various paths to support NVMe
drive addition.

_scsih_pcie_add_device
_scsih_pcie_device_add
_scsih_pcie_device_init_add
_scsih_check_pcie_access_status
_scsih_pcie_check_device

mpt3sas_get_pdev_by_handle

mpt3sas_config_get_pcie_device_pg0
mpt3sas_config_get_pcie_device_pg2

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 034b34d..a4ec459 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1464,6 +1464,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 *
@@ -1502,6 +1506,12 @@ int mpt3sas_config_get_sas_device_pg0(struct 
MPT3SAS_ADAPTER *ioc,
 int mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+   u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
+   u32 form, u32 handle);
 int mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
u16 sz);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c 
b/drivers/scsi/mpt3sas/mpt3sas_config.c
index dd62701..1c747cf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -150,6 +150,24 @@ _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, 
u16 smid,
case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
desc = "driver_mapping";
break;
+   case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:
+   desc = "sas_port";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:
+   desc = "ext_manufacturing";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:
+   desc = "pcie_io_unit";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:
+   desc = "pcie_switch";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:
+   desc = "pcie_device";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:
+   desc = "pcie_link";
+   break;
}
break;
}
@@ -1053,6 +1071,88 @@ mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER 
*ioc,
 }
 
 /**
+ * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
+ * @ioc: per adapter object
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * @form: GET_NEXT_HANDLE or HANDLE
+ * @handle: device handle
+ * Context: sleep.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+   u32 form, u32 handle)
+{
+   Mpi2ConfigRequest_t mpi_request;
+   int r;
+
+   memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+   mpi_request.Function = MPI2_FUNCTION_CONFIG;
+   mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+   mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
+   mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
+   mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
+   mpi_request.Header.PageNumber = 0;
+   ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
+   r = _config_request(ioc, &mpi_request, mpi_reply,
+   MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+   if (r)
+   goto out;
+
+   mpi_request.PageAddress = cpu_to_le32(form | handle);
+   mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
+   r = _config_request(i

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

2017-10-31 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 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 276 +++-
 drivers/scsi/mpt3sas/mpt3sas_base.h |   4 +
 drivers/scsi/mpt3sas/mpt3sas_ctl.c  |  69 -
 3 files changed, 342 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 1ad3cbb..b0a75c6 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))) {
@@ -1345,6 +1352,225 @@ _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 use

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 148 ++-
 1 file changed, 145 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index d3f8a10..d83560c 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 */
@@ -1126,6 +1128,41 @@ _scsih_pcie_device_remove(struct MPT3SAS_ADAPTER *ioc,
pcie_device_put(pcie_device);
}
 }
+
+
+/**
+ * _scsih_pcie_device_remove_by_handle - removing pcie device object by handle
+ * @ioc: per adapter object
+ * @handle: device handle
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_remove_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+   struct _pcie_device *pcie_device;
+   unsigned long flags;
+   int was_on_pcie_device_list = 0;
+
+   if (ioc->shost_recovery)
+   return;
+
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device) {
+   if (!list_empty(&pcie_device->list)) {
+   list_del_init(&pcie_device->list);
+   was_on_pcie_device_list = 1;
+   pcie_device_put(pcie_device);
+   }
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   if (was_on_pcie_device_list) {
+   _scsih_pcie_device_remove_from_sml(ioc, pcie_device);
+   pcie_device_put(pcie_device);
+   }
+}
+
 /**
  * _scsih_pcie_device_add - add pcie_device object
  * @ioc: per adapter object
@@ -6567,6 +6604,83 @@ _scsih_check_pcie_access_status(struct MPT3SAS_ADAPTER 
*ioc, u64 wwid,
(unsigned long long)wwid, handle);
return rc;
 }
+
+/**
+ * _scsih_pcie_device_remove_from_sml -  removing pcie device
+ * from SML and free up associated memory
+ * @ioc: per adapter object
+ * @pcie_device: the pcie_device object
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
+   struct _pcie_device *pcie_device)
+{
+   struct MPT3SAS_TARGET *sas_target_priv_data;
+
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: handle(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
+   pcie_device->handle, (unsigned long long)
+   pcie_device->wwid));
+   if (pcie_device->enclosure_handle != 0)
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: enclosure logical id(0x%016llx), slot(%d)\n",
+   ioc->name, __func__,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot));
+   if (pcie_device->connector_name[0] != '\0')
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: enclosure level(0x%04x), connector name( %s)\n",
+   ioc->name, __func__,
+   pcie_device->enclosure_level,
+   pcie_device->connector_name));
+
+   if (pcie_device->starget && pcie_device->starget->hostdata) {
+   sas_target_priv_data = pcie_device->starget->hostdata;
+   sas_target_priv_data->deleted = 1;
+   _scsih_ublock_io_device(ioc, pcie_device->wwid);
+   sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE;
+   }
+
+   pr_info(MPT3SAS_FMT
+   "removing handle(0x%04x), wwid (0x%016llx)\n",
+   ioc->name, pcie_device->handle,
+   (unsigned long long) pcie_device->wwid);
+   if (pcie_device->enclosure_handle != 0)
+   pr_info(MPT3SAS_FMT
+   "removing : enclosure logical id(0x%016llx), slot(%d)\n",
+   ioc->name,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0] != '\0')
+   pr_info(MPT3SAS_FMT
+   "removing: enclosure level(0x%04x), connector name( %s)\n",
+  

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

2017-10-31 Thread Suganath Prabu S
* The controller firmware sends separate events for NVMe devices and
PCIe switches similar to existing SAS events.

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

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

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  30 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 471 ++-
 2 files changed, 495 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index b0a75c6..0da639d 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 = "Cable Event";
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)
@@ -6125,7 +6145,15 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
_base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
_base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD);
_base_unmask_events(ioc, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
-
+   if (ioc->hba_mpi_version_belonged == MPI26_VERSION) {
+   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)
goto out_free_resources;
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index d83560c..21260bd 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 */
@@ -3476,8 +3478,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;
@@ -3487,7 +3487,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,
@@ -3498,7 +3498,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);
 }
 
 /**
@@ -3582,6 +3583,33 @@ _scsih_block_io_to_children_attached_directly(struct 
MPT3SAS_A

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

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

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 9006a60..81f4d2d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4887,6 +4887,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;
@@ -5019,6 +5020,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) {
@@ -5055,11 +5078,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd,
struct sense_info data;
_scsih_normalize_sense(scmd->sense_buffer, &data);
pr_warn(MPT3SAS_FMT
-   "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], 
count(%d)\n",
-   ioc->name, data.skey,
-   data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
+ "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
+ ioc->name, data.skey,
+ data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
}
-
if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
response_info = le32_to_cpu(mpi_reply->ResponseInfo);
response_bytes = (u8 *)&response_info;
@@ -8559,6 +8581,130 @@ _scsih_search_responding_sas_devices(struct 
MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * _scsih_mark_responding_pcie_device - mark a pcie_device as responding
+ * @ioc: per adapter object
+ * @pcie_device_pg0: PCIe Device page 0
+ *
+ * After host reset, find out whether devices are still responding.
+ * Used in _scsih_remove_unresponding_devices.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_mark_responding_pcie_device(struct MPT3SAS_ADAPTER *ioc,
+   Mpi26PCIeDevicePage0_t *pcie_device_pg0)
+{
+   struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
+   struct scsi_target *starget;
+   struct _pcie_device *pcie_device;
+   unsigned long flags;
+
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
+   if ((pcie_device->wwid == pcie_device_pg0->WWID) &&
+   (pcie_device->slot == pcie_device_pg0->Slot)) {
+   pcie_device->responding = 1;
+   starget = pcie_device->starget;
+   if (starget && starget->hostdata) {
+   sas_target_priv_data = starget->hostdata;
+   

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 80 
 1 file changed, 71 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 81f4d2d..dc1fdad 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2929,6 +2929,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;
 
@@ -2945,6 +2946,31 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd)
"%s handle(0x%04x), %s wwid(0x%016llx)\n",
device_str, priv_target->handle,
device_str, (unsigned long long)priv_target->sas_address);
+
+   } else if (priv_target->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_from_target(ioc, priv_target);
+   if (pcie_device) {
+   starget_printk(KERN_INFO, starget,
+   "handle(0x%04x), wwid(0x%016llx), port(%d)\n",
+   pcie_device->handle,
+   (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   starget_printk(KERN_INFO, starget,
+   "enclosure logical id(0x%016llx), 
slot(%d)\n",
+   (unsigned long long)
+   pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0] != '\0')
+   starget_printk(KERN_INFO, starget,
+   "enclosure level(0x%04x), connector 
name( %s)\n",
+   pcie_device->enclosure_level,
+   pcie_device->connector_name);
+   pcie_device_put(pcie_device);
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
} else {
spin_lock_irqsave(&ioc->sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
@@ -3680,18 +3706,14 @@ _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;
struct _tr_list *delayed_tr;
u32 ioc_state;
 
-   if (ioc->remove_host) {
-   dewtprintk(ioc, pr_info(MPT3SAS_FMT
-   "%s: host has been removed: handle(0x%04x)\n",
-   __func__, ioc->name, handle));
-   return;
-   } else if (ioc->pci_error_recovery) {
+   if (ioc->pci_error_recovery) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: host in pci error recovery: handle(0x%04x)\n",
__func__, ioc->name,
@@ -3722,14 +3744,52 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
sas_address = sas_device->sas_address;
}
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
+   if (!sas_device) {
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device && pcie_device->starget &&
+   pcie_device->starget->hostdata) {
+   sas_target_priv_data = pcie_device->starget->hostdata;
+   sas_target_priv_data->deleted = 1;
+   sas_address = pcie_device->wwid;
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   }
if (sas_target_priv_data) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"setting delete flag: handle(0x%04x), 
sas_addr(0x%016llx)\n",
ioc->name, handle,
   

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

2017-10-31 Thread Suganath Prabu S
Updated mpt3sas driver version to 17.100.00.00

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 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 2d005af..ef7d001 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -74,8 +74,8 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies "
 #define MPT3SAS_DESCRIPTION"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION "16.100.00.00"
-#define MPT3SAS_MAJOR_VERSION  16
+#define MPT3SAS_DRIVER_VERSION "17.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  17
 #define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
-- 
2.5.5



[PATCH 12/13] mpt3sas: Fix sparse warnings

2017-10-31 Thread Suganath Prabu S
1) Used variable __le64/__le32 whichever required in
building NVME PRP, and passed to LE Controller.
2) Remove unused functions, And Declared functions as
static which are used only in mpt3sas_scsih.c.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 22 ++---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 37 +---
 2 files changed, 16 insertions(+), 43 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 0da639d..3061c17 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;
@@ -1740,7 +1740,7 @@ base_is_prp_possible(struct MPT3SAS_ADAPTER *ioc,
struct scatterlist *sg_scmd;
bool build_prp = true;
 
-   data_length = cpu_to_le32(scsi_bufflen(scmd));
+   data_length = scsi_bufflen(scmd);
sg_scmd = scsi_sglist(scmd);
 
/* If Datalenth is <= 16K and number of SGE???s entries are <= 2
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 72dd57f..31e9343 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -599,7 +599,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)
 {
@@ -942,7 +942,7 @@ _scsih_sas_device_init_add(struct MPT3SAS_ADAPTER *ioc,
 }
 
 
-struct _pcie_device *
+static struct _pcie_device *
 __mpt3sas_get_pdev_by_wwid(struct MPT3SAS_ADAPTER *ioc, u64 wwid)
 {
struct _pcie_device *pcie_device;
@@ -975,7 +975,7 @@ found_device:
  *
  * This searches for pcie_device based on wwid, then return pcie_device object.
  */
-struct _pcie_device *
+static struct _pcie_device *
 mpt3sas_get_pdev_by_wwid(struct MPT3SAS_ADAPTER *ioc, u64 wwid)
 {
struct _pcie_device *pc

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 22 --
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index dc1fdad..72dd57f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2048,6 +2048,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
@@ -4834,8 +4842,9 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd 
*scmd)
/* Make sure Device is not raid volume.
 * We do not expose raid functionality to upper layer for warpdrive.
 */
-   if (!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev)
-   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
+   if (((!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev))
+   && !scsih_is_nvme(&scmd->device->sdev_gendev))
+   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
 
smid = mpt3sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
@@ -4880,8 +4889,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) {
@@ -5411,9 +5420,10 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index, u32 reply)
le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
if (!sas_device_priv_data->tlr_snoop_check) {
sas_device_priv_data->tlr_snoop_check++;
-   if (!ioc->is_warpdrive &&
+   if ((!ioc->is_warpdrive &&
!scsih_is_raid(&scmd->device->sdev_gendev) &&
-   sas_is_tlr_enabled(scmd->device) &&
+   !scsih_is_nvme(&scmd->device->sdev_gendev))
+   && sas_is_tlr_enabled(scmd->device) &&
response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
sas_disable_tlr(scmd->device);
sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
-- 
2.5.5



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

2017-10-31 Thread Suganath Prabu S
* Added debug prints for pcie devices in ioctl debug path. Which
will be helpful for debugging.
* Added PCIe device support for ioctl BTDHMAPPING ioctl.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c | 88 +-
 1 file changed, 58 insertions(+), 30 deletions(-)

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

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

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

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index a4ec459..2d005af 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -117,7 +117,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 21260bd..9006a60 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2324,6 +2324,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;
@@ -2454,6 +2455,55 @@ scsih_slave_configure(struct scsi_device *sdev)
}
}
 
+   /* PCIe handling */
+   if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_wwid(ioc,
+   sas_device_priv_data->sas_target->sas_address);
+   if (!pcie_device) {
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   dfailprintk(ioc, pr_warn(MPT3SAS_FMT
+   "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
+   __LINE__, __func__));
+   return 1;
+   }
+
+   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(&ioc->pcie_device_lock, flags);
+   scsih_change_queue_depth(sdev, qdepth);
+
+   if (pcie_device->nvme_mdts)
+   blk_queue_max_hw_sectors(sdev->request_queue,
+   pcie_device->nvme_mdts/512);
+   /* 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(&ioc->sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
   sas_device_priv_data->sas_target->sas_address);
-- 
2.5.5



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

2017-10-31 Thread Suganath Prabu S
* Added support for translating the SGLs associated with incoming
commands either to IEE SGL or NVMe PRPs for NVMe devices.

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 339 ++-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  41 +++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |   1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  14 +-
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |   2 +-
 5 files changed, 380 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 11c6afe..1ad3cbb 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 
 
 
@@ -1344,7 +1345,218 @@ _base_build_sg(struct MPT3SAS_ADAPTER *ioc, void *psge,
}
 }
 
-/* IEEE format sgls */
+/**
+ * base_make_prp_nvme -
+ * Prepare PRPs(Physical Region Page)- SGLs specific to NVMe drives only
+ *
+ * @ioc:   per adapter object
+ * @scmd:  SCSI command from the mid-layer
+ * @mpi_request:   mpi request
+ * @smid:  msg Index
+ * @sge_count: scatter gather element count.
+ *
+ * Returns:true: PRPs are built
+ * false: IEEE SGLs needs to be built
+ */
+void
+base_make_prp_nvme(struct MPT3SAS_ADAPTER *ioc,
+   struct scsi_cmnd *scmd,
+   Mpi25SCSIIORequest_t *mpi_request,
+   u16 smid, int sge_count)
+{
+   int sge_len, offset, num_prp_in_chain = 0;
+   Mpi25IeeeSgeChain64_t *main_chain_element, *ptr_first_sgl;
+   u64 *curr_buff;
+   dma_addr_t msg_phys;
+   u64 sge_addr;
+   u32 page_mask, page_mask_result;
+   struct scatterlist *sg_scmd;
+   u32 first_prp_len;
+   int data_len = scsi_bufflen(scmd);
+   u32 nvme_pg_size;
+
+   nvme_pg_size = max_t(u32, ioc->page_size, NVME_PRP_PAGE_SIZE);
+   /*
+* Nvme has a very convoluted prp format.  One prp is required
+* for each page or partial page. Driver need to split up OS sg_list
+* entries if it is longer than one page or cross a page
+* boundary.  Driver also have to insert a PRP list pointer entry as
+* the last entry in each physical page of the PRP list.
+*
+* NOTE: The first PRP "entry" is actually placed in the first
+* SGL entry in the main message as IEEE 64 format.  The 2nd
+* entry in the main message is the chain element, and the rest
+* of the PRP entries are built in the contiguous pcie buffer.
+*/
+   page_mask = nvme_pg_size - 1;
+
+   /*
+* Native SGL is needed.
+* Put a chain element in main message frame that points to the first
+* chain buffer.
+*
+* NOTE:  The ChainOffset field must be 0 when using a chain pointer to
+*a native SGL.
+*/
+
+   /* Set main message chain element pointer */
+   main_chain_element = (pMpi25IeeeSgeChain64_t)&mpi_request->SGL;
+   /*
+* For NVMe the chain element needs to be the 2nd SG entry in the main
+* message.
+*/
+   main_chain_element = (Mpi25IeeeSgeChain64_t *)
+   ((u8 *)main_chain_element + sizeof(MPI25_IEEE_SGE_CHAIN64));
+
+   /*
+* For the PRP entries, use the specially allocated buffer of
+* contiguous memory.  Normal chain buffers can't be used
+* because each chain buffer would need to be the size of an OS
+* page (4k).
+*/
+   curr_buff = mpt3sas_base_get_pcie_sgl(ioc, smid);
+   msg_phys = (dma_addr_t)mpt3sas_base_get_pcie_sgl_dma(ioc, smid);
+
+   main_chain_element->Address = cpu_to_le64(msg_phys);
+   main_chain_element->NextChainOffset = 0;
+   main_chain_element->Flags = MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
+   MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR |
+   MPI26_IEEE_SGE_FLAGS_NSF_NVME_PRP;
+
+   /* Build first prp, sge need not to be page aligned*/
+   ptr_first_sgl = (pMpi25IeeeSgeChain64_t)&mpi_request->SGL;
+   sg_scmd = scsi_sglist(scmd);
+   sge_addr = sg_dma_address(sg_scmd);
+   sge_len = sg_dma_len(sg_scmd);
+
+   offset = (u32)(sge_addr & page_mask);
+   first_prp_len = nvme_pg_size - offset;
+
+   ptr_first_sgl->Address = cpu_to_le64(sge_addr);
+   ptr_first_sgl->Length = cpu_to_le32(

[PATCH 00/13] mpt3sas driver NVMe support:

2017-10-31 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: 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: Fix sparse warnings
  mpt3sas: Update mpt3sas driver version.

 drivers/scsi/mpt3sas/mpt3sas_base.c  |  643 -
 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 | 2080 +++---
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 7 files changed, 3054 insertions(+), 330 deletions(-)

Thanks,
Suganath Prabu S
-- 
2.5.5



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

2017-09-18 Thread Suganath Prabu Subramani
Hi Martin,

On Fri, Sep 15, 2017 at 6:37 AM, Martin K. Petersen
 wrote:
>
> Suganath,
>
>> Is there any update on the submitted mpt3sas patches.
>
> We are waiting for you to report back your findings on PRP vs. SGL.

We are working on this, since there is h/w dependent, we are in
discussion with H/W & F/W team and doing experiments. If there is no
impact, and if SGL translation has to be removed, this change has to
go through some phase of testing, before we post it to upstream, since
that is not inline with H/W requirement.

The hardware translation of IEEE SGL to NVMe PRPs has limitation.

We have added the below comment in patch 3 as well:

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

Current code posted to upstream is inline with hardware requirements
and well tested internally.

SGL vs NVMe PRP building in driver is small sanity check for decision making
and it is not going to change in long run.

Also, Making all PRP buffer may or may not need FW changes (assuming
it is possible.),
we may end up into multiple FW version check.

Since this is main IO path and current driver is following H/W limitation,
we should avoid any changes in this area until and unless change is
universal acceptable in FW (for all type of work load).

Hope this clarifies.
>
> --
> Martin K. Petersen  Oracle Linux Engineering

Thanks,
Suganath Prabu S


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

2017-09-13 Thread Suganath Prabu Subramani
Hi Martin,

Is there any update on the submitted mpt3sas patches.

Thanks,
Suganath Prabu S

On Fri, Sep 1, 2017 at 2:09 PM, Suganath Prabu Subramani
 wrote:
> Hi Martin,
>
> On Fri, Sep 1, 2017 at 8:52 AM, Martin K. Petersen
>  wrote:
>>
>> Hi Suganath,
>>
>>> Let me explain - NVME device fast path is possible in two ways.  IEEE
>>> SGL and PRP SGL. Due to h/w constraint we choose IEEE SGL only for
>>> smaller IO size.  Both above is true h/w Fast Path and no firmware
>>> involvement.
>>
>>> Agree with you. We are planning to see if we can keep only simple Fast
>>> Path using only PRP.
>>
>> That would be great, thank you!
>>
>>> Currently there is no performance issue for UNMAP translation in FW.
>>
>> Good!
>>
>>>> And yet patch 4 circumvents that statement by adding support for
>>>> encapsulated commands to bypass the FW translation...
>>>
>>> This path is not due to performance reason. User wants to interact
>>> with NVME drive in native NVME command for management.
>>
>> Patch 4 states:
>>
>> "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."
>>
>> --
>
> The statement in description of patch 4 is added by mistake, We ll
> correct the description and re sending that.
>
>> Martin K. Petersen  Oracle Linux Engineering
>
> Thanks,
> Suganath Prabu S


[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 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 56 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h |  1 +
 drivers/scsi/mpt3sas/mpt3sas_ctl.c  | 69 +
 3 files changed, 119 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 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;
+
+   descriptor.Default.RequestFlags =
+   MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
+   descriptor.Default.MSIxIndex =  _base_get_msix_index(ioc);
+   descriptor.Default.SMID = cpu_to_le16(smid);
+   descriptor.Default.LMID = 0;
+   descriptor.Default.DescriptorTypeDependent = 0;
+   _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
+   &ioc->scsi_lookup_lock);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * @ioc: per adapter object
  * @smid: system request message index
@@ -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;
+
+   descriptor.RequestFlags = MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
+   descriptor.MSIxIndex = _base_get_msix_index(ioc);
+   descriptor.SMID = cpu_to_le16(smid);
+
+   writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * use Atomic Request Descriptor
  * @ioc: per adapter object
@@ -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_encap = &_base_put_smid_nvme_encap;
 

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

2017-09-01 Thread Suganath Prabu Subramani
Hi Martin,

On Fri, Sep 1, 2017 at 8:52 AM, Martin K. Petersen
 wrote:
>
> Hi Suganath,
>
>> Let me explain - NVME device fast path is possible in two ways.  IEEE
>> SGL and PRP SGL. Due to h/w constraint we choose IEEE SGL only for
>> smaller IO size.  Both above is true h/w Fast Path and no firmware
>> involvement.
>
>> Agree with you. We are planning to see if we can keep only simple Fast
>> Path using only PRP.
>
> That would be great, thank you!
>
>> Currently there is no performance issue for UNMAP translation in FW.
>
> Good!
>
>>> And yet patch 4 circumvents that statement by adding support for
>>> encapsulated commands to bypass the FW translation...
>>
>> This path is not due to performance reason. User wants to interact
>> with NVME drive in native NVME command for management.
>
> Patch 4 states:
>
> "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."
>
> --

The statement in description of patch 4 is added by mistake, We ll
correct the description and re sending that.

> Martin K. Petersen  Oracle Linux Engineering

Thanks,
Suganath Prabu S


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

2017-08-30 Thread Suganath Prabu Subramani
Hi Martin,
Replied inline.

Thanks,
Suganath Prabu S

On Thu, Aug 31, 2017 at 8:35 AM, Martin K. Petersen
 wrote:
>
> Hi Suganath,
>
>> Theoretically we want to use h/w capability (to translate IEEE to PRP)
>> for smaller IO size to leverage h/w capability.
>
> Nobody says we have to use the capability just because the hardware has
> it.
>
> Unlike some other operating systems, Linux will only submit I/Os to the
> driver that conform to the reported underlying constraints of the
> hardware.

 In general, h/w constraints are handled. What we missed is
Fast Path h/w
which is not exposed to OS.

> I fail to understand how letting the HBA firmware translate an
> SGL to a PRP for a subset of I/Os could do anything but add latency.

 Let me explain - NVME device fast path is possible in two ways.
IEEE SGL and PRP SGL. Due to h/w constraint we choose IEEE SGL only for
smaller IO size.
Both above is true h/w Fast Path and no firmware involvement.

> Plus complexity in the hot path of the driver.

 Agree with you. We are planning to see if we can keep only
simple Fast
Path using only PRP. It will take some time to finalize as we have to
engage h/w and f/w team.  BTW - This area is h/w dependent and we do not
see further changes in this area.

>
>> - If the unmap translation in firmware is slow, why don't you translate
>>   WRITE SAME/w UNMAP set to DSM DEALLOCATE without requiring
>>   applications to do encapsulated passthrough?
>
>> => As of now, current FW supports UNMAP command but not WRITE_SAME for
>> NVME drive. We did some experiment to convert UMAP command in driver,
>> but that is not really giving any performance improvement.
>
> It is imperative that the common use case, Linux' discard
> infrastructure, is working correctly and is as performant as any
> application-driven passthrough workaround.
>
> Unlike SCSI-to-SATA translation you have the benefit of a 1:1 mapping
> between UNMAP and DEALLOCATE. I'm not even sure why there would be a
> significant performance penalty in the firmware?

 I agree. Currently there is no performance issue for UNMAP
translation in
FW.


>> We would like to continue with UNMAP (and all other non-read/write
>> commands) to be handled in FW.
>
> And yet patch 4 circumvents that statement by adding support for
> encapsulated commands to bypass the FW translation...

 This path is not due to performance reason. User wants to
interact with
NVME drive in native NVME command for management.

>
> --
> Martin K. Petersen  Oracle Linux Engineering


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

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

v1 - v3: no change.
v3 - v4: Removed hole check as suggested by Martin.
With commit-id <5a8d75a1b8c99bdc926ba69b7b7dbe4fae81a5af> "block: 
fix bio_will_gap() for first bvec with offset" driver can always assume
that their won't be any holes in the data buffers pointed by SGE's and no
need to have extra checks for detecting the holes.
v4 - v5: Removed the check to find data transfer length exceeding MDTS,
as we are setting max I/O size to match MDTS in slave_configure.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 590 ++-
 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, 635 insertions(+), 16 deletions(-)

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

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 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(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device) {
+   if (!list_empty(&pcie_device->list)) {
+   list_del_init(&pcie_device->list);
+   was_on_pcie_device_list = 1;
+   pcie_device_put(pcie_device);
+   }
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   if (was_on_pcie_device_list) {
+   _scsih_pcie_device_remove_from_sml(ioc, pcie_device);
+   pcie_device_put(pcie_device);
+   }
+}
+
 /**
  * _scsih_pcie_device_add - add pcie_device object
  * @ioc: per adapter object
@@ -6533,6 +6570,83 @@ _scsih_check_pcie_access_status(struct MPT3SAS_ADAPTER 
*ioc, u64 wwid,
(unsigned long long)wwid, handle);
return rc;
 }
+
+/**
+ * _scsih_pcie_device_remove_from_sml -  removing pcie device
+ * from SML and free up associated memory
+ * @ioc: per adapter object
+ * @pcie_device: the pcie_device object
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
+   struct _pcie_device *pcie_device)
+{
+   struct MPT3SAS_TARGET *sas_target_priv_data;
+
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: handle(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
+   pcie_device->handle, (unsigned long long)
+   pcie_device->wwid));
+   if (pcie_device->enclosure_handle != 0)
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: enclosure logical id(0x%016llx), slot(%d)\n",
+   ioc->name, __func__,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot));
+   if (pcie_device->connector_name[0] != '\0')
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: enclosure level(0x%04x), connector name( %s)\n",
+   ioc->name, __func__,
+   pcie_device->enclosure_level,
+   pcie_device->connector_name));
+
+   if (pcie_device->starget && pcie_device->starget->hostdata) {
+   sas_target_priv_data = pcie_device->starget->hostdata;
+   sas_target_priv_data->deleted = 1;
+   _scsih_ublock_io_device(ioc, pcie_device->wwid);
+   sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE;
+   }
+
+   pr_info(MPT3SAS_FMT
+   "removing handle(0x%04x), wwid (0x%016llx)\n",
+   ioc->name, pcie_device->handle,
+   (unsigned long long) pcie_device->wwid);
+   if (pcie_device->enclosure_handle != 0)
+   pr_info(MPT3SAS_FMT
+   "removing : enclosure logical id(0x%016llx), slot(%d)\n",
+   ioc->name,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0] != '\0')
+   pr_info(MPT3SAS_FMT
+   "removing: enclosure level(0x%04x), connector name( %s

[v5 07/14] mpt3sas: Handle NVMe PCIe device related events generated from firmware.

2017-08-30 Thread Suganath Prabu S
* The controller firmware sends separate events for NVMe devices and
PCIe switches similar to existing SAS events.

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

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

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  30 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 471 ++-
 2 files changed, 495 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 9653cfa..6e0a940 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)
@@ -6154,8 +6174,16 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
_base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS);
_base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
_base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD);
-   if (ioc->hba_mpi_version_belonged == MPI26_VERSION)
+   if (ioc->hba_mpi_version_belonged == MPI26_VERSION) {
_base_unmask_events(ioc, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
+   if (ioc->is_gen35_ioc) {
+   _base_unmask_events(ioc,
+   MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE);
+   _base_unmask_events(ioc, MPI2_EVENT_PCIE_ENUMERATION);
+   _base_unmask_events(ioc,
+   MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST);
+   }
+   }
 
r = _base_make_ioc_operational(ioc);
if (r)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 710ea63..344f946 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -75,6 +75,8 @@ static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle,
 static int _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static void _scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
struct _pcie_device *pcie_device);
+static void
+_scsih_pcie_check_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
 /* global parameters */
@@ -3458,8 +3460,6 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
struct _sas_device *sas_device;
 
sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
-   if (!sas_device)
-   return;
 
shost_for_each_device(sdev, ioc->shost) {
sas_device_priv_data = sdev->hostdata;
@@ -3469,7 +3469,7 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
continue;
if (sas_device_priv_data->block)
continue;
-   if (sas_device->pend_sas_rphy_add)
+   if (sas_device && sas_device->pend_sas_rphy_add)
continue;
if (sas_device_priv_data->ignore_delay_remove) {
sdev_printk(KERN_INFO, sdev,
@@ -3480,7 +3480,8 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
_scsih_internal_device_block(sdev, sas_device_priv_data);
}
 
-   sas_device_put(sas_device);
+   if (sas_de

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 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 8834919..a6bb65c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4879,6 +4879,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;
@@ -5011,6 +5012,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) {
@@ -5057,11 +5080,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd,
struct sense_info data;
_scsih_normalize_sense(scmd->sense_buffer, &data);
pr_warn(MPT3SAS_FMT
-   "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], 
count(%d)\n",
-   ioc->name, data.skey,
-   data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
+ "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
+ ioc->name, data.skey,
+ data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
}
-
if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
response_info = le32_to_cpu(mpi_reply->ResponseInfo);
response_bytes = (u8 *)&response_info;
@@ -8522,6 +8544,130 @@ _scsih_search_responding_sas_devices(struct 
MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * _scsih_mark_responding_pcie_device - mark a pcie_device as responding
+ * @ioc: per adapter object
+ * @pcie_device_pg0: PCIe Device page 0
+ *
+ * After host reset, find out whether devices are still responding.
+ * Used in _scsih_remove_unresponding_devices.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_mark_responding_pcie_device(struct MPT3SAS_ADAPTER *ioc,
+   Mpi26PCIeDevicePage0_t *pcie_device_pg0)
+{
+   struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
+   struct scsi_target *starget;
+   struct _pcie_device *pcie_device;
+   unsigned long flags;
+
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
+   if ((pcie_device->wwid == pcie_device_pg0->WWID) &&
+   (pcie_device->slot == pcie_device_pg0->Slot)) {
+   pcie_device->responding = 1;
+   starget = pcie_device->starget;
+   if (starget && starget->hostdata) {
+   sas_target_priv_data = starget->ho

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 83 ++--
 1 file changed, 70 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index a6bb65c..8754ade 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2903,6 +2903,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;
 
@@ -2919,6 +2920,31 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd)
"%s handle(0x%04x), %s wwid(0x%016llx)\n",
device_str, priv_target->handle,
device_str, (unsigned long long)priv_target->sas_address);
+
+   } else if (priv_target->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_from_target(ioc, priv_target);
+   if (pcie_device) {
+   starget_printk(KERN_INFO, starget,
+   "handle(0x%04x), wwid(0x%016llx), port(%d)\n",
+   pcie_device->handle,
+   (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   starget_printk(KERN_INFO, starget,
+   "enclosure logical id(0x%016llx), 
slot(%d)\n",
+   (unsigned long long)
+   pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0] != '\0')
+   starget_printk(KERN_INFO, starget,
+   "enclosure level(0x%04x), connector 
name( %s)\n",
+   pcie_device->enclosure_level,
+   pcie_device->connector_name);
+   pcie_device_put(pcie_device);
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
} else {
spin_lock_irqsave(&ioc->sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
@@ -3662,6 +3688,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;
@@ -3704,24 +3731,52 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
sas_address = sas_device->sas_address;
}
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-
+   if (!sas_device) {
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device && pcie_device->starget &&
+   pcie_device->starget->hostdata) {
+   sas_target_priv_data = pcie_device->starget->hostdata;
+   sas_target_priv_data->deleted = 1;
+   sas_address = pcie_device->wwid;
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   }
if (sas_target_priv_data) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"setting delete flag: handle(0x%04x), 
sas_addr(0x%016llx)\n",
ioc->name, handle,
(unsigned long long)sas_address));
-   if (sas_device->enclosure_handle != 0)
-   dewtprintk(ioc, pr_info(MPT3SAS_FMT
-"setting delete flag:enclosure logical id(0x%016llx),"
-" slot(%d)\n", ioc->name, (unsigned long long)
- sas_device->enclosure_logical_id,
- sas_device->slot));
-   if (sas_device->connector_name[0] != '\0')
-

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

2017-08-30 Thread Suganath Prabu S
* Added debug prints for pcie devices in ioctl debug path. Which
will be helpful for debugging.
* Added PCIe device support for ioctl BTDHMAPPING ioctl.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c | 88 +-
 1 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, &ioc->sas_device_list, list) {
-   if (sas_device->handle != handle)
-   continue;
-   r = sas_device;
-   goto out;
-   }
-
- out:
-   return r;
-}
-
-/**
  * _ctl_display_some_debug - debug routine
  * @ioc: per adapter object
  * @smid: system request message index
@@ -229,10 +203,9 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
Mpi2SCSIIOReply_t *scsi_reply =
(Mpi2SCSIIOReply_t *)mpi_reply;
struct _sas_device *sas_device = NULL;
-   unsigned long flags;
+   struct _pcie_device *pcie_device = NULL;
 
-   spin_lock_irqsave(&ioc->sas_device_lock, flags);
-   sas_device = _ctl_sas_device_find_by_handle(ioc,
+   sas_device = mpt3sas_get_sdev_by_handle(ioc,
le16_to_cpu(scsi_reply->DevHandle));
if (sas_device) {
pr_warn(MPT3SAS_FMT "\tsas_address(0x%016llx), 
phy(%d)\n",
@@ -242,8 +215,25 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
"\tenclosure_logical_id(0x%016llx), slot(%d)\n",
ioc->name, (unsigned long long)
sas_device->enclosure_logical_id, sas_device->slot);
+   sas_device_put(sas_device);
+   }
+   if (!sas_device) {
+   pcie_device = mpt3sas_get_pdev_by_handle(ioc,
+   le16_to_cpu(scsi_reply->DevHandle));
+   if (pcie_device) {
+   pr_warn(MPT3SAS_FMT
+   "\tWWID(0x%016llx), port(%d)\n", ioc->name,
+   (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   pr_warn(MPT3SAS_FMT
+   "\tenclosure_logical_id(0x%016llx), 
slot(%d)\n",
+   ioc->name, (unsigned long long)
+   pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   pcie_device_put(pcie_device);
+   }
}
-   spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)
pr_info(MPT3SAS_FMT
"\tscsi_state(0x%02x), scsi_status"
@@ -1353,6 +1343,42 @@ _ctl_btdh_search_sas_device(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _ctl_btdh_search_pcie_device - searching for pcie device
+ * @ioc: per adapter object
+ * @btdh: btdh ioctl payload
+ */
+static int
+_ctl_btdh_search_pcie_device(struct MPT3SAS_ADAPTER *ioc,
+   struct mpt3_ioctl_btdh_mapping *btdh)
+{
+   struct _pcie_device *pcie_device;
+   unsigned long flags;
+   int rc = 0;
+
+   if (list_empty(&ioc->pcie_device_list))
+   return rc;
+
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
+   if (btdh->bus == 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 

[v5 13/14] mpt3sas: Update mpt3sas driver version.

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++--
 1 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 "
 #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



[v5 14/14] mpt3sas: Fix sparse warnings

2017-08-30 Thread Suganath Prabu S
1) Used variable __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 
Signed-off-by: Suganath Prabu S 
---
 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 6e0a940..f86c7b2 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 aece862..6960d69 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_device *
+static struct _pcie_device *
 __mpt3sas_get_pdev_by_wwid(struct MPT3SAS_ADAPTER *ioc, u64 wwid)
 {
struct _pcie_device *pcie_device;
@@ -941,

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 22 --
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 8754ade..aece862 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
@@ -4821,8 +4829,9 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd 
*scmd)
/* Make sure Device is not raid volume.
 * We do not expose raid functionality to upper layer for warpdrive.
 */
-   if (!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev)
-   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
+   if (((!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev))
+   && !scsih_is_nvme(&scmd->device->sdev_gendev))
+   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
 
smid = mpt3sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
@@ -4867,8 +4876,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) {
@@ -5416,9 +5425,10 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index, u32 reply)
le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
if (!sas_device_priv_data->tlr_snoop_check) {
sas_device_priv_data->tlr_snoop_check++;
-   if (!ioc->is_warpdrive &&
+   if ((!ioc->is_warpdrive &&
!scsih_is_raid(&scmd->device->sdev_gendev) &&
-   sas_is_tlr_enabled(scmd->device) &&
+   !scsih_is_nvme(&scmd->device->sdev_gendev))
+   && sas_is_tlr_enabled(scmd->device) &&
response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
sas_disable_tlr(scmd->device);
sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
-- 
2.5.5



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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  2 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 50 
 2 files changed, 51 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..8834919 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,55 @@ scsih_slave_configure(struct scsi_device *sdev)
}
}
 
+   /* PCIe handling */
+   if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_wwid(ioc,
+   sas_device_priv_data->sas_target->sas_address);
+   if (!pcie_device) {
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   dfailprintk(ioc, pr_warn(MPT3SAS_FMT
+   "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
+   __LINE__, __func__));
+   return 1;
+   }
+
+   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(&ioc->pcie_device_lock, flags);
+   scsih_change_queue_depth(sdev, qdepth);
+
+   if (pcie_device->nvme_mdts)
+   blk_queue_max_hw_sectors(sdev->request_queue,
+   pcie_device->nvme_mdts/512);
+   /* 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(&ioc->sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
   sas_device_priv_data->sas_target->sas_address);
-- 
2.5.5



[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 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h   |  10 +
 drivers/scsi/mpt3sas/mpt3sas_config.c | 100 +++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c  | 473 +-
 3 files changed, 575 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index c4be9ad..09ad823 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1458,6 +1458,10 @@ struct _sas_device *mpt3sas_get_sdev_by_addr(
 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
 struct _sas_device *__mpt3sas_get_sdev_by_addr(
 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
+struct _sas_device *mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
+   u16 handle);
+struct _pcie_device *mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
+   u16 handle);
 
 void mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc);
 struct _raid_device *
@@ -1496,6 +1500,12 @@ int mpt3sas_config_get_sas_device_pg0(struct 
MPT3SAS_ADAPTER *ioc,
 int mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+   u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
+   u32 form, u32 handle);
 int mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
u16 sz);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c 
b/drivers/scsi/mpt3sas/mpt3sas_config.c
index dd62701..1c747cf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -150,6 +150,24 @@ _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, 
u16 smid,
case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
desc = "driver_mapping";
break;
+   case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:
+   desc = "sas_port";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:
+   desc = "ext_manufacturing";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:
+   desc = "pcie_io_unit";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:
+   desc = "pcie_switch";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:
+   desc = "pcie_device";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:
+   desc = "pcie_link";
+   break;
}
break;
}
@@ -1053,6 +1071,88 @@ mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER 
*ioc,
 }
 
 /**
+ * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
+ * @ioc: per adapter object
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * @form: GET_NEXT_HANDLE or HANDLE
+ * @handle: device handle
+ * Context: sleep.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+   u32 form, u32 handle)
+{
+   Mpi2ConfigRequest_t mpi_request;
+   int r;
+
+   memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+   mpi_request.Function = MPI2_FUNCTION_CONFIG;
+   mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+   mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
+   mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
+   mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
+   mpi_request.Header.PageNumber = 0;
+   ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
+   r = _config_request(ioc, &mpi_request, mpi_reply,
+   MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+   if (r)
+   goto out;
+
+   mpi_request.PageAddress = cpu_to_le32(form | handle);
+   mpi_request.Action = MPI2_CONF

[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 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 56 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h |  1 +
 drivers/scsi/mpt3sas/mpt3sas_ctl.c  | 69 +
 3 files changed, 119 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 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;
+
+   descriptor.Default.RequestFlags =
+   MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
+   descriptor.Default.MSIxIndex =  _base_get_msix_index(ioc);
+   descriptor.Default.SMID = cpu_to_le16(smid);
+   descriptor.Default.LMID = 0;
+   descriptor.Default.DescriptorTypeDependent = 0;
+   _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
+   &ioc->scsi_lookup_lock);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * @ioc: per adapter object
  * @smid: system request message index
@@ -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;
+
+   descriptor.RequestFlags = MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
+   descriptor.MSIxIndex = _base_get_msix_index(ioc);
+   descriptor.SMID = cpu_to_le16(smid);
+
+   writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * use Atomic Request Descriptor
  * @ioc: per adapter object
@@ -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_pu

[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 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  | 110 -
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 431 ---
 2 files changed, 507 insertions(+), 34 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 099ab4c..c522057 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -159,6 +159,7 @@
 #define MPT_TARGET_FLAGS_VOLUME0x02
 #define MPT_TARGET_FLAGS_DELETED   0x04
 #define MPT_TARGET_FASTPATH_IO 0x08
+#define MPT_TARGET_FLAGS_PCIE_DEVICE   0x10
 
 #define SAS2_PCI_DEVICE_B0_REVISION(0x01)
 #define SAS3_PCI_DEVICE_C0_REVISION(0x02)
@@ -357,7 +358,8 @@ struct Mpi2ManufacturingPage11_t {
  * @flags: MPT_TARGET_FLAGS_XXX flags
  * @deleted: target flaged for deletion
  * @tm_busy: target is busy with TM request.
- * @sdev: The sas_device associated with this target
+ * @sas_dev: The sas_device associated with this target
+ * @pcie_dev: The pcie device associated with this target
  */
 struct MPT3SAS_TARGET {
struct scsi_target *starget;
@@ -368,7 +370,8 @@ struct MPT3SAS_TARGET {
u32 flags;
u8  deleted;
u8  tm_busy;
-   struct _sas_device *sdev;
+   struct _sas_device *sas_dev;
+   struct _pcie_device *pcie_dev;
 };
 
 
@@ -508,6 +511,89 @@ static inline void sas_device_put(struct _sas_device *s)
kref_put(&s->refcount, sas_device_free);
 }
 
+/*
+ * struct _pcie_device - attached PCIe device information
+ * @list: pcie device list
+ * @starget: starget object
+ * @wwid: device WWID
+ * @handle: device handle
+ * @device_info: bitfield provides detailed info about the device
+ * @id: target id
+ * @channel: target channel
+ * @slot: slot number
+ * @port_num: port number
+ * @responding: used in _scsih_pcie_device_mark_responding
+ * @fast_path: fast path feature enable bit
+ * @nvme_mdts: MaximumDataTransferSize from PCIe Device Page 2 for
+ * NVMe device only
+ * @enclosure_handle: enclosure handle
+ * @enclosure_logical_id: enclosure logical identifier
+ * @enclosure_level: The level of device's enclosure from the controller
+ * @connector_name: ASCII value of the Connector's name
+ * @serial_number: pointer of serial number string allocated runtime
+ * @refcount: reference count for deletion
+ */
+struct _pcie_device {
+   struct list_head list;
+   struct scsi_target *starget;
+   u64 wwid;
+   u16 handle;
+   u32 device_info;
+   int id;
+   int channel;
+   u16 slot;
+   u8  port_num;
+   u8  responding;
+   u8  fast_path;
+   u32 nvme_mdts;
+   u16 enclosure_handle;
+   u64 enclosure_logical_id;
+   u8  enclosure_level;
+   u8  connector_name[4];
+   u8  *serial_number;
+   struct kref refcount;
+};
+/**
+ * pcie_device_get - Increment the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will increment the
+ * reference count of the pcie device for which this function called.
+ *
+ */
+static inline void pcie_device_get(struct _pcie_device *p)
+{
+   kref_get(&p->refcount);
+}
+
+/**
+ * pcie_device_free - Release the pcie device object
+ * @r - kref object
+ *
+ * Free's the pcie device object. It will be called when reference count
+ * reaches to zero.
+ */
+static inline void pcie_device_free(struct kref *r)
+{
+   kfree(container_of(r, struct _pcie_device, refcount));
+}
+
+/**
+ * pcie_device_put - Decrement the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will decrement the
+ * reference count of the pcie device for which this function called.
+ *
+ * When refernce count reaches to Zero, this will call pcie_device_free to the
+ * pcie_device object.
+ */
+static inline void pcie_device_put(struct _pcie_device *p)
+{
+   kref_put(&p->refcount, pcie_device_free);
+}
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -556,12 +642,13 @@ struct _raid_device {
 
 /**
  * struct _boot_device - boot device 

[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 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2.h  |  43 ++-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 564 +--
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |  11 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  | 282 +-
 drivers/scsi/mpt3sas/mpi/mpi2_pci.h  | 112 +++
 drivers/scsi/mpt3sas/mpi/mpi2_tool.h |  14 +-
 6 files changed, 992 insertions(+), 34 deletions(-)
 create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h
index a9a659f..bc59058 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2.h
@@ -8,7 +8,7 @@
  * scatter/gather formats.
  * Creation Date:  June 21, 2006
  *
- * mpi2.h Version:  02.00.42
+ * mpi2.h Version:  02.00.48
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *   prefix are for use only on MPI v2.5 products, and must not be used
@@ -103,6 +103,16 @@
  * 08-25-15  02.00.40  Bumped MPI2_HEADER_VERSION_UNIT.
  * 12-15-15  02.00.41  Bumped MPI_HEADER_VERSION_UNIT
  * 01-01-16  02.00.42  Bumped MPI_HEADER_VERSION_UNIT
+ * 04-05-16  02.00.43  Modified  MPI26_DIAG_BOOT_DEVICE_SELECT defines
+ * to be unique within first 32 characters.
+ * Removed AHCI support.
+ * Removed SOP support.
+ * Bumped MPI2_HEADER_VERSION_UNIT.
+ * 04-10-16  02.00.44  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 07-06-16  02.00.45  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 09-02-16  02.00.46  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 11-23-16  02.00.47  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 02-03-17  02.00.48  Bumped MPI2_HEADER_VERSION_UNIT.
  * --
  */
 
@@ -142,7 +152,7 @@
 #define MPI2_VERSION_02_06 (0x0206)
 
 /*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT(0x2A)
+#define MPI2_HEADER_VERSION_UNIT(0x30)
 #define MPI2_HEADER_VERSION_DEV (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK   (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT  (8)
@@ -249,6 +259,12 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS {
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -367,6 +383,7 @@ typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR {
 #define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE(0x08)
 #define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR(0x0A)
 #define MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO  (0x0C)
+#define MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED  (0x10)
 
 #define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01)
 
@@ -425,6 +442,13 @@ typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
Mpi25FastPathSCSIIORequestDescriptor_t,
*pMpi25FastPathSCSIIORequestDescriptor_t;
 
+/*PCIe Encapsulated Request Descriptor */
+typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
+   MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+   *PTR_MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+   Mpi26PCIeEncapsulatedRequestDescriptor_t,
+   *pMpi26PCIeEncapsulatedRequestDescriptor_t;
+
 /*union of Request Descriptors */
 typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
MPI2_DEFAULT_REQUEST_DESCRIPTOR Default;
@@ -433,6 +457,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget;
MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator;
MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR FastPathSCSIIO;
+   MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR PCIeEncapsulated;
U64 Words;
 } MPI2_REQUEST_DESCRIPTOR_UNION,
*PTR_MPI2_REQUEST_DESCRIPTOR_UNION,
@@ -450,6 +475,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
  *  Atomic SCSI Target Request Descriptor
  *  Atomic RAID Accelerator Request Descriptor
  *  Atomic Fast Path SCSI IO Request Descriptor
+ *  Atomic PCIe Encapsulated Request Descriptor
  */
 
 /*Atomic Request Descriptor */
@@ -487,6 +513,7 @@ typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR {
 #define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER   (0x03)
 #define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS(0x05)
 #define MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS  (0x06)
+#define

[v5 00/14] mpt3sas driver NVMe support:

2017-08-30 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 v5 patset:
1) Removed the check to find data transfer length
exceeding MDTS, Since we are setting max I/O size to
match MDTS, this check is not required.

mpt3sas v4 patset:
1) Removed code which detects gaps/holes in IO data buffers.
With commit-id 5a8d75a1b8c99bdc926ba69b7b7dbe4fae81a5af (block:
fix bio_will_gap() for first bvec with offset) driver can always assume that
their won't be any holes in the data buffers pointed by SGE's

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):
  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 warnings

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

-- 
2.5.5



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

2017-08-30 Thread Suganath Prabu Subramani
Hi Martin,

Replied in line.

- I don't understand why you go through all these hoops to decide
  whether to use PRPs or IEEE scatterlists. If the firmware translation
  is slow, why even bother with the SG format in the first place? Set
  the max I/O size to match MDTS and you're done.

=>  We will  set MDTS value as max hw sectors using
blk_queue_max_hw_sectors(). As of now, we see correct MDTS value is
being set to block layer via VPD page 0xb0 (Block limits VPD page )
response from FW for NVME device.
=> I will remove MDTS checks in IO path.


- What's the benefit of using SG for regular I/O commands?

=>  Broadcom's IT Tri-mode HBA hardware has a capability of
translating IEEE SGLs to PRP's only up to ~4 page block size.
If the IO block size is greater than that (along with other condition
described code base_is_prp_possible), driver has to frame the PRP's to
avoid FW intervention. Both the case is a fast path, but for smaller
IO (up to 20K) size will frame IEEE SGL and large IO size will frame
PRP format SGL. Theoretically we want to use h/w capability (to
translate IEEE to PRP) for smaller IO size to leverage h/w capability.
We are investigating if at all we can send all PRP and avoid checks in
driver, but that exercise may take time as we have many different
opinions. We prefer to use existing code as it is stable and in-line
with h/w requirement.


- If the unmap translation in firmware is slow, why don't you translate
  WRITE SAME/w UNMAP set to DSM DEALLOCATE without requiring
  applications to do encapsulated passthrough?

=> As of now, current FW supports UNMAP command but not WRITE_SAME for
NVME drive. We did some experiment to convert UMAP command in driver,
but that is not really giving any performance improvement. We would
like to continue with UNMAP (and all other non-read/write commands) to
be handled in FW.


- Also make sure you attribute your patches correctly (From: root
). And you don't need
that long CC: list. Just send the patch series to
linux-s...@vger.kernel.org.

=>  I will fix this type of issue going forward

Thanks,
Suganath Prabu S

On Wed, Aug 23, 2017 at 7:48 AM, Martin K. Petersen
 wrote:
>
> Suganath,
>
>>   mpt3sas: SGL to PRP Translation for I/Os to NVMe  devices
>
> I'm still confused about this patch.
>
>  - I don't understand why you go through all these hoops to decide
>whether to use PRPs or IEEE scatterlists. If the firmware translation
>is slow, why even bother with the SG format in the first place? Set
>the max I/O size to match MDTS and you're done.
>
>  - What's the benefit of using SG for regular I/O commands?
>
>  - If the unmap translation in firmware is slow, why don't you translate
>WRITE SAME/w UNMAP set to DSM DEALLOCATE without requiring
>applications to do encapsulated passthrough?
>
> Also make sure you attribute your patches correctly (From: root
> ). And you don't need that
> long CC: list. Just send the patch series to linux-s...@vger.kernel.org.
>
> Thanks!
>
> --
> Martin K. Petersen  Oracle Linux Engineering


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

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

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

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 56 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h |  1 +
 drivers/scsi/mpt3sas/mpt3sas_ctl.c  | 69 +
 3 files changed, 119 insertions(+), 7 deletions(-)

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

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

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

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

_scsih_pcie_add_device
_scsih_pcie_device_add
_scsih_pcie_device_init_add
_scsih_check_pcie_access_status
_scsih_pcie_check_device

mpt3sas_get_pdev_by_handle

mpt3sas_config_get_pcie_device_pg0
mpt3sas_config_get_pcie_device_pg2

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h   |  10 +
 drivers/scsi/mpt3sas/mpt3sas_config.c | 100 +++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c  | 473 +-
 3 files changed, 575 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index c4be9ad..09ad823 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1458,6 +1458,10 @@ struct _sas_device *mpt3sas_get_sdev_by_addr(
 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
 struct _sas_device *__mpt3sas_get_sdev_by_addr(
 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
+struct _sas_device *mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
+   u16 handle);
+struct _pcie_device *mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
+   u16 handle);
 
 void mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc);
 struct _raid_device *
@@ -1496,6 +1500,12 @@ int mpt3sas_config_get_sas_device_pg0(struct 
MPT3SAS_ADAPTER *ioc,
 int mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+   u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
+   u32 form, u32 handle);
 int mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
u16 sz);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c 
b/drivers/scsi/mpt3sas/mpt3sas_config.c
index dd62701..1c747cf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -150,6 +150,24 @@ _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, 
u16 smid,
case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
desc = "driver_mapping";
break;
+   case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:
+   desc = "sas_port";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:
+   desc = "ext_manufacturing";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:
+   desc = "pcie_io_unit";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:
+   desc = "pcie_switch";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:
+   desc = "pcie_device";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:
+   desc = "pcie_link";
+   break;
}
break;
}
@@ -1053,6 +1071,88 @@ mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER 
*ioc,
 }
 
 /**
+ * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
+ * @ioc: per adapter object
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * @form: GET_NEXT_HANDLE or HANDLE
+ * @handle: device handle
+ * Context: sleep.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+   u32 form, u32 handle)
+{
+   Mpi2ConfigRequest_t mpi_request;
+   int r;
+
+   memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+   mpi_request.Function = MPI2_FUNCTION_CONFIG;
+   mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+   mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
+   mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
+   mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
+   mpi_request.Header.PageNumber = 0;
+   ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
+   r = _config_request(ioc, &mpi_request, mpi_reply,
+   MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+   if (r)
+   goto out;
+
+   mpi_request.PageAddress = cpu_to_le32(form | handle);
+   mpi_request.Action = MPI2_CONF

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

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

Sets nvme device queue depth, name and displays device capabilities

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  2 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 47 
 2 files changed, 48 insertions(+), 1 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(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_wwid(ioc,
+   sas_device_priv_data->sas_target->sas_address);
+   if (!pcie_device) {
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   dfailprintk(ioc, pr_warn(MPT3SAS_FMT
+   "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
+   __LINE__, __func__));
+   return 1;
+   }
+
+   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(&ioc->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(&ioc->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 11/14] mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c | 88 +-
 1 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, &ioc->sas_device_list, list) {
-   if (sas_device->handle != handle)
-   continue;
-   r = sas_device;
-   goto out;
-   }
-
- out:
-   return r;
-}
-
-/**
  * _ctl_display_some_debug - debug routine
  * @ioc: per adapter object
  * @smid: system request message index
@@ -229,10 +203,9 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
Mpi2SCSIIOReply_t *scsi_reply =
(Mpi2SCSIIOReply_t *)mpi_reply;
struct _sas_device *sas_device = NULL;
-   unsigned long flags;
+   struct _pcie_device *pcie_device = NULL;
 
-   spin_lock_irqsave(&ioc->sas_device_lock, flags);
-   sas_device = _ctl_sas_device_find_by_handle(ioc,
+   sas_device = mpt3sas_get_sdev_by_handle(ioc,
le16_to_cpu(scsi_reply->DevHandle));
if (sas_device) {
pr_warn(MPT3SAS_FMT "\tsas_address(0x%016llx), 
phy(%d)\n",
@@ -242,8 +215,25 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
"\tenclosure_logical_id(0x%016llx), slot(%d)\n",
ioc->name, (unsigned long long)
sas_device->enclosure_logical_id, sas_device->slot);
+   sas_device_put(sas_device);
+   }
+   if (!sas_device) {
+   pcie_device = mpt3sas_get_pdev_by_handle(ioc,
+   le16_to_cpu(scsi_reply->DevHandle));
+   if (pcie_device) {
+   pr_warn(MPT3SAS_FMT
+   "\tWWID(0x%016llx), port(%d)\n", ioc->name,
+   (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   pr_warn(MPT3SAS_FMT
+   "\tenclosure_logical_id(0x%016llx), 
slot(%d)\n",
+   ioc->name, (unsigned long long)
+   pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   pcie_device_put(pcie_device);
+   }
}
-   spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)
pr_info(MPT3SAS_FMT
"\tscsi_state(0x%02x), scsi_status"
@@ -1353,6 +1343,42 @@ _ctl_btdh_search_sas_device(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _ctl_btdh_search_pcie_device - searching for pcie device
+ * @ioc: per adapter object
+ * @btdh: btdh ioctl payload
+ */
+static int
+_ctl_btdh_search_pcie_device(struct MPT3SAS_ADAPTER *ioc,
+   struct mpt3_ioctl_btdh_mapping *btdh)
+{
+   struct _pcie_device *pcie_device;
+   unsigned long flags;
+   int rc = 0;
+
+   if (list_empty(&ioc->pcie_device_list))
+   return rc;
+
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
+   if (btdh->bus == 0x && btdh->id == 0x &&
+  btdh->handle == pcie_device->handle) {
+   btdh->bus = pcie_device->channel;
+   btdh->id = pcie_device->id;
+   rc = 1;
+   goto out;
+   } 

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

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

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 
Signed-off-by: Suganath Prabu S 
---
 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_device *
+static struct _pcie_device *
 __mpt3sas_get_pdev_by_wwid(struct MPT3SAS_ADAPTER *ioc, u64 wwid)
 {
struct _pcie_device *pcie_

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

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

Updated mpt3sas driver version to 15.101.00.00

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++--
 1 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 "
 #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 12/14] mpt3sas: Fix nvme drives checking for tlr.

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

Check for NVMe drives before enabling or checking tlr.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 22 --
 1 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(&scmd->device->sdev_gendev)
-   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
+   if (((!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev))
+   && !scsih_is_nvme(&scmd->device->sdev_gendev))
+   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
 
smid = mpt3sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
@@ -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(&scmd->device->sdev_gendev) &&
-   sas_is_tlr_enabled(scmd->device) &&
+   !scsih_is_nvme(&scmd->device->sdev_gendev))
+   && sas_is_tlr_enabled(scmd->device) &&
response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
sas_disable_tlr(scmd->device);
sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
-- 
2.5.5



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

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 83 ++--
 1 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(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_from_target(ioc, priv_target);
+   if (pcie_device) {
+   starget_printk(KERN_INFO, starget,
+   "handle(0x%04x), wwid(0x%016llx), port(%d)\n",
+   pcie_device->handle,
+   (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   starget_printk(KERN_INFO, starget,
+   "enclosure logical id(0x%016llx), 
slot(%d)\n",
+   (unsigned long long)
+   pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0] != '\0')
+   starget_printk(KERN_INFO, starget,
+   "enclosure level(0x%04x), connector 
name( %s)\n",
+   pcie_device->enclosure_level,
+   pcie_device->connector_name);
+   pcie_device_put(pcie_device);
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
} else {
spin_lock_irqsave(&ioc->sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
@@ -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(&ioc->sas_device_lock, flags);
-
+   if (!sas_device) {
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device && pcie_device->starget &&
+   pcie_device->starget->hostdata) {
+   sas_target_priv_data = pcie_device->starget->hostdata;
+   sas_target_priv_data->deleted = 1;
+   sas_address = pcie_device->wwid;
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   }
if (sas_target_priv_data) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"setting delete flag: handle(0x%04x), 
sas_addr(0x%016llx)\n",
ioc->name, handle,
(unsigned long long)sas_address));
-   if (sas_device->enclosure_handle != 0)
-   dewtprintk(ioc, pr_info(MPT3SAS_FMT
-"setting delete flag:enclosure logical id(0x%016llx),"
-" slot(%d)\n", ioc->name, (unsigned long long)
- sas_device->enclosure_logical_id,
- sas_device->slot));
-   if (sas_device->connector_name[0] != '\0')
-

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

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 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, &data);
pr_warn(MPT3SAS_FMT
-   "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], 
count(%d)\n",
-   ioc->name, data.skey,
-   data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
+ "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
+ ioc->name, data.skey,
+ data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
}
-
if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
response_info = le32_to_cpu(mpi_reply->ResponseInfo);
response_bytes = (u8 *)&response_info;
@@ -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(&ioc->pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
+   if ((pcie_device->wwid == pcie_device_pg0->WWID) &&
+   (pcie_device->slot == pcie_device_pg0->Slot)) {
+   pcie_device->responding = 1;
+   starget = pcie_device->starget;
+   if (starget && starget->hostdata) {
+

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

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

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

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

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

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  30 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 471 ++-
 2 files changed, 495 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 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 
handle)
_scsih_internal_device_block(sdev, sas_device_priv_data);
}
 
-   sas_device_put(sas_device);
+   if 

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

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 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(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device) {
+   if (!list_empty(&pcie_device->list)) {
+   list_del_init(&pcie_device->list);
+   was_on_pcie_device_list = 1;
+   pcie_device_put(pcie_device);
+   }
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   if (was_on_pcie_device_list) {
+   _scsih_pcie_device_remove_from_sml(ioc, pcie_device);
+   pcie_device_put(pcie_device);
+   }
+}
+
 /**
  * _scsih_pcie_device_add - add pcie_device object
  * @ioc: per adapter object
@@ -6533,6 +6570,83 @@ _scsih_check_pcie_access_status(struct MPT3SAS_ADAPTER 
*ioc, u64 wwid,
(unsigned long long)wwid, handle);
return rc;
 }
+
+/**
+ * _scsih_pcie_device_remove_from_sml -  removing pcie device
+ * from SML and free up associated memory
+ * @ioc: per adapter object
+ * @pcie_device: the pcie_device object
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
+   struct _pcie_device *pcie_device)
+{
+   struct MPT3SAS_TARGET *sas_target_priv_data;
+
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: handle(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
+   pcie_device->handle, (unsigned long long)
+   pcie_device->wwid));
+   if (pcie_device->enclosure_handle != 0)
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: enclosure logical id(0x%016llx), slot(%d)\n",
+   ioc->name, __func__,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot));
+   if (pcie_device->connector_name[0] != '\0')
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: enclosure level(0x%04x), connector name( %s)\n",
+   ioc->name, __func__,
+   pcie_device->enclosure_level,
+   pcie_device->connector_name));
+
+   if (pcie_device->starget && pcie_device->starget->hostdata) {
+   sas_target_priv_data = pcie_device->starget->hostdata;
+   sas_target_priv_data->deleted = 1;
+   _scsih_ublock_io_device(ioc, pcie_device->wwid);
+   sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE;
+   }
+
+   pr_info(MPT3SAS_FMT
+   "removing handle(0x%04x), wwid (0x%016llx)\n",
+   ioc->name, pcie_device->handle,
+   (unsigned long long) pcie_device->wwid);
+   if (pcie_device->enclosure_handle != 0)
+   pr_info(MPT3SAS_FMT
+   "removing : enclosure logical id(0x%016llx), slot(%d)\n",
+   ioc->name,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0] != '\0')
+   pr_info(MPT3SAS_FMT
+   "removing: enclosure level(0x%04x), conne

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

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

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 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 *prp_entry, *prp1_entry, *prp2_entry, *prp_entry_phys;
+   u64 *prp_page, *prp_page_phys;
+   u32

[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 

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

2) Added support for determing NVMe as boot device.

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

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

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

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

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 099ab4c..c522057 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -159,6 +159,7 @@
 #define MPT_TARGET_FLAGS_VOLUME0x02
 #define MPT_TARGET_FLAGS_DELETED   0x04
 #define MPT_TARGET_FASTPATH_IO 0x08
+#define MPT_TARGET_FLAGS_PCIE_DEVICE   0x10
 
 #define SAS2_PCI_DEVICE_B0_REVISION(0x01)
 #define SAS3_PCI_DEVICE_C0_REVISION(0x02)
@@ -357,7 +358,8 @@ struct Mpi2ManufacturingPage11_t {
  * @flags: MPT_TARGET_FLAGS_XXX flags
  * @deleted: target flaged for deletion
  * @tm_busy: target is busy with TM request.
- * @sdev: The sas_device associated with this target
+ * @sas_dev: The sas_device associated with this target
+ * @pcie_dev: The pcie device associated with this target
  */
 struct MPT3SAS_TARGET {
struct scsi_target *starget;
@@ -368,7 +370,8 @@ struct MPT3SAS_TARGET {
u32 flags;
u8  deleted;
u8  tm_busy;
-   struct _sas_device *sdev;
+   struct _sas_device *sas_dev;
+   struct _pcie_device *pcie_dev;
 };
 
 
@@ -508,6 +511,89 @@ static inline void sas_device_put(struct _sas_device *s)
kref_put(&s->refcount, sas_device_free);
 }
 
+/*
+ * struct _pcie_device - attached PCIe device information
+ * @list: pcie device list
+ * @starget: starget object
+ * @wwid: device WWID
+ * @handle: device handle
+ * @device_info: bitfield provides detailed info about the device
+ * @id: target id
+ * @channel: target channel
+ * @slot: slot number
+ * @port_num: port number
+ * @responding: used in _scsih_pcie_device_mark_responding
+ * @fast_path: fast path feature enable bit
+ * @nvme_mdts: MaximumDataTransferSize from PCIe Device Page 2 for
+ * NVMe device only
+ * @enclosure_handle: enclosure handle
+ * @enclosure_logical_id: enclosure logical identifier
+ * @enclosure_level: The level of device's enclosure from the controller
+ * @connector_name: ASCII value of the Connector's name
+ * @serial_number: pointer of serial number string allocated runtime
+ * @refcount: reference count for deletion
+ */
+struct _pcie_device {
+   struct list_head list;
+   struct scsi_target *starget;
+   u64 wwid;
+   u16 handle;
+   u32 device_info;
+   int id;
+   int channel;
+   u16 slot;
+   u8  port_num;
+   u8  responding;
+   u8  fast_path;
+   u32 nvme_mdts;
+   u16 enclosure_handle;
+   u64 enclosure_logical_id;
+   u8  enclosure_level;
+   u8  connector_name[4];
+   u8  *serial_number;
+   struct kref refcount;
+};
+/**
+ * pcie_device_get - Increment the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will increment the
+ * reference count of the pcie device for which this function called.
+ *
+ */
+static inline void pcie_device_get(struct _pcie_device *p)
+{
+   kref_get(&p->refcount);
+}
+
+/**
+ * pcie_device_free - Release the pcie device object
+ * @r - kref object
+ *
+ * Free's the pcie device object. It will be called when reference count
+ * reaches to zero.
+ */
+static inline void pcie_device_free(struct kref *r)
+{
+   kfree(container_of(r, struct _pcie_device, refcount));
+}
+
+/**
+ * pcie_device_put - Decrement the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will decrement the
+ * reference count of the pcie device for which this function called.
+ *
+ * When refernce count reaches to Zero, this will call pcie_device_free to the
+ * pcie_device object.
+ */
+static inline void pcie_device_put(struct _pcie_device *p)
+{
+   kref_put(&p->refcount, pcie_device_free);
+}
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -556,12 +642,13 @@ struct _raid_device {
 
 /**
  * struct _boot_device - boot 

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

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

Update MPI Files for NVMe support

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2.h  |  43 ++-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 564 +--
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |  11 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  | 282 +-
 drivers/scsi/mpt3sas/mpi/mpi2_pci.h  | 112 +++
 drivers/scsi/mpt3sas/mpi/mpi2_tool.h |  14 +-
 6 files changed, 992 insertions(+), 34 deletions(-)
 create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h
index a9a659f..bc59058 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2.h
@@ -8,7 +8,7 @@
  * scatter/gather formats.
  * Creation Date:  June 21, 2006
  *
- * mpi2.h Version:  02.00.42
+ * mpi2.h Version:  02.00.48
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *   prefix are for use only on MPI v2.5 products, and must not be used
@@ -103,6 +103,16 @@
  * 08-25-15  02.00.40  Bumped MPI2_HEADER_VERSION_UNIT.
  * 12-15-15  02.00.41  Bumped MPI_HEADER_VERSION_UNIT
  * 01-01-16  02.00.42  Bumped MPI_HEADER_VERSION_UNIT
+ * 04-05-16  02.00.43  Modified  MPI26_DIAG_BOOT_DEVICE_SELECT defines
+ * to be unique within first 32 characters.
+ * Removed AHCI support.
+ * Removed SOP support.
+ * Bumped MPI2_HEADER_VERSION_UNIT.
+ * 04-10-16  02.00.44  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 07-06-16  02.00.45  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 09-02-16  02.00.46  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 11-23-16  02.00.47  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 02-03-17  02.00.48  Bumped MPI2_HEADER_VERSION_UNIT.
  * --
  */
 
@@ -142,7 +152,7 @@
 #define MPI2_VERSION_02_06 (0x0206)
 
 /*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT(0x2A)
+#define MPI2_HEADER_VERSION_UNIT(0x30)
 #define MPI2_HEADER_VERSION_DEV (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK   (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT  (8)
@@ -249,6 +259,12 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS {
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -367,6 +383,7 @@ typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR {
 #define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE(0x08)
 #define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR(0x0A)
 #define MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO  (0x0C)
+#define MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED  (0x10)
 
 #define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01)
 
@@ -425,6 +442,13 @@ typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
Mpi25FastPathSCSIIORequestDescriptor_t,
*pMpi25FastPathSCSIIORequestDescriptor_t;
 
+/*PCIe Encapsulated Request Descriptor */
+typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
+   MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+   *PTR_MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+   Mpi26PCIeEncapsulatedRequestDescriptor_t,
+   *pMpi26PCIeEncapsulatedRequestDescriptor_t;
+
 /*union of Request Descriptors */
 typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
MPI2_DEFAULT_REQUEST_DESCRIPTOR Default;
@@ -433,6 +457,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget;
MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator;
MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR FastPathSCSIIO;
+   MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR PCIeEncapsulated;
U64 Words;
 } MPI2_REQUEST_DESCRIPTOR_UNION,
*PTR_MPI2_REQUEST_DESCRIPTOR_UNION,
@@ -450,6 +475,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
  *  Atomic SCSI Target Request Descriptor
  *  Atomic RAID Accelerator Request Descriptor
  *  Atomic Fast Path SCSI IO Request Descriptor
+ *  Atomic PCIe Encapsulated Request Descriptor
  */
 
 /*Atomic Request Descriptor */
@@ -487,6 +513,7 @@ typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR {
 #define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER   (0x03)
 #define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS(0x05)
 #define MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS  (0x06)
+#define

[PATCH 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



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

2017-08-20 Thread Suganath Prabu Subramani
Hi James,
we have fixed the sparse warnings associated with this patch set and
posting V4 of mpt3sas patches soon. We are also working on sparse
error/warnings that existed before this patch set and we ll be posting
it separately.

Thanks,
Suganath Prabu S

On Wed, Aug 9, 2017 at 2:48 AM, J Freyensee
 wrote:
>
>
> Looks like your header has a white space error:
>
> Applying: mpt3sas: Update MPI Header
> .git/rebase-apply/patch:1452: new blank line at EOF.
> +
>
> Also, FYI, this project has a lot of sparse errors that look like existed
> before your patchset.  As your patchset touches a few of the files that
> have sparse warnings (such as mpt3sas_base.c, mpt3sas_scsih.c, etc), maybe
> you'll want to investigate fixing these things?
>
>
> [mainline-linux]$ make C=1
>   CHK include/config/kernel.release
>   CHK include/generated/uapi/linux/version.h
>   CHK include/generated/utsrelease.h
>   CHK include/generated/bounds.h
>   CHK include/generated/timeconst.h
>   CHK include/generated/asm-offsets.h
>   CALLscripts/checksyscalls.sh
>   CHK scripts/mod/devicetable-offsets.h
>   CHK include/generated/compile.h
>   AR  drivers/scsi/mpt3sas/built-in.o
>   CHECK   drivers/scsi/mpt3sas/mpt3sas_base.c
> drivers/scsi/mpt3sas/mpt3sas_base.c:861:42: warning: incorrect type in
> assignment (different base types)
> drivers/scsi/mpt3sas/mpt3sas_base.c:861:42:expected unsigned short
> [unsigned] [usertype] Event
> drivers/scsi/mpt3sas/mpt3sas_base.c:861:42:got restricted __le16
> [usertype] Event
> drivers/scsi/mpt3sas/mpt3sas_base.c:862:49: warning: incorrect type in
> assignment (different base types)
> drivers/scsi/mpt3sas/mpt3sas_base.c:862:49:expected unsigned int
> [unsigned] [usertype] EventContext
> drivers/scsi/mpt3sas/mpt3sas_base.c:862:49:got restricted __le32
> [usertype] EventContext
> drivers/scsi/mpt3sas/mpt3sas_base.c:1080:64: warning: incorrect type in
> argument 2 (different address spaces)
> drivers/scsi/mpt3sas/mpt3sas_base.c:1080:64:expected void volatile
> [noderef] *addr
> drivers/scsi/mpt3sas/mpt3sas_base.c:1080:64:got unsigned long long
> [usertype] *
> drivers/scsi/mpt3sas/mpt3sas_base.c:1129:52: warning: incorrect type in
> argument 2 (different address spaces)
> drivers/scsi/mpt3sas/mpt3sas_base.c:1129:52:expected void volatile
> [noderef] *addr
> drivers/scsi/mpt3sas/mpt3sas_base.c:1129:52:got unsigned long long
> [usertype] *
> drivers/scsi/mpt3sas/mpt3sas_base.c:1519:36: warning: incorrect type in
> assignment (different base types)
> drivers/scsi/mpt3sas/mpt3sas_base.c:1519:36:expected unsigned long long
> [unsigned] [long] [long long] [usertype] 
> drivers/scsi/mpt3sas/mpt3sas_base.c:1519:36:got restricted __le64
> [usertype] 
> drivers/scsi/mpt3sas/mpt3sas_base.c:1532:37: warning: incorrect type in
> assignment (different base types)
> drivers/scsi/mpt3sas/mpt3sas_base.c:1532:37:expected unsigned long long
> [unsigned] [long] [long long] [usertype] 
> drivers/scsi/mpt3sas/mpt3sas_base.c:1532:37:got restricted __le64
> [usertype] 
> drivers/scsi/mpt3sas/mpt3sas_base.c:1552:45: warning: incorrect type in
> assignment (different base types)
> drivers/scsi/mpt3sas/mpt3sas_base.c:1552:45:expected unsigned long long
> [unsigned] [long] [long long] [usertype] 
> drivers/scsi/mpt3sas/mpt3sas_base.c:1552:45:got restricted __le64
> [usertype] 
> drivers/scsi/mpt3sas/mpt3sas_base.c:1565:45: warning: incorrect type in
> assignment (different base types)
> drivers/scsi/mpt3sas/mpt3sas_base.c:1565:45:expected unsigned long long
> [unsigned] [long] [long long] [usertype] 
> drivers/scsi/mpt3sas/mpt3sas_base.c:1565:45:got restricted __le64
> [usertype] 
> drivers/scsi/mpt3sas/mpt3sas_base.c:1575:36: warning: incorrect type in
> assignment (different base types)
> drivers/scsi/mpt3sas/mpt3sas_base.c:1575:36:expected unsigned long long
> [unsigned] [long] [long long] [usertype] 
> drivers/scsi/mpt3sas/mpt3sas_base.c:1575:36:got restricted __le64
> [usertype] 
> drivers/scsi/mpt3sas/mpt3sas_base.c:1594:5: warning: symbol 'base_mod64'
> was not declared. Should it be static?
> drivers/scsi/mpt3sas/mpt3sas_base.c:1717:36: warning: incorrect type in
> assignment (different base types)
> drivers/scsi/mpt3sas/mpt3sas_base.c:1717:36:expected unsigned long long
> [unsigned] [long] [long long] [usertype] 
> drivers/scsi/mpt3sas/mpt3sas_base.c:1717:36:got restricted __le64
> [usertype] 
> drivers/scsi/mpt3sas/mpt3sas_base.c:1722:28: warning: incorrect type in
> assignment (different base types)
> drivers/scsi/mpt3sas/mpt3sas_base.c:1722:28:expected unsigned long long
> [unsigned] [long] [long long] [use

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

2017-08-09 Thread Suganath Prabu Subramani
Hi Martin,
This code was added to detect holes, when we started testing with 4.9
kernel. when we disabled "use_blk_mq" and no merges, we are hitting
issues with holes. Anyhow In latest upstream, it got fixed with this
commit 5a8d75a1b8c99bdc926ba69b7b7dbe4fae81a5af

So we are removing the code related to hole detection .

Thanks,
Suganath Prabu S



On Tue, Aug 8, 2017 at 9:42 PM, Martin K. Petersen
 wrote:
>
> Suganath,
>
>> + /*
>> +  ** Below code detects gaps/holes in IO data buffers.
>> +  ** What does holes/gaps mean?
>> +  ** Any SGE except first one in a SGL starts at non NVME page size
>> +  ** aligned address OR Any SGE except last one in a SGL ends at
>> +  ** non NVME page size boundary.
>> +  **
>> +  ** Driver has already informed block layer by setting boundary rules
>> +  ** for bio merging done at NVME page size boundary calling kernel API
>> +  ** blk_queue_virt_boundary inside slave_config.
>> +  ** Still there is possibility of IO coming with holes to driver 
>> because
>> +  ** of IO merging done by IO scheduler.
>
> All this SGL to PRP code needs to go.
>
> If you are seeing anything that's not a valid PRP after setting the
> queue virt boundary then there's a block layer bug that needs to be
> debugged and fixed. Regardless of whether you are using an I/O scheduler
> or not.
>
> --
> Martin K. Petersen  Oracle Linux Engineering


[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 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c |   56 -
 drivers/scsi/mpt3sas/mpt3sas_base.h |1 +
 drivers/scsi/mpt3sas/mpt3sas_ctl.c  |   69 ---
 3 files changed, 119 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 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;
+
+   descriptor.Default.RequestFlags =
+   MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
+   descriptor.Default.MSIxIndex =  _base_get_msix_index(ioc);
+   descriptor.Default.SMID = cpu_to_le16(smid);
+   descriptor.Default.LMID = 0;
+   descriptor.Default.DescriptorTypeDependent = 0;
+   _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
+   &ioc->scsi_lookup_lock);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * @ioc: per adapter object
  * @smid: system request message index
@@ -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;
+
+   descriptor.RequestFlags = MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
+   descriptor.MSIxIndex = _base_get_msix_index(ioc);
+   descriptor.SMID = cpu_to_le16(smid);
+
+   writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost);
+}
+
+/**
  * _base_put_smid_default - Default, primarily used for config pages
  * use Atomic Request Descriptor
  * @ioc: per adapter object
@@ -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;
ioc->put_smid_hi_priority = &_base_pu

[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 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 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(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device) {
+   if (!list_empty(&pcie_device->list)) {
+   list_del_init(&pcie_device->list);
+   was_on_pcie_device_list = 1;
+   pcie_device_put(pcie_device);
+   }
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   if (was_on_pcie_device_list) {
+   _scsih_pcie_device_remove_from_sml(ioc, pcie_device);
+   pcie_device_put(pcie_device);
+   }
+}
+
 /**
  * _scsih_pcie_device_add - add pcie_device object
  * @ioc: per adapter object
@@ -6533,6 +6570,83 @@ _scsih_check_pcie_access_status(struct MPT3SAS_ADAPTER 
*ioc, u64 wwid,
(unsigned long long)wwid, handle);
return rc;
 }
+
+/**
+ * _scsih_pcie_device_remove_from_sml -  removing pcie device
+ * from SML and free up associated memory
+ * @ioc: per adapter object
+ * @pcie_device: the pcie_device object
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
+   struct _pcie_device *pcie_device)
+{
+   struct MPT3SAS_TARGET *sas_target_priv_data;
+
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: handle(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
+   pcie_device->handle, (unsigned long long)
+   pcie_device->wwid));
+   if (pcie_device->enclosure_handle != 0)
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: enclosure logical id(0x%016llx), slot(%d)\n",
+   ioc->name, __func__,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot));
+   if (pcie_device->connector_name[0] != '\0')
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: enclosure level(0x%04x), connector name( %s)\n",
+   ioc->name, __func__,
+   pcie_device->enclosure_level,
+   pcie_device->connector_name));
+
+   if (pcie_device->starget && pcie_device->starget->hostdata) {
+   sas_target_priv_data = pcie_device->starget->hostdata;
+   sas_target_priv_data->deleted = 1;
+   _scsih_ublock_io_device(ioc, pcie_device->wwid);
+   sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE;
+   }
+
+   pr_info(MPT3SAS_FMT
+   "removing handle(0x%04x), wwid (0x%016llx)\n",
+   ioc->name, pcie_device->handle,
+   (unsigned long long) pcie_device->wwid);
+   if (pcie_device->enclosure_handle != 0)
+   pr_info(MPT3SAS_FMT
+   "removing : enclosure logical id(0x%016llx), slot(%d)\n",
+   ioc->name,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0] != '\0')
+   pr_info(MPT3SAS_FMT
+   "removing: enclosure level(0x%04x), connector name( %s

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   22 --
 1 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index ff77850..49e1943 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2014,6 +2014,14 @@ scsih_is_raid(struct device *dev)
return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
 }
 
+static int
+scsih_is_nvme(struct device *dev)
+{
+   struct scsi_device *sdev = to_scsi_device(dev);
+
+   return (sdev->channel == PCIE_CHANNEL) ? 1 : 0;
+}
+
 /**
  * scsih_get_resync - get raid volume resync percent complete
  * @dev the device struct object
@@ -4818,8 +4826,9 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd 
*scmd)
/* Make sure Device is not raid volume.
 * We do not expose raid functionality to upper layer for warpdrive.
 */
-   if (!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev)
-   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
+   if (((!ioc->is_warpdrive && !scsih_is_raid(&scmd->device->sdev_gendev))
+   && !scsih_is_nvme(&scmd->device->sdev_gendev))
+   && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
 
smid = mpt3sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
@@ -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(&scmd->device->sdev_gendev) &&
-   sas_is_tlr_enabled(scmd->device) &&
+   !scsih_is_nvme(&scmd->device->sdev_gendev))
+   && sas_is_tlr_enabled(scmd->device) &&
response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
sas_disable_tlr(scmd->device);
sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n");
-- 
1.7.1



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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   83 -
 1 files changed, 70 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 2242edb..ff77850 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2900,6 +2900,7 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd)
struct scsi_target *starget = scmd->device->sdev_target;
struct MPT3SAS_TARGET *priv_target = starget->hostdata;
struct _sas_device *sas_device = NULL;
+   struct _pcie_device *pcie_device = NULL;
unsigned long flags;
char *device_str = NULL;
 
@@ -2916,6 +2917,31 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd)
"%s handle(0x%04x), %s wwid(0x%016llx)\n",
device_str, priv_target->handle,
device_str, (unsigned long long)priv_target->sas_address);
+
+   } else if (priv_target->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_from_target(ioc, priv_target);
+   if (pcie_device) {
+   starget_printk(KERN_INFO, starget,
+   "handle(0x%04x), wwid(0x%016llx), port(%d)\n",
+   pcie_device->handle,
+   (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   starget_printk(KERN_INFO, starget,
+   "enclosure logical id(0x%016llx), 
slot(%d)\n",
+   (unsigned long long)
+   pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0] != '\0')
+   starget_printk(KERN_INFO, starget,
+   "enclosure level(0x%04x), connector 
name( %s)\n",
+   pcie_device->enclosure_level,
+   pcie_device->connector_name);
+   pcie_device_put(pcie_device);
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+
} else {
spin_lock_irqsave(&ioc->sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_from_target(ioc, priv_target);
@@ -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(&ioc->sas_device_lock, flags);
-
+   if (!sas_device) {
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device && pcie_device->starget &&
+   pcie_device->starget->hostdata) {
+   sas_target_priv_data = pcie_device->starget->hostdata;
+   sas_target_priv_data->deleted = 1;
+   sas_address = pcie_device->wwid;
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   }
if (sas_target_priv_data) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"setting delete flag: handle(0x%04x), 
sas_addr(0x%016llx)\n",
ioc->name, handle,
(unsigned long long)sas_address));
-   if (sas_device->enclosure_handle != 0)
-   dewtprintk(ioc, pr_info(MPT3SAS_FMT
-"setting delete flag:enclosure logical id(0x%016llx),"
-" slot(%d)\n", ioc->name, (unsigned long long)
- sas_device->enclosure_logical_id,
- sas_device->slot));
-   if (sas_device->connector_name[0] != '\0')
-

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

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

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 51d2668..2cd1550 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -74,9 +74,9 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies "
 #define MPT3SAS_DESCRIPTION"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION "15.100.00.00"
+#define MPT3SAS_DRIVER_VERSION "15.101.00.00"
 #define MPT3SAS_MAJOR_VERSION  15
-#define MPT3SAS_MINOR_VERSION  100
+#define MPT3SAS_MINOR_VERSION  101
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
 
-- 
1.7.1



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

2017-08-08 Thread Suganath Prabu S
* The controller firmware sends separate events for NVMe devices and
PCIe switches similar to existing SAS events.

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

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

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |   30 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  471 +-
 2 files changed, 495 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 27fe074..f8ed98c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -663,6 +663,26 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
desc = "Active cable exception";
break;
+   case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
+   desc = "PCIE Device Status Change";
+   break;
+   case MPI2_EVENT_PCIE_ENUMERATION:
+   {
+   Mpi26EventDataPCIeEnumeration_t *event_data =
+   (Mpi26EventDataPCIeEnumeration_t *)mpi_reply->EventData;
+   pr_info(MPT3SAS_FMT "PCIE Enumeration: (%s)", ioc->name,
+  (event_data->ReasonCode ==
+   MPI26_EVENT_PCIE_ENUM_RC_STARTED) ?
+   "start" : "stop");
+   if (event_data->EnumerationStatus)
+   pr_info("enumeration_status(0x%08x)",
+  le32_to_cpu(event_data->EnumerationStatus));
+   pr_info("\n");
+   return;
+   }
+   case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
+   desc = "PCIE Topology Change List";
+   break;
}
 
if (!desc)
@@ -6232,8 +6252,16 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
_base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS);
_base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
_base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD);
-   if (ioc->hba_mpi_version_belonged == MPI26_VERSION)
+   if (ioc->hba_mpi_version_belonged == MPI26_VERSION) {
_base_unmask_events(ioc, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
+   if (ioc->is_gen35_ioc) {
+   _base_unmask_events(ioc,
+   MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE);
+   _base_unmask_events(ioc, MPI2_EVENT_PCIE_ENUMERATION);
+   _base_unmask_events(ioc,
+   MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST);
+   }
+   }
 
r = _base_make_ioc_operational(ioc);
if (r)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 710ea63..344f946 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -75,6 +75,8 @@ static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle,
 static int _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static void _scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
struct _pcie_device *pcie_device);
+static void
+_scsih_pcie_check_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
 /* global parameters */
@@ -3458,8 +3460,6 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
struct _sas_device *sas_device;
 
sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
-   if (!sas_device)
-   return;
 
shost_for_each_device(sdev, ioc->shost) {
sas_device_priv_data = sdev->hostdata;
@@ -3469,7 +3469,7 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
continue;
if (sas_device_priv_data->block)
continue;
-   if (sas_device->pend_sas_rphy_add)
+   if (sas_device && sas_device->pend_sas_rphy_add)
continue;
if (sas_device_priv_data->ignore_delay_remove) {
sdev_printk(KERN_INFO, sdev,
@@ -3480,7 +3480,8 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
_scsih_internal_device_block(sdev, sas_device_priv_data);
}
 
-   sas_device_put(sas_device);
+   if (sas_de

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

2017-08-08 Thread Suganath Prabu S
* Added debug prints for pcie devices in ioctl debug path. Which
will be helpful for debugging.
* Added PCIe device support for ioctl BTDHMAPPING ioctl.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c |   88 +++
 1 files changed, 58 insertions(+), 30 deletions(-)

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

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

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

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 35b472f..2242edb 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4876,6 +4876,7 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct 
scsi_cmnd *scmd,
char *desc_scsi_state = ioc->tmp_string;
u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
struct _sas_device *sas_device = NULL;
+   struct _pcie_device *pcie_device = NULL;
struct scsi_target *starget = scmd->device->sdev_target;
struct MPT3SAS_TARGET *priv_target = starget->hostdata;
char *device_str = NULL;
@@ -5008,6 +5009,28 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct 
scsi_cmnd *scmd,
if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
device_str, (unsigned long long)priv_target->sas_address);
+   } else if (priv_target->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   pcie_device = mpt3sas_get_pdev_from_target(ioc, priv_target);
+   if (pcie_device) {
+   pr_info(MPT3SAS_FMT "\twwid(0x%016llx), port(%d)\n",
+   ioc->name,
+   (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   pr_info(MPT3SAS_FMT
+   "\tenclosure logical id(0x%016llx), "
+   "slot(%d)\n", ioc->name,
+   (unsigned long long)
+   pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0])
+   pr_info(MPT3SAS_FMT
+   "\tenclosure level(0x%04x),"
+   "connector name( %s)\n",
+   ioc->name, pcie_device->enclosure_level,
+   pcie_device->connector_name);
+   pcie_device_put(pcie_device);
+   }
} else {
sas_device = mpt3sas_get_sdev_from_target(ioc, priv_target);
if (sas_device) {
@@ -5054,11 +5077,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd,
struct sense_info data;
_scsih_normalize_sense(scmd->sense_buffer, &data);
pr_warn(MPT3SAS_FMT
-   "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], 
count(%d)\n",
-   ioc->name, data.skey,
-   data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
+ "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
+ ioc->name, data.skey,
+ data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
}
-
if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
response_info = le32_to_cpu(mpi_reply->ResponseInfo);
response_bytes = (u8 *)&response_info;
@@ -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(&ioc->pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
+   if ((pcie_device->wwid == pcie_device_pg0->WWID) &&
+   (pcie_device->slot == pcie_device_pg0->Slot)) {
+   pcie_device->responding = 1;
+   starget = pcie_device->starget;
+   if (starget && starget->hostdata) {
+   sas_target_priv_data = starget->hostdata;
+   

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

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

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 09ad823..51d2668 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -115,7 +115,7 @@
 
 #define MPT3SAS_RAID_MAX_SECTORS   8192
 #define MPT3SAS_HOST_PAGE_SIZE_4K  12
-
+#define MPT3SAS_NVME_QUEUE_DEPTH   128
 #define MPT_NAME_LENGTH32  /* generic length of 
strings */
 #define MPT_STRING_LENGTH  64
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 344f946..35b472f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2290,6 +2290,7 @@ scsih_slave_configure(struct scsi_device *sdev)
struct MPT3SAS_DEVICE *sas_device_priv_data;
struct MPT3SAS_TARGET *sas_target_priv_data;
struct _sas_device *sas_device;
+   struct _pcie_device *pcie_device;
struct _raid_device *raid_device;
unsigned long flags;
int qdepth;
@@ -2420,6 +2421,52 @@ scsih_slave_configure(struct scsi_device *sdev)
}
}
 
+   /* PCIe handling */
+   if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_wwid(ioc,
+   sas_device_priv_data->sas_target->sas_address);
+   if (!pcie_device) {
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   dfailprintk(ioc, pr_warn(MPT3SAS_FMT
+   "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
+   __LINE__, __func__));
+   return 1;
+   }
+
+   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(&ioc->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(&ioc->sas_device_lock, flags);
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
   sas_device_priv_data->sas_target->sas_address);
-- 
1.7.1



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

2017-08-08 Thread Suganath Prabu S
Below Functions are added in various paths to support NVMe
drive addition.

_scsih_pcie_add_device
_scsih_pcie_device_add
_scsih_pcie_device_init_add
_scsih_check_pcie_access_status
_scsih_pcie_check_device

mpt3sas_get_pdev_by_handle

mpt3sas_config_get_pcie_device_pg0
mpt3sas_config_get_pcie_device_pg2

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h   |   10 +
 drivers/scsi/mpt3sas/mpt3sas_config.c |  100 +++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c  |  473 -
 3 files changed, 575 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index c4be9ad..09ad823 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1458,6 +1458,10 @@ struct _sas_device *mpt3sas_get_sdev_by_addr(
 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
 struct _sas_device *__mpt3sas_get_sdev_by_addr(
 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
+struct _sas_device *mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
+   u16 handle);
+struct _pcie_device *mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
+   u16 handle);
 
 void mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc);
 struct _raid_device *
@@ -1496,6 +1500,12 @@ int mpt3sas_config_get_sas_device_pg0(struct 
MPT3SAS_ADAPTER *ioc,
 int mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+   u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
+   u32 form, u32 handle);
 int mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
u16 sz);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c 
b/drivers/scsi/mpt3sas/mpt3sas_config.c
index dd62701..1c747cf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -150,6 +150,24 @@ _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, 
u16 smid,
case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
desc = "driver_mapping";
break;
+   case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:
+   desc = "sas_port";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:
+   desc = "ext_manufacturing";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:
+   desc = "pcie_io_unit";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:
+   desc = "pcie_switch";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:
+   desc = "pcie_device";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:
+   desc = "pcie_link";
+   break;
}
break;
}
@@ -1053,6 +1071,88 @@ mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER 
*ioc,
 }
 
 /**
+ * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
+ * @ioc: per adapter object
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * @form: GET_NEXT_HANDLE or HANDLE
+ * @handle: device handle
+ * Context: sleep.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+   u32 form, u32 handle)
+{
+   Mpi2ConfigRequest_t mpi_request;
+   int r;
+
+   memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+   mpi_request.Function = MPI2_FUNCTION_CONFIG;
+   mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+   mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
+   mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
+   mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
+   mpi_request.Header.PageNumber = 0;
+   ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
+   r = _config_request(ioc, &mpi_request, mpi_reply,
+   MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+   if (r)
+   goto out;
+
+   mpi_request.PageAddress = cpu_to_le32(form | handle);
+   mpi_request.Action = MPI2_CONF

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2.h  |   43 +++-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  564 --
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |   11 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |  282 +-
 drivers/scsi/mpt3sas/mpi/mpi2_pci.h  |  112 +++
 drivers/scsi/mpt3sas/mpi/mpi2_tool.h |   14 +-
 6 files changed, 992 insertions(+), 34 deletions(-)
 create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h
index a9a659f..bc59058 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2.h
@@ -8,7 +8,7 @@
  * scatter/gather formats.
  * Creation Date:  June 21, 2006
  *
- * mpi2.h Version:  02.00.42
+ * mpi2.h Version:  02.00.48
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *   prefix are for use only on MPI v2.5 products, and must not be used
@@ -103,6 +103,16 @@
  * 08-25-15  02.00.40  Bumped MPI2_HEADER_VERSION_UNIT.
  * 12-15-15  02.00.41  Bumped MPI_HEADER_VERSION_UNIT
  * 01-01-16  02.00.42  Bumped MPI_HEADER_VERSION_UNIT
+ * 04-05-16  02.00.43  Modified  MPI26_DIAG_BOOT_DEVICE_SELECT defines
+ * to be unique within first 32 characters.
+ * Removed AHCI support.
+ * Removed SOP support.
+ * Bumped MPI2_HEADER_VERSION_UNIT.
+ * 04-10-16  02.00.44  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 07-06-16  02.00.45  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 09-02-16  02.00.46  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 11-23-16  02.00.47  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 02-03-17  02.00.48  Bumped MPI2_HEADER_VERSION_UNIT.
  * --
  */
 
@@ -142,7 +152,7 @@
 #define MPI2_VERSION_02_06 (0x0206)
 
 /*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT(0x2A)
+#define MPI2_HEADER_VERSION_UNIT(0x30)
 #define MPI2_HEADER_VERSION_DEV (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK   (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT  (8)
@@ -249,6 +259,12 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS {
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -367,6 +383,7 @@ typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR {
 #define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE(0x08)
 #define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR(0x0A)
 #define MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO  (0x0C)
+#define MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED  (0x10)
 
 #define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01)
 
@@ -425,6 +442,13 @@ typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
Mpi25FastPathSCSIIORequestDescriptor_t,
*pMpi25FastPathSCSIIORequestDescriptor_t;
 
+/*PCIe Encapsulated Request Descriptor */
+typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
+   MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+   *PTR_MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+   Mpi26PCIeEncapsulatedRequestDescriptor_t,
+   *pMpi26PCIeEncapsulatedRequestDescriptor_t;
+
 /*union of Request Descriptors */
 typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
MPI2_DEFAULT_REQUEST_DESCRIPTOR Default;
@@ -433,6 +457,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget;
MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator;
MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR FastPathSCSIIO;
+   MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR PCIeEncapsulated;
U64 Words;
 } MPI2_REQUEST_DESCRIPTOR_UNION,
*PTR_MPI2_REQUEST_DESCRIPTOR_UNION,
@@ -450,6 +475,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
  *  Atomic SCSI Target Request Descriptor
  *  Atomic RAID Accelerator Request Descriptor
  *  Atomic Fast Path SCSI IO Request Descriptor
+ *  Atomic PCIe Encapsulated Request Descriptor
  */
 
 /*Atomic Request Descriptor */
@@ -487,6 +513,7 @@ typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR {
 #define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER   (0x03)
 #define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS(0x05)
 #define MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS  (0x06)
+#define

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

2017-08-08 Thread Suganath Prabu S
1) Added support for probing pcie device and adding NVMe drives to
SML and driver's internal list pcie_device_list.

2) Added support for determing NVMe as boot device.

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

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

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

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

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 099ab4c..c522057 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -159,6 +159,7 @@
 #define MPT_TARGET_FLAGS_VOLUME0x02
 #define MPT_TARGET_FLAGS_DELETED   0x04
 #define MPT_TARGET_FASTPATH_IO 0x08
+#define MPT_TARGET_FLAGS_PCIE_DEVICE   0x10
 
 #define SAS2_PCI_DEVICE_B0_REVISION(0x01)
 #define SAS3_PCI_DEVICE_C0_REVISION(0x02)
@@ -357,7 +358,8 @@ struct Mpi2ManufacturingPage11_t {
  * @flags: MPT_TARGET_FLAGS_XXX flags
  * @deleted: target flaged for deletion
  * @tm_busy: target is busy with TM request.
- * @sdev: The sas_device associated with this target
+ * @sas_dev: The sas_device associated with this target
+ * @pcie_dev: The pcie device associated with this target
  */
 struct MPT3SAS_TARGET {
struct scsi_target *starget;
@@ -368,7 +370,8 @@ struct MPT3SAS_TARGET {
u32 flags;
u8  deleted;
u8  tm_busy;
-   struct _sas_device *sdev;
+   struct _sas_device *sas_dev;
+   struct _pcie_device *pcie_dev;
 };
 
 
@@ -508,6 +511,89 @@ static inline void sas_device_put(struct _sas_device *s)
kref_put(&s->refcount, sas_device_free);
 }
 
+/*
+ * struct _pcie_device - attached PCIe device information
+ * @list: pcie device list
+ * @starget: starget object
+ * @wwid: device WWID
+ * @handle: device handle
+ * @device_info: bitfield provides detailed info about the device
+ * @id: target id
+ * @channel: target channel
+ * @slot: slot number
+ * @port_num: port number
+ * @responding: used in _scsih_pcie_device_mark_responding
+ * @fast_path: fast path feature enable bit
+ * @nvme_mdts: MaximumDataTransferSize from PCIe Device Page 2 for
+ * NVMe device only
+ * @enclosure_handle: enclosure handle
+ * @enclosure_logical_id: enclosure logical identifier
+ * @enclosure_level: The level of device's enclosure from the controller
+ * @connector_name: ASCII value of the Connector's name
+ * @serial_number: pointer of serial number string allocated runtime
+ * @refcount: reference count for deletion
+ */
+struct _pcie_device {
+   struct list_head list;
+   struct scsi_target *starget;
+   u64 wwid;
+   u16 handle;
+   u32 device_info;
+   int id;
+   int channel;
+   u16 slot;
+   u8  port_num;
+   u8  responding;
+   u8  fast_path;
+   u32 nvme_mdts;
+   u16 enclosure_handle;
+   u64 enclosure_logical_id;
+   u8  enclosure_level;
+   u8  connector_name[4];
+   u8  *serial_number;
+   struct kref refcount;
+};
+/**
+ * pcie_device_get - Increment the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will increment the
+ * reference count of the pcie device for which this function called.
+ *
+ */
+static inline void pcie_device_get(struct _pcie_device *p)
+{
+   kref_get(&p->refcount);
+}
+
+/**
+ * pcie_device_free - Release the pcie device object
+ * @r - kref object
+ *
+ * Free's the pcie device object. It will be called when reference count
+ * reaches to zero.
+ */
+static inline void pcie_device_free(struct kref *r)
+{
+   kfree(container_of(r, struct _pcie_device, refcount));
+}
+
+/**
+ * pcie_device_put - Decrement the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will decrement the
+ * reference count of the pcie device for which this function called.
+ *
+ * When refernce count reaches to Zero, this will call pcie_device_free to the
+ * pcie_device object.
+ */
+static inline void pcie_device_put(struct _pcie_device *p)
+{
+   kref_put(&p->refcount, pcie_device_free);
+}
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -556,12 +642,13 @@ struct _raid_device {
 
 /**
  * struct _boot_device - boot device 

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

2017-08-08 Thread Suganath Prabu S
* Added support for translating the SGLs associated with incoming
commands either to IEE SGL or NVMe PRPs for NVMe devices.

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  668 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |   44 ++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   14 +-
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 5 files changed, 713 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 18039bb..d48f176 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include /* To get host page size per arch */
 #include 
 
 
@@ -1347,6 +1348,547 @@ _base_build_sg(struct MPT3SAS_ADAPTER *ioc, void *psge,
 /* IEEE format sgls */
 
 /**
+ * _base_build_nvme_prp - This function is called for NVMe end devices to build
+ * a native SGL (NVMe PRP). The native SGL is built starting in the first PRP
+ * entry of the NVMe message (PRP1).  If the data buffer is small enough to be
+ * described entirely using PRP1, then PRP2 is not used.  If needed, PRP2 is
+ * used to describe a larger data buffer.  If the data buffer is too large to
+ * describe using the two PRP entriess inside the NVMe message, then PRP1
+ * describes the first data memory segment, and PRP2 contains a pointer to a 
PRP
+ * list located elsewhere in memory to describe the remaining data memory
+ * segments.  The PRP list will be contiguous.
+
+ * The native SGL for NVMe devices is a Physical Region Page (PRP).  A PRP
+ * consists of a list of PRP entries to describe a number of noncontigous
+ * physical memory segments as a single memory buffer, just as a SGL does.  
Note
+ * however, that this function is only used by the IOCTL call, so the memory
+ * given will be guaranteed to be contiguous.  There is no need to translate
+ * non-contiguous SGL into a PRP in this case.  All PRPs will describe
+ * contiguous space that is one page size each.
+ *
+ * Each NVMe message contains two PRP entries.  The first (PRP1) either 
contains
+ * a PRP list pointer or a PRP element, depending upon the command.  PRP2
+ * contains the second PRP element if the memory being described fits within 2
+ * PRP entries, or a PRP list pointer if the PRP spans more than two entries.
+ *
+ * A PRP list pointer contains the address of a PRP list, structured as a 
linear
+ * array of PRP entries.  Each PRP entry in this list describes a segment of
+ * physical memory.
+ *
+ * Each 64-bit PRP entry comprises an address and an offset field.  The address
+ * always points at the beginning of a 4KB physical memory page, and the offset
+ * describes where within that 4KB page the memory segment begins.  Only the
+ * first element in a PRP list may contain a non-zero offest, implying that all
+ * memory segments following the first begin at the start of a 4KB page.
+ *
+ * Each PRP element normally describes 4KB of physical memory, with exceptions
+ * for the first and last elements in the list.  If the memory being described
+ * by the list begins at a non-zero offset within the first 4KB page, then the
+ * first PRP element will contain a non-zero offset indicating where the region
+ * begins within the 4KB page.  The last memory segment may end before the end
+ * of the 4KB segment, depending upon the overall size of the memory being
+ * described by the PRP list.
+ *
+ * Since PRP entries lack any indication of size, the overall data buffer 
length
+ * is used to determine where the end of the data memory buffer is located, and
+ * how many PRP entries are required to describe it.
+ *
+ * @ioc: per adapter object
+ * @smid: system request message index for getting asscociated SGL
+ * @nvme_encap_request: the NVMe request msg frame pointer
+ * @data_out_dma: physical address for WRITES
+ * @data_out_sz: data xfer size for WRITES
+ * @data_in_dma: physical address for READS
+ * @data_in_sz: data xfer size for READS
+ *
+ * Returns nothing.
+ */
+static void
+_base_build_nvme_prp(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+   Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request,
+   dma_addr_t data_out_dma, size_t data_out_sz, dma_addr_t data_in_dma,
+   size_t data_in_sz)
+{
+   int prp_size = NVME_PRP_SIZE;
+   u64 *prp_entry, *prp1_entry, *prp2_entry, *prp_entry_phys;
+   u64 *prp_page, *prp_page_phys;
+   u32

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

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

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

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

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

 drivers/scsi/mpt3sas/mpi/mpi2.h  |   43 +-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  564 +-
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |   11 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |  282 +-
 drivers/scsi/mpt3sas/mpi/mpi2_pci.h  |  112 ++
 drivers/scsi/mpt3sas/mpi/mpi2_tool.h |   14 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  754 -
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  171 +++-
 drivers/scsi/mpt3sas/mpt3sas_config.c|  100 ++
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  158 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 1881 --
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 12 files changed, 3929 insertions(+), 163 deletions(-)
 create mode 100644 drivers/scsi/mpt3sas/mpi/mpi2_pci.h

Thanks,
Suganath Prabu S


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

2017-07-24 Thread Suganath Prabu Subramani
Is there any update on these patches ?

Thanks,
Suganath Prabu S

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


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

2017-07-19 Thread Suganath Prabu Subramani
Hi Elliott,
We are maintaining NVMe drives as scsi device in mpt3sas driver.
There are lot of firmware/hardware level dependencies and after lot of
discussions we arrived this value (128).
So, we prefer not to provide module parameter to change this at least for now.

Thanks,
Suganath Prabu S

On Tue, Jul 11, 2017 at 10:53 PM, Elliott, Robert (Persistent Memory)
 wrote:
>> +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
>> @@ -115,7 +115,7 @@
>>
>>  #define MPT3SAS_RAID_MAX_SECTORS 8192
>>  #define MPT3SAS_HOST_PAGE_SIZE_4K12
>> -
>> +#define MPT3SAS_NVME_QUEUE_DEPTH 128
> ...
>> + /*TODO-right Queue Depth?*/
>> + qdepth = MPT3SAS_NVME_QUEUE_DEPTH;
>> + ds = "NVMe";
>
> The native NVMe driver is getting a modparam to set that value (rather than
> using a #define of 1024) in this patch:
> http://lists.infradead.org/pipermail/linux-nvme/2017-July/011734.html
>
> Perhaps this driver should do the same.
>
> ---
> Robert Elliott, HPE Persistent Memory
>
>


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

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

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

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h
index a9a659f..bc59058 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2.h
@@ -8,7 +8,7 @@
  * scatter/gather formats.
  * Creation Date:  June 21, 2006
  *
- * mpi2.h Version:  02.00.42
+ * mpi2.h Version:  02.00.48
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *   prefix are for use only on MPI v2.5 products, and must not be used
@@ -103,6 +103,16 @@
  * 08-25-15  02.00.40  Bumped MPI2_HEADER_VERSION_UNIT.
  * 12-15-15  02.00.41  Bumped MPI_HEADER_VERSION_UNIT
  * 01-01-16  02.00.42  Bumped MPI_HEADER_VERSION_UNIT
+ * 04-05-16  02.00.43  Modified  MPI26_DIAG_BOOT_DEVICE_SELECT defines
+ * to be unique within first 32 characters.
+ * Removed AHCI support.
+ * Removed SOP support.
+ * Bumped MPI2_HEADER_VERSION_UNIT.
+ * 04-10-16  02.00.44  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 07-06-16  02.00.45  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 09-02-16  02.00.46  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 11-23-16  02.00.47  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 02-03-17  02.00.48  Bumped MPI2_HEADER_VERSION_UNIT.
  * --
  */
 
@@ -142,7 +152,7 @@
 #define MPI2_VERSION_02_06 (0x0206)
 
 /*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT(0x2A)
+#define MPI2_HEADER_VERSION_UNIT(0x30)
 #define MPI2_HEADER_VERSION_DEV (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK   (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT  (8)
@@ -249,6 +259,12 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS {
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -367,6 +383,7 @@ typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR {
 #define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE(0x08)
 #define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR(0x0A)
 #define MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO  (0x0C)
+#define MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED  (0x10)
 
 #define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01)
 
@@ -425,6 +442,13 @@ typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
Mpi25FastPathSCSIIORequestDescriptor_t,
*pMpi25FastPathSCSIIORequestDescriptor_t;
 
+/*PCIe Encapsulated Request Descriptor */
+typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
+   MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+   *PTR_MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+   Mpi26PCIeEncapsulatedRequestDescriptor_t,
+   *pMpi26PCIeEncapsulatedRequestDescriptor_t;
+
 /*union of Request Descriptors */
 typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
MPI2_DEFAULT_REQUEST_DESCRIPTOR Default;
@@ -433,6 +457,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget;
MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator;
MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR FastPathSCSIIO;
+   MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR PCIeEncapsulated;
U64 Words;
 } MPI2_REQUEST_DESCRIPTOR_UNION,
*PTR_MPI2_REQUEST_DESCRIPTOR_UNION,
@@ -450,6 +475,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
  *  Atomic SCSI Target Request Descriptor
  *  Atomic RAID Accelerator Request Descriptor
  *  Atomic Fast Path SCSI IO Request Descriptor
+ *  Atomic PCIe Encapsulated Request Descriptor
  */
 
 /*Atomic Request Descriptor */
@@ -487,6 +513,7 @@ typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR {
 #define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER   (0x03)
 #define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS(0x05)
 #define MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS  (0x06)
+#define

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

2017-07-14 Thread Suganath Prabu Subramani
Hi Keith,
We have made change and submitted V2 of patch set.

Thanks,
Suganath Prabu S

On Wed, Jul 12, 2017 at 5:34 AM, Keith Busch  wrote:
> On Tue, Jul 11, 2017 at 01:55:02AM -0700, Suganath Prabu S wrote:
>> +/**
>> + * _base_check_pcie_native_sgl - This function is called for PCIe end 
>> devices to
>> + * determine if the driver needs to build a native SGL.  If so, that native
>> + * SGL is built in the special contiguous buffers allocated especially for
>> + * PCIe SGL creation.  If the driver will not build a native SGL, return
>> + * TRUE and a normal IEEE SGL will be built.  Currently this routine
>> + * supports NVMe.
>> + * @ioc: per adapter object
>> + * @mpi_request: mf request pointer
>> + * @smid: system request message index
>> + * @scmd: scsi command
>> + * @pcie_device: points to the PCIe device's info
>> + *
>> + * Returns 0 if native SGL was built, 1 if no SGL was built
>> + */
>> +static int
>> +_base_check_pcie_native_sgl(struct MPT3SAS_ADAPTER *ioc,
>> + Mpi25SCSIIORequest_t *mpi_request, u16 smid, struct scsi_cmnd *scmd,
>> + struct _pcie_device *pcie_device)
>> +{
>
> 
>
>> + /* Return 0, indicating we built a native SGL. */
>> + return 1;
>> +}
>
> This function doesn't return 0 ever. Not sure why it's here.
>
> Curious about your device, though, if a nvme native SGL can *not* be
> built, does the HBA firmware then buffer it in its local memory before
> sending/receiving to/from the host?
>
> And if a native SGL can be built, does the NVMe target DMA directly
> to/from host memory, giving a performance boost?


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

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

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index d813a11..6d730bc 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -73,6 +73,8 @@ static void _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc,
 static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle,
u8 retry_count, u8 is_pd);
 static int _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
+static void _scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
+   struct _pcie_device *pcie_device);
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
 /* global parameters */
@@ -1092,6 +1094,41 @@ _scsih_pcie_device_remove(struct MPT3SAS_ADAPTER *ioc,
pcie_device_put(pcie_device);
}
 }
+
+
+/**
+ * _scsih_pcie_device_remove_by_handle - removing pcie device object by handle
+ * @ioc: per adapter object
+ * @handle: device handle
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_remove_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+   struct _pcie_device *pcie_device;
+   unsigned long flags;
+   int was_on_pcie_device_list = 0;
+
+   if (ioc->shost_recovery)
+   return;
+
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device) {
+   if (!list_empty(&pcie_device->list)) {
+   list_del_init(&pcie_device->list);
+   was_on_pcie_device_list = 1;
+   pcie_device_put(pcie_device);
+   }
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   if (was_on_pcie_device_list) {
+   _scsih_pcie_device_remove_from_sml(ioc, pcie_device);
+   pcie_device_put(pcie_device);
+   }
+}
+
 /**
  * _scsih_pcie_device_add - add pcie_device object
  * @ioc: per adapter object
@@ -6533,6 +6570,83 @@ _scsih_check_pcie_access_status(struct MPT3SAS_ADAPTER 
*ioc, u64 wwid,
(unsigned long long)wwid, handle);
return rc;
 }
+
+/**
+ * _scsih_pcie_device_remove_from_sml -  removing pcie device
+ * from SML and free up associated memory
+ * @ioc: per adapter object
+ * @pcie_device: the pcie_device object
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
+   struct _pcie_device *pcie_device)
+{
+   struct MPT3SAS_TARGET *sas_target_priv_data;
+
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: handle(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
+   pcie_device->handle, (unsigned long long)
+   pcie_device->wwid));
+   if (pcie_device->enclosure_handle != 0)
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: enclosure logical id(0x%016llx), slot(%d)\n",
+   ioc->name, __func__,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot));
+   if (pcie_device->connector_name[0] != '\0')
+   dewtprintk(ioc, pr_info(MPT3SAS_FMT
+   "%s: enter: enclosure level(0x%04x), connector name( %s)\n",
+   ioc->name, __func__,
+   pcie_device->enclosure_level,
+   pcie_device->connector_name));
+
+   if (pcie_device->starget && pcie_device->starget->hostdata) {
+   sas_target_priv_data = pcie_device->starget->hostdata;
+   sas_target_priv_data->deleted = 1;
+   _scsih_ublock_io_device(ioc, pcie_device->wwid);
+   sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE;
+   }
+
+   pr_info(MPT3SAS_FMT
+   "removing handle(0x%04x), wwid (0x%016llx)\n",
+   ioc->name, pcie_device->handle,
+   (unsigned long long) pcie_device->wwid);
+   if (pcie_device->enclosure_handle != 0)
+   pr_info(MPT3SAS_FMT
+   "removing : enclosure logical id(0x%016llx), slot(%d)\n",
+   ioc->name,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0] != '\0')
+   pr_info(MPT3SAS_FMT
+   "removing: enclosure level(0x%04x), connector name( %s)\n",
+  

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

2017-07-14 Thread Suganath Prabu S
Below Functions are added in various paths to support NVMe
drive addition.

_scsih_pcie_add_device
_scsih_pcie_device_add
_scsih_pcie_device_init_add
_scsih_check_pcie_access_status
_scsih_pcie_check_device

mpt3sas_get_pdev_by_handle

mpt3sas_config_get_pcie_device_pg0
mpt3sas_config_get_pcie_device_pg2

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index bd32b0c..0a8187e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1458,6 +1458,10 @@ struct _sas_device *mpt3sas_get_sdev_by_addr(
 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
 struct _sas_device *__mpt3sas_get_sdev_by_addr(
 struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
+struct _sas_device *mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
+   u16 handle);
+struct _pcie_device *mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc,
+   u16 handle);
 
 void mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc);
 struct _raid_device *
@@ -1496,6 +1500,12 @@ int mpt3sas_config_get_sas_device_pg0(struct 
MPT3SAS_ADAPTER *ioc,
 int mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+   u32 form, u32 handle);
+int mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
+   u32 form, u32 handle);
 int mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
u16 sz);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c 
b/drivers/scsi/mpt3sas/mpt3sas_config.c
index dd62701..1c747cf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -150,6 +150,24 @@ _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, 
u16 smid,
case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
desc = "driver_mapping";
break;
+   case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:
+   desc = "sas_port";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:
+   desc = "ext_manufacturing";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:
+   desc = "pcie_io_unit";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:
+   desc = "pcie_switch";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:
+   desc = "pcie_device";
+   break;
+   case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:
+   desc = "pcie_link";
+   break;
}
break;
}
@@ -1053,6 +1071,88 @@ mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER 
*ioc,
 }
 
 /**
+ * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
+ * @ioc: per adapter object
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * @form: GET_NEXT_HANDLE or HANDLE
+ * @handle: device handle
+ * Context: sleep.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+   Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
+   u32 form, u32 handle)
+{
+   Mpi2ConfigRequest_t mpi_request;
+   int r;
+
+   memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+   mpi_request.Function = MPI2_FUNCTION_CONFIG;
+   mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+   mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
+   mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
+   mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
+   mpi_request.Header.PageNumber = 0;
+   ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
+   r = _config_request(ioc, &mpi_request, mpi_reply,
+   MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+   if (r)
+   goto out;
+
+   mpi_request.PageAddress = cpu_to_le32(form | handle);
+   mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
+   r = _config_request(i

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

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

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

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



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

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

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

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

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

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

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

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



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

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

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

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



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

2017-07-14 Thread Suganath Prabu S
* Added debug prints for pcie devices in ioctl debug path. Which
will be helpful for debugging.
* Added PCIe device support for ioctl BTDHMAPPING ioctl.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c |   88 +++
 1 files changed, 58 insertions(+), 30 deletions(-)

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

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

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

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index c5a131f..e3e803c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4869,6 +4869,7 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct 
scsi_cmnd *scmd,
char *desc_scsi_state = ioc->tmp_string;
u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
struct _sas_device *sas_device = NULL;
+   struct _pcie_device *pcie_device = NULL;
struct scsi_target *starget = scmd->device->sdev_target;
struct MPT3SAS_TARGET *priv_target = starget->hostdata;
char *device_str = NULL;
@@ -5001,6 +5002,28 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct 
scsi_cmnd *scmd,
if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
device_str, (unsigned long long)priv_target->sas_address);
+   } else if (priv_target->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   pcie_device = mpt3sas_get_pdev_from_target(ioc, priv_target);
+   if (pcie_device) {
+   pr_info(MPT3SAS_FMT "\twwid(0x%016llx), port(%d)\n",
+   ioc->name,
+   (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   pr_info(MPT3SAS_FMT
+   "\tenclosure logical id(0x%016llx), "
+   "slot(%d)\n", ioc->name,
+   (unsigned long long)
+   pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0])
+   pr_info(MPT3SAS_FMT
+   "\tenclosure level(0x%04x),"
+   "connector name( %s)\n",
+   ioc->name, pcie_device->enclosure_level,
+   pcie_device->connector_name);
+   pcie_device_put(pcie_device);
+   }
} else {
sas_device = mpt3sas_get_sdev_from_target(ioc, priv_target);
if (sas_device) {
@@ -5047,11 +5070,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd,
struct sense_info data;
_scsih_normalize_sense(scmd->sense_buffer, &data);
pr_warn(MPT3SAS_FMT
-   "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], 
count(%d)\n",
-   ioc->name, data.skey,
-   data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
+ "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
+ ioc->name, data.skey,
+ data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
}
-
if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
response_info = le32_to_cpu(mpi_reply->ResponseInfo);
response_bytes = (u8 *)&response_info;
@@ -8512,6 +8534,130 @@ _scsih_search_responding_sas_devices(struct 
MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * _scsih_mark_responding_pcie_device - mark a pcie_device as responding
+ * @ioc: per adapter object
+ * @pcie_device_pg0: PCIe Device page 0
+ *
+ * After host reset, find out whether devices are still responding.
+ * Used in _scsih_remove_unresponding_devices.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_mark_responding_pcie_device(struct MPT3SAS_ADAPTER *ioc,
+   Mpi26PCIeDevicePage0_t *pcie_device_pg0)
+{
+   struct MPT3SAS_TARGET *sas_target_priv_data = NULL;
+   struct scsi_target *starget;
+   struct _pcie_device *pcie_device;
+   unsigned long flags;
+
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
+   if ((pcie_device->wwid == pcie_device_pg0->WWID) &&
+   (pcie_device->slot == pcie_device_pg0->Slot)) {
+   pcie_device->responding = 1;
+   starget = pcie_device->starget;
+   if (starget && starget->hostdata) {
+   sas_target_priv_data = starget->hostdata;
+   

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

2017-07-14 Thread Suganath Prabu S
* The controller firmware sends separate events for NVMe devices and
PCIe switches similar to existing SAS events.

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

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

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

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |   30 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  471 +-
 2 files changed, 495 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index c3a6c7a..794b2c0 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -663,6 +663,26 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
desc = "Active cable exception";
break;
+   case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
+   desc = "PCIE Device Status Change";
+   break;
+   case MPI2_EVENT_PCIE_ENUMERATION:
+   {
+   Mpi26EventDataPCIeEnumeration_t *event_data =
+   (Mpi26EventDataPCIeEnumeration_t *)mpi_reply->EventData;
+   pr_info(MPT3SAS_FMT "PCIE Enumeration: (%s)", ioc->name,
+  (event_data->ReasonCode ==
+   MPI26_EVENT_PCIE_ENUM_RC_STARTED) ?
+   "start" : "stop");
+   if (event_data->EnumerationStatus)
+   pr_info("enumeration_status(0x%08x)",
+  le32_to_cpu(event_data->EnumerationStatus));
+   pr_info("\n");
+   return;
+   }
+   case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
+   desc = "PCIE Topology Change List";
+   break;
}
 
if (!desc)
@@ -6188,8 +6208,16 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
_base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS);
_base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
_base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD);
-   if (ioc->hba_mpi_version_belonged == MPI26_VERSION)
+   if (ioc->hba_mpi_version_belonged == MPI26_VERSION) {
_base_unmask_events(ioc, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
+   if (ioc->is_gen35_ioc) {
+   _base_unmask_events(ioc,
+   MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE);
+   _base_unmask_events(ioc, MPI2_EVENT_PCIE_ENUMERATION);
+   _base_unmask_events(ioc,
+   MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST);
+   }
+   }
 
r = _base_make_ioc_operational(ioc);
if (r)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 6d730bc..1dd9674 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -75,6 +75,8 @@ static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle,
 static int _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static void _scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
struct _pcie_device *pcie_device);
+static void
+_scsih_pcie_check_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
 /* global parameters */
@@ -3458,8 +3460,6 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
struct _sas_device *sas_device;
 
sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
-   if (!sas_device)
-   return;
 
shost_for_each_device(sdev, ioc->shost) {
sas_device_priv_data = sdev->hostdata;
@@ -3469,7 +3469,7 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
continue;
if (sas_device_priv_data->block)
continue;
-   if (sas_device->pend_sas_rphy_add)
+   if (sas_device && sas_device->pend_sas_rphy_add)
continue;
if (sas_device_priv_data->ignore_delay_remove) {
sdev_printk(KERN_INFO, sdev,
@@ -3480,7 +3480,8 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
_scsih_internal_device_block(sdev, sas_device_priv_data);
}
 
-   sas_device_put(sas_device);
+   if (sas_device)
+   

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

2017-07-14 Thread Suganath Prabu S
* Mpt3sas driver uses the NVMe Encapsulated Request message to
send an NVMe command to an NVMe device attached to the IOC.

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

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

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

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

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

2017-07-14 Thread Suganath Prabu S
* Added support for translating the SGLs associated with incoming
commands either to IEE SGL or NVMe PRPs for NVMe devices.

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

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  624 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |   44 ++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   14 +-
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 5 files changed, 669 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 18039bb..a90c386 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include /* To get host page size per arch */
 #include 
 
 
@@ -1347,6 +1348,503 @@ _base_build_sg(struct MPT3SAS_ADAPTER *ioc, void *psge,
 /* IEEE format sgls */
 
 /**
+ * _base_build_nvme_prp - This function is called for NVMe end devices to build
+ * a native SGL (NVMe PRP). The native SGL is built starting in the first PRP
+ * entry of the NVMe message (PRP1).  If the data buffer is small enough to be
+ * described entirely using PRP1, then PRP2 is not used.  If needed, PRP2 is
+ * used to describe a larger data buffer.  If the data buffer is too large to
+ * describe using the two PRP entriess inside the NVMe message, then PRP1
+ * describes the first data memory segment, and PRP2 contains a pointer to a 
PRP
+ * list located elsewhere in memory to describe the remaining data memory
+ * segments.  The PRP list will be contiguous.
+
+ * The native SGL for NVMe devices is a Physical Region Page (PRP).  A PRP
+ * consists of a list of PRP entries to describe a number of noncontigous
+ * physical memory segments as a single memory buffer, just as a SGL does.  
Note
+ * however, that this function is only used by the IOCTL call, so the memory
+ * given will be guaranteed to be contiguous.  There is no need to translate
+ * non-contiguous SGL into a PRP in this case.  All PRPs will describe
+ * contiguous space that is one page size each.
+ *
+ * Each NVMe message contains two PRP entries.  The first (PRP1) either 
contains
+ * a PRP list pointer or a PRP element, depending upon the command.  PRP2
+ * contains the second PRP element if the memory being described fits within 2
+ * PRP entries, or a PRP list pointer if the PRP spans more than two entries.
+ *
+ * A PRP list pointer contains the address of a PRP list, structured as a 
linear
+ * array of PRP entries.  Each PRP entry in this list describes a segment of
+ * physical memory.
+ *
+ * Each 64-bit PRP entry comprises an address and an offset field.  The address
+ * always points at the beginning of a 4KB physical memory page, and the offset
+ * describes where within that 4KB page the memory segment begins.  Only the
+ * first element in a PRP list may contain a non-zero offest, implying that all
+ * memory segments following the first begin at the start of a 4KB page.
+ *
+ * Each PRP element normally describes 4KB of physical memory, with exceptions
+ * for the first and last elements in the list.  If the memory being described
+ * by the list begins at a non-zero offset within the first 4KB page, then the
+ * first PRP element will contain a non-zero offset indicating where the region
+ * begins within the 4KB page.  The last memory segment may end before the end
+ * of the 4KB segment, depending upon the overall size of the memory being
+ * described by the PRP list.
+ *
+ * Since PRP entries lack any indication of size, the overall data buffer 
length
+ * is used to determine where the end of the data memory buffer is located, and
+ * how many PRP entries are required to describe it.
+ *
+ * @ioc: per adapter object
+ * @smid: system request message index for getting asscociated SGL
+ * @nvme_encap_request: the NVMe request msg frame pointer
+ * @data_out_dma: physical address for WRITES
+ * @data_out_sz: data xfer size for WRITES
+ * @data_in_dma: physical address for READS
+ * @data_in_sz: data xfer size for READS
+ *
+ * Returns nothing.
+ */
+static void
+_base_build_nvme_prp(struct MPT3SAS_ADAPTER *ioc, u16 smid,
+   Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request,
+   dma_addr_t data_out_dma, size_t data_out_sz, dma_addr_t data_in_dma,
+   size_t data_in_sz)
+{
+   int prp_size = NVME_PRP_SIZE;
+   u64 *prp_entry, *prp1_entry, *prp2_entry, *prp_entry_phys;
+   u64 *prp_page, *prp_page_phys;
+   u32

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

2017-07-14 Thread Suganath Prabu S
1) Added support for probing pcie device and adding NVMe drives to
SML and driver's internal list pcie_device_list.

2) Added support for determing NVMe as boot device.

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

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

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

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

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 099ab4c..c522057 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -159,6 +159,7 @@
 #define MPT_TARGET_FLAGS_VOLUME0x02
 #define MPT_TARGET_FLAGS_DELETED   0x04
 #define MPT_TARGET_FASTPATH_IO 0x08
+#define MPT_TARGET_FLAGS_PCIE_DEVICE   0x10
 
 #define SAS2_PCI_DEVICE_B0_REVISION(0x01)
 #define SAS3_PCI_DEVICE_C0_REVISION(0x02)
@@ -357,7 +358,8 @@ struct Mpi2ManufacturingPage11_t {
  * @flags: MPT_TARGET_FLAGS_XXX flags
  * @deleted: target flaged for deletion
  * @tm_busy: target is busy with TM request.
- * @sdev: The sas_device associated with this target
+ * @sas_dev: The sas_device associated with this target
+ * @pcie_dev: The pcie device associated with this target
  */
 struct MPT3SAS_TARGET {
struct scsi_target *starget;
@@ -368,7 +370,8 @@ struct MPT3SAS_TARGET {
u32 flags;
u8  deleted;
u8  tm_busy;
-   struct _sas_device *sdev;
+   struct _sas_device *sas_dev;
+   struct _pcie_device *pcie_dev;
 };
 
 
@@ -508,6 +511,89 @@ static inline void sas_device_put(struct _sas_device *s)
kref_put(&s->refcount, sas_device_free);
 }
 
+/*
+ * struct _pcie_device - attached PCIe device information
+ * @list: pcie device list
+ * @starget: starget object
+ * @wwid: device WWID
+ * @handle: device handle
+ * @device_info: bitfield provides detailed info about the device
+ * @id: target id
+ * @channel: target channel
+ * @slot: slot number
+ * @port_num: port number
+ * @responding: used in _scsih_pcie_device_mark_responding
+ * @fast_path: fast path feature enable bit
+ * @nvme_mdts: MaximumDataTransferSize from PCIe Device Page 2 for
+ * NVMe device only
+ * @enclosure_handle: enclosure handle
+ * @enclosure_logical_id: enclosure logical identifier
+ * @enclosure_level: The level of device's enclosure from the controller
+ * @connector_name: ASCII value of the Connector's name
+ * @serial_number: pointer of serial number string allocated runtime
+ * @refcount: reference count for deletion
+ */
+struct _pcie_device {
+   struct list_head list;
+   struct scsi_target *starget;
+   u64 wwid;
+   u16 handle;
+   u32 device_info;
+   int id;
+   int channel;
+   u16 slot;
+   u8  port_num;
+   u8  responding;
+   u8  fast_path;
+   u32 nvme_mdts;
+   u16 enclosure_handle;
+   u64 enclosure_logical_id;
+   u8  enclosure_level;
+   u8  connector_name[4];
+   u8  *serial_number;
+   struct kref refcount;
+};
+/**
+ * pcie_device_get - Increment the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will increment the
+ * reference count of the pcie device for which this function called.
+ *
+ */
+static inline void pcie_device_get(struct _pcie_device *p)
+{
+   kref_get(&p->refcount);
+}
+
+/**
+ * pcie_device_free - Release the pcie device object
+ * @r - kref object
+ *
+ * Free's the pcie device object. It will be called when reference count
+ * reaches to zero.
+ */
+static inline void pcie_device_free(struct kref *r)
+{
+   kfree(container_of(r, struct _pcie_device, refcount));
+}
+
+/**
+ * pcie_device_put - Decrement the pcie device reference count
+ *
+ * @p: pcie_device object
+ *
+ * When ever this function called it will decrement the
+ * reference count of the pcie device for which this function called.
+ *
+ * When refernce count reaches to Zero, this will call pcie_device_free to the
+ * pcie_device object.
+ */
+static inline void pcie_device_put(struct _pcie_device *p)
+{
+   kref_put(&p->refcount, pcie_device_free);
+}
 /**
  * struct _raid_device - raid volume link list
  * @list: sas device list
@@ -556,12 +642,13 @@ struct _raid_device {
 
 /**
  * struct _boot_device - boot device 

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

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

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

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

Thanks,
Suganath Prabu S


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

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

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 68aa102..7100ee8 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4867,6 +4867,7 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct 
scsi_cmnd *scmd,
char *desc_scsi_state = ioc->tmp_string;
u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
struct _sas_device *sas_device = NULL;
+   struct _pcie_device *pcie_device = NULL;
struct scsi_target *starget = scmd->device->sdev_target;
struct MPT3SAS_TARGET *priv_target = starget->hostdata;
char *device_str = NULL;
@@ -4999,6 +5000,28 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct 
scsi_cmnd *scmd,
if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
device_str, (unsigned long long)priv_target->sas_address);
+   } else if (priv_target->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) {
+   pcie_device = mpt3sas_get_pdev_from_target(ioc, priv_target);
+   if (pcie_device) {
+   pr_info(MPT3SAS_FMT "\twwid(0x%016llx), port(%d)\n",
+   ioc->name,
+   (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   pr_info(MPT3SAS_FMT
+   "\tenclosure logical id(0x%016llx), "
+   "slot(%d)\n", ioc->name,
+   (unsigned long long)
+   pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0])
+   pr_info(MPT3SAS_FMT
+   "\tenclosure level(0x%04x),"
+   "connector name( %s)\n",
+   ioc->name, pcie_device->enclosure_level,
+   pcie_device->connector_name);
+   pcie_device_put(pcie_device);
+   }
} else {
sas_device = mpt3sas_get_sdev_from_target(ioc, priv_target);
if (sas_device) {
@@ -5045,11 +5068,10 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, 
struct scsi_cmnd *scmd,
struct sense_info data;
_scsih_normalize_sense(scmd->sense_buffer, &data);
pr_warn(MPT3SAS_FMT
-   "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], 
count(%d)\n",
-   ioc->name, data.skey,
-   data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
+ "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n",
+ ioc->name, data.skey,
+ data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount));
}
-
if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
response_info = le32_to_cpu(mpi_reply->ResponseInfo);
response_bytes = (u8 *)&response_info;
@@ -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(&ioc->pcie_device_lock, flags);
+   list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {
+   if ((pcie_device->wwid == pcie_d

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

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

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

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



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

2017-07-11 Thread Suganath Prabu S
* Added debug prints for pcie devices in ioctl debug path. Which
will be helpful for debugging.
* Added PCIe device support for ioctl BTDHMAPPING ioctl.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |3 +-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |   88 --
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |2 +-
 3 files changed, 61 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 063977a..ea6e607 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -452,6 +452,7 @@ struct _internal_cmd {
struct completion done;
void*reply;
void*sense;
+   u64 *nvme_error_response;
u16 status;
u16 smid;
 };
@@ -1615,7 +1616,7 @@ void
 mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
direct_io);
 void
 mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
-   struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
+   struct _raid_device *raid_device, Mpi25SCSIIORequest_t *mpi_request,
u16 smid);
 
 /* NCQ Prio Handling Check */
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 35e5c30..269c753 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -79,32 +79,6 @@ enum block_state {
 };
 
 /**
- * _ctl_sas_device_find_by_handle - sas device search
- * @ioc: per adapter object
- * @handle: sas device handle (assigned by firmware)
- * Context: Calling function should acquire ioc->sas_device_lock
- *
- * This searches for sas_device based on sas_address, then return sas_device
- * object.
- */
-static struct _sas_device *
-_ctl_sas_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
-{
-   struct _sas_device *sas_device, *r;
-
-   r = NULL;
-   list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
-   if (sas_device->handle != handle)
-   continue;
-   r = sas_device;
-   goto out;
-   }
-
- out:
-   return r;
-}
-
-/**
  * _ctl_display_some_debug - debug routine
  * @ioc: per adapter object
  * @smid: system request message index
@@ -229,10 +203,9 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
Mpi2SCSIIOReply_t *scsi_reply =
(Mpi2SCSIIOReply_t *)mpi_reply;
struct _sas_device *sas_device = NULL;
-   unsigned long flags;
+   struct _pcie_device *pcie_device = NULL;
 
-   spin_lock_irqsave(&ioc->sas_device_lock, flags);
-   sas_device = _ctl_sas_device_find_by_handle(ioc,
+   sas_device = mpt3sas_get_sdev_by_handle(ioc,
le16_to_cpu(scsi_reply->DevHandle));
if (sas_device) {
pr_warn(MPT3SAS_FMT "\tsas_address(0x%016llx), 
phy(%d)\n",
@@ -242,8 +215,25 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 
smid,
"\tenclosure_logical_id(0x%016llx), slot(%d)\n",
ioc->name, (unsigned long long)
sas_device->enclosure_logical_id, sas_device->slot);
+   sas_device_put(sas_device);
+   }
+   if (!sas_device) {
+   pcie_device = mpt3sas_get_pdev_by_handle(ioc,
+   le16_to_cpu(scsi_reply->DevHandle));
+   if (pcie_device) {
+   pr_warn(MPT3SAS_FMT
+   "\tWWID(0x%016llx), port(%d)\n", ioc->name,
+   (unsigned long long)pcie_device->wwid,
+   pcie_device->port_num);
+   if (pcie_device->enclosure_handle != 0)
+   pr_warn(MPT3SAS_FMT
+   "\tenclosure_logical_id(0x%016llx), 
slot(%d)\n",
+   ioc->name, (unsigned long long)
+   pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   pcie_device_put(pcie_device);
+   }
}
-   spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)
pr_info(MPT3SAS_FMT
"\tscsi_state(0x%02x), scsi_status"
@@ -1375,6 +1365,42 @@ _ctl_btdh_search_sas_device(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _ctl_btdh_search_pcie_device - searching for pcie device
+ * @ioc:

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

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

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index ea6e607..835d6da 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -74,11 +74,11 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies "
 #define MPT3SAS_DESCRIPTION"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION "15.100.00.00"
+#define MPT3SAS_DRIVER_VERSION "15.101.00.00"
 #define MPT3SAS_MAJOR_VERSION  15
-#define MPT3SAS_MINOR_VERSION  100
+#define MPT3SAS_MINOR_VERSION  101
 #define MPT3SAS_BUILD_VERSION  0
-#define MPT3SAS_RELEASE_VERSION00
+#define MPT3SAS_RELEASE_VERSION0
 
 #define MPT2SAS_DRIVER_NAME"mpt2sas"
 #define MPT2SAS_DESCRIPTION"LSI MPT Fusion SAS 2.0 Device Driver"
-- 
1.7.1



[PATCH 12/13] mpt3sas: Update MPI Header

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

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

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h
index a9a659f..bc59058 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2.h
@@ -8,7 +8,7 @@
  * scatter/gather formats.
  * Creation Date:  June 21, 2006
  *
- * mpi2.h Version:  02.00.42
+ * mpi2.h Version:  02.00.48
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *   prefix are for use only on MPI v2.5 products, and must not be used
@@ -103,6 +103,16 @@
  * 08-25-15  02.00.40  Bumped MPI2_HEADER_VERSION_UNIT.
  * 12-15-15  02.00.41  Bumped MPI_HEADER_VERSION_UNIT
  * 01-01-16  02.00.42  Bumped MPI_HEADER_VERSION_UNIT
+ * 04-05-16  02.00.43  Modified  MPI26_DIAG_BOOT_DEVICE_SELECT defines
+ * to be unique within first 32 characters.
+ * Removed AHCI support.
+ * Removed SOP support.
+ * Bumped MPI2_HEADER_VERSION_UNIT.
+ * 04-10-16  02.00.44  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 07-06-16  02.00.45  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 09-02-16  02.00.46  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 11-23-16  02.00.47  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 02-03-17  02.00.48  Bumped MPI2_HEADER_VERSION_UNIT.
  * --
  */
 
@@ -142,7 +152,7 @@
 #define MPI2_VERSION_02_06 (0x0206)
 
 /*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT(0x2A)
+#define MPI2_HEADER_VERSION_UNIT(0x30)
 #define MPI2_HEADER_VERSION_DEV (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK   (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT  (8)
@@ -249,6 +259,12 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS {
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT(0x)
 #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW   (0x0800)
 
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH  (0x)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW   (0x0800)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH  (0x1000)
+#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW   (0x1800)
+
 #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG   (0x0400)
 #define MPI2_DIAG_FORCE_HCB_ON_RESET(0x0200)
 #define MPI2_DIAG_HCB_MODE  (0x0100)
@@ -367,6 +383,7 @@ typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR {
 #define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE(0x08)
 #define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR(0x0A)
 #define MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO  (0x0C)
+#define MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED  (0x10)
 
 #define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01)
 
@@ -425,6 +442,13 @@ typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
Mpi25FastPathSCSIIORequestDescriptor_t,
*pMpi25FastPathSCSIIORequestDescriptor_t;
 
+/*PCIe Encapsulated Request Descriptor */
+typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
+   MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+   *PTR_MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
+   Mpi26PCIeEncapsulatedRequestDescriptor_t,
+   *pMpi26PCIeEncapsulatedRequestDescriptor_t;
+
 /*union of Request Descriptors */
 typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
MPI2_DEFAULT_REQUEST_DESCRIPTOR Default;
@@ -433,6 +457,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget;
MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator;
MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR FastPathSCSIIO;
+   MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR PCIeEncapsulated;
U64 Words;
 } MPI2_REQUEST_DESCRIPTOR_UNION,
*PTR_MPI2_REQUEST_DESCRIPTOR_UNION,
@@ -450,6 +475,7 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION {
  *  Atomic SCSI Target Request Descriptor
  *  Atomic RAID Accelerator Request Descriptor
  *  Atomic Fast Path SCSI IO Request Descriptor
+ *  Atomic PCIe Encapsulated Request Descriptor
  */
 
 /*Atomic Request Descriptor */
@@ -487,6 +513,7 @@ typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR {
 #define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER   (0x03)
 #define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS(0x05)
 #define MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS  (0x06)
+#define

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

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

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index e52bebe..68aa102 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -73,7 +73,8 @@ static void _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc,
 static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle,
u8 retry_count, u8 is_pd);
 static int _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
-
+static void _scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
+   struct _pcie_device *pcie_device);
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
 /* global parameters */
@@ -1048,6 +1049,86 @@ mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc, 
u16 handle)
 
return pcie_device;
 }
+
+/**
+ * _scsih_pcie_device_remove - remove pcie_device from list.
+ * @ioc: per adapter object
+ * @pcie_device: the pcie_device object
+ * Context: This function will acquire ioc->pcie_device_lock.
+ *
+ * If pcie_device is on the list, remove it and decrement its reference count.
+ */
+static void
+_scsih_pcie_device_remove(struct MPT3SAS_ADAPTER *ioc,
+   struct _pcie_device *pcie_device)
+{
+   unsigned long flags;
+   int was_on_pcie_device_list = 0;
+
+   if (!pcie_device)
+   return;
+   pr_info(MPT3SAS_FMT
+   "removing handle(0x%04x), wwid(0x%016llx)\n",
+   ioc->name, pcie_device->handle,
+   (unsigned long long) pcie_device->wwid);
+   if (pcie_device->enclosure_handle != 0)
+   pr_info(MPT3SAS_FMT
+   "removing enclosure logical id(0x%016llx), slot(%d)\n",
+   ioc->name,
+   (unsigned long long)pcie_device->enclosure_logical_id,
+   pcie_device->slot);
+   if (pcie_device->connector_name[0] != '\0')
+   pr_info(MPT3SAS_FMT
+   "removing enclosure level(0x%04x), connector name( 
%s)\n",
+   ioc->name, pcie_device->enclosure_level,
+   pcie_device->connector_name);
+
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   if (!list_empty(&pcie_device->list)) {
+   list_del_init(&pcie_device->list);
+   was_on_pcie_device_list = 1;
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   if (was_on_pcie_device_list) {
+   kfree(pcie_device->serial_number);
+   pcie_device_put(pcie_device);
+   }
+}
+
+
+/**
+ * _scsih_pcie_device_remove_by_handle - removing pcie device object by handle
+ * @ioc: per adapter object
+ * @handle: device handle
+ *
+ * Return nothing.
+ */
+static void
+_scsih_pcie_device_remove_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+   struct _pcie_device *pcie_device;
+   unsigned long flags;
+   int was_on_pcie_device_list = 0;
+
+   if (ioc->shost_recovery)
+   return;
+
+   spin_lock_irqsave(&ioc->pcie_device_lock, flags);
+   pcie_device = __mpt3sas_get_pdev_by_handle(ioc, handle);
+   if (pcie_device) {
+   if (!list_empty(&pcie_device->list)) {
+   list_del_init(&pcie_device->list);
+   was_on_pcie_device_list = 1;
+   pcie_device_put(pcie_device);
+   }
+   }
+   spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
+   if (was_on_pcie_device_list) {
+   _scsih_pcie_device_remove_from_sml(ioc, pcie_device);
+   pcie_device_put(pcie_device);
+   }
+}
+
 /**
  * _scsih_pcie_device_add - add pcie_device object
  * @ioc: per adapter object
@@ -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)
+   

  1   2   >