[PATCH] mpt3sas: Fix for regression caused due to cf6bf9710c patch

2018-06-29 Thread Chaitra P B
 "scsi: mpt3sas: Bug fix for big endian systems"

Above patch with commit id "cf6bf9710cabba1fe94a4349f4eb8db623c77ebc" was
posted to fix sparse warnings. While posting this patch it was assumed that
readl() & writel() APIs internally calls le32_to_cpu() & cpu_to_le32() APIs
respectively. Looks like it is not true for all architecture and hence
this patch is reverting back only those hunks which removed le32_to_cpu()
API call while using readl() API & cpu_to_le32() API call while using
writel() API.

Signed-off-by: Chaitra P B 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index dc41bd3..17b6b0a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -3321,7 +3321,7 @@ void mpt3sas_base_clear_st(struct MPT3SAS_ADAPTER *ioc,
spinlock_t *writeq_lock)
 {
unsigned long flags;
-   __u64 data_out = b;
+   __u64 data_out = cpu_to_le64(b);
 
spin_lock_irqsave(writeq_lock, flags);
writel((u32)(data_out), addr);
@@ -3344,7 +3344,7 @@ void mpt3sas_base_clear_st(struct MPT3SAS_ADAPTER *ioc,
 static inline void
 _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock)
 {
-   writeq(b, addr);
+   writeq(cpu_to_le64(b), addr);
 }
 #else
 static inline void
@@ -5215,7 +5215,7 @@ void mpt3sas_base_clear_st(struct MPT3SAS_ADAPTER *ioc,
 
/* send message 32-bits at a time */
for (i = 0, failed = 0; i < request_bytes/4 && !failed; i++) {
-   writel((u32)(request[i]), &ioc->chip->Doorbell);
+   writel(cpu_to_le32(request[i]), &ioc->chip->Doorbell);
if ((_base_wait_for_doorbell_ack(ioc, 5)))
failed = 1;
}
@@ -5236,7 +5236,7 @@ void mpt3sas_base_clear_st(struct MPT3SAS_ADAPTER *ioc,
}
 
/* read the first two 16-bits, it gives the total length of the reply */
-   reply[0] = (u16)(readl(&ioc->chip->Doorbell)
+   reply[0] = le16_to_cpu(readl(&ioc->chip->Doorbell)
& MPI2_DOORBELL_DATA_MASK);
writel(0, &ioc->chip->HostInterruptStatus);
if ((_base_wait_for_doorbell_int(ioc, 5))) {
@@ -5245,7 +5245,7 @@ void mpt3sas_base_clear_st(struct MPT3SAS_ADAPTER *ioc,
ioc->name, __LINE__);
return -EFAULT;
}
-   reply[1] = (u16)(readl(&ioc->chip->Doorbell)
+   reply[1] = le16_to_cpu(readl(&ioc->chip->Doorbell)
& MPI2_DOORBELL_DATA_MASK);
writel(0, &ioc->chip->HostInterruptStatus);
 
@@ -5259,7 +5259,7 @@ void mpt3sas_base_clear_st(struct MPT3SAS_ADAPTER *ioc,
if (i >=  reply_bytes/2) /* overflow case */
readl(&ioc->chip->Doorbell);
else
-   reply[i] = (u16)(readl(&ioc->chip->Doorbell)
+   reply[i] = le16_to_cpu(readl(&ioc->chip->Doorbell)
& MPI2_DOORBELL_DATA_MASK);
writel(0, &ioc->chip->HostInterruptStatus);
}
-- 
1.8.3.1



[PATCH v1] mpt3sas: Fix calltrace observed while running IO & host reset

2018-06-14 Thread Chaitra P B
 [] scsi_softirq_done+0x132/0x160
 [] blk_done_softirq+0x96/0xc0
 [] __do_softirq+0xf5/0x280
 [] call_softirq+0x1c/0x30
 [] do_softirq+0x65/0xa0
 [] irq_exit+0x105/0x110
 [] smp_apic_timer_interrupt+0x48/0x60
 [] apic_timer_interrupt+0x162/0x170
 
 [] ? scsi_done+0x21/0x60
 [] ? delay_tsc+0x38/0x60
 [] __const_udelay+0x2d/0x30
 [] _base_handshake_req_reply_wait+0x8e/0x4a0 [mpt3sas]
 [] _base_get_ioc_facts+0x123/0x590 [mpt3sas]
 [] ? _base_diag_reset+0x238/0x340 [mpt3sas]
 [] mpt3sas_base_hard_reset_handler+0x1f3/0x420 [mpt3sas]
 [] _ctl_ioctl_main.isra.12+0x11b9/0x1200 [mpt3sas]
 [] ? xfs_file_aio_write+0x155/0x1b0 [xfs]
 [] ? do_sync_write+0x93/0xe0
 [] _ctl_ioctl+0x1a/0x20 [mpt3sas]
 [] do_vfs_ioctl+0x350/0x560
 [] ? __sb_end_write+0x31/0x60
 [] SyS_ioctl+0xa1/0xc0
 [] ? system_call_after_swapgs+0xa2/0x146
 [] system_call_fastpath+0x1c/0x21
 [] ? system_call_after_swapgs+0xae/0x146
Code: 83 c3 10 4c 89 e2 4c 89 ee e8 8d 21 04 00 48 8b 03 48 85 c0 75 e5 41 f6 
44 24 4a 10 74 ad 4c 89 e6 4c 89 ef e8 b2 42 00 00 eb a0 <0f> 0b 0f 1f 40 00 66 
2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90
RIP  [] blk_requeue_request+0x90/0xa0
 RSP 

As a part of host reset operation, driver will flushout all IOs
outstanding at driver level with "DID_RESET" result.
To find which are all commands outstanding at the driver level,
driver loops with smid starting from one to HBA queue depth and
calls mpt3sas_scsih_scsi_lookup_get() to get scmd as shown below

 for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid);
if (!scmd)
continue;

But in mpt3sas_scsih_scsi_lookup_get() function, driver returns some
scsi cmnds which are not outstanding at the driver level (possibly request
is constructed at block layer since QUEUE_FLAG_QUIESCED is not set. Even if
driver uses scsi_block_requests and scsi_unblock_requests, issue still
persists as they will be just blocking further IO from scsi layer and
not from block layer) and these commands are flushed with
DID_RESET host bytes thus resulting into above kernel BUG.

To fix this issue, we have modified the mpt3sas_scsih_scsi_lookup_get()
to check for smid equals to zero (note: whenever any scsi cmnd is
outstanding at the driver level then smid for that scsi cmnd won't
be zero, always it starts from one) before it returns the scmd pointer to
the caller. If smid is zero then this function returns scmd pointer as
NULL and driver won't flushout those scsi cmnds at driver level with
DID_RESET host byte thus this issue will not be observed.

Signed-off-by: Chaitra P B 
Signed-off-by: Sreekanth Reddy 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 1 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 668f350..49d92d0 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -3309,6 +3309,7 @@ void mpt3sas_base_clear_st(struct MPT3SAS_ADAPTER *ioc,
return;
st->cb_idx = 0xFF;
st->direct_io = 0;
+   st->smid = 0;
atomic_set(&ioc->chain_lookup[st->smid - 1].chain_offset, 0);
 }
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 23902ad..96e523a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1489,7 +1489,7 @@ struct scsi_cmnd *
scmd = scsi_host_find_tag(ioc->shost, unique_tag);
if (scmd) {
st = scsi_cmd_priv(scmd);
-   if (st->cb_idx == 0xFF)
+   if (st->cb_idx == 0xFF || st->smid == 0)
scmd = NULL;
}
}
-- 
1.8.3.1



[PATCH] mpt3sas: Fix calltrace observed while running IO & host reset

2018-06-12 Thread Chaitra P B
 [] scsi_softirq_done+0x132/0x160
 [] blk_done_softirq+0x96/0xc0
 [] __do_softirq+0xf5/0x280
 [] call_softirq+0x1c/0x30
 [] do_softirq+0x65/0xa0
 [] irq_exit+0x105/0x110
 [] smp_apic_timer_interrupt+0x48/0x60
 [] apic_timer_interrupt+0x162/0x170
 
 [] ? scsi_done+0x21/0x60
 [] ? delay_tsc+0x38/0x60
 [] __const_udelay+0x2d/0x30
 [] _base_handshake_req_reply_wait+0x8e/0x4a0 [mpt3sas]
 [] _base_get_ioc_facts+0x123/0x590 [mpt3sas]
 [] ? _base_diag_reset+0x238/0x340 [mpt3sas]
 [] mpt3sas_base_hard_reset_handler+0x1f3/0x420 [mpt3sas]
 [] _ctl_ioctl_main.isra.12+0x11b9/0x1200 [mpt3sas]
 [] ? xfs_file_aio_write+0x155/0x1b0 [xfs]
 [] ? do_sync_write+0x93/0xe0
 [] _ctl_ioctl+0x1a/0x20 [mpt3sas]
 [] do_vfs_ioctl+0x350/0x560
 [] ? __sb_end_write+0x31/0x60
 [] SyS_ioctl+0xa1/0xc0
 [] ? system_call_after_swapgs+0xa2/0x146
 [] system_call_fastpath+0x1c/0x21
 [] ? system_call_after_swapgs+0xae/0x146
Code: 83 c3 10 4c 89 e2 4c 89 ee e8 8d 21 04 00 48 8b 03 48 85 c0 75 e5 41 f6 
44 24 4a 10 74 ad 4c 89 e6 4c 89 ef e8 b2 42 00 00 eb a0 <0f> 0b 0f 1f 40 00 66 
2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90
RIP  [] blk_requeue_request+0x90/0xa0
 RSP 

As a part of host reset operation, driver will flushout all IOs
outstanding at driver level with "DID_RESET" result.
To find which are all commands outstanding at the driver level,
driver loops with smid starting from one to HBA queue depth and
calls mpt3sas_scsih_scsi_lookup_get() to get scmd as shown below

 for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid);
if (!scmd)
continue;

But in mpt3sas_scsih_scsi_lookup_get() function, driver returns some
scsi cmnds which are not outstanding at the driver level (possibly request
is constructed at block layer since QUEUE_FLAG_QUIESCED is not set. Even if
driver uses scsi_block_requests and scsi_unblock_requests, issue still
persists as they will be just blocking further IO from scsi layer and
not from block layer) and these commands are flushed with
DID_RESET host bytes thus resulting into above kernel BUG.

To fix this issue, we have modified the mpt3sas_scsih_scsi_lookup_get()
to check for smid equals to zero (note: whenever any scsi cmnd is
outstanding at the driver level then smid for that scsi cmnd won't
be zero, always it starts from one) before it returns the scmd pointer to
the caller. If smid is zero then this function returns scmd pointer as
NULL and driver won't flushout those scsi cmnds at driver level with
DID_RESET host byte thus this issue will not be observed.

Signed-off-by: Chaitra P B 
Signed-off-by: Sreekanth Reddy  
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 23902ad..96e523a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1489,7 +1489,7 @@ struct scsi_cmnd *
scmd = scsi_host_find_tag(ioc->shost, unique_tag);
if (scmd) {
st = scsi_cmd_priv(scmd);
-   if (st->cb_idx == 0xFF)
+   if (st->cb_idx == 0xFF || st->smid == 0)
scmd = NULL;
}
}
-- 
1.8.3.1



[PATCH 3/6] mpt3sas: Don't access the structure after decrementing it's instance reference count.

2018-05-31 Thread Chaitra P B
While configuring of NVMe device handling, _pcie_device structure member
was accessed after its reference count is decremented/put. Hence modified
code to access member of _pcie_device structure before its reference count
is decremented/put.

Signed-off-by: Chaitra P B 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 884878b..bf57827 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2365,13 +2365,14 @@ scsih_slave_configure(struct scsi_device *sdev)
"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);
+
+   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.
-- 
1.8.3.1



[PATCH 6/6] mpt3sas: Update driver version "26.100.00.00"

2018-05-31 Thread Chaitra P B
Updated driver version to "26.100.00.00"

Signed-off-by: Chaitra P B 
---
 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 3d49ead..b00670a 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 "25.100.00.00"
-#define MPT3SAS_MAJOR_VERSION  25
+#define MPT3SAS_DRIVER_VERSION "26.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  26
 #define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
-- 
1.8.3.1



[PATCH 5/6] mpt3sas: As per MPI-spec, use combined reply queue for SAS3.5 controllers when HBA supports more than 16 MSI-x vectors.

2018-05-31 Thread Chaitra P B
Presently driver is using combined reply queue feature when
MSI-x vectors > 8, for both SAS3 and SAS3.5 controllers.
But as per MPI-spec,
1.For SAS3 controllers, driver should use combined reply queue when HBA
supports more than 8 MSI-x vectors.
2.For SAS3.5 controllers, driver should use combined reply queue when HBA
supports more than 16 MSI-x vectors.

So modified driver code to use combined reply queue for SAS3 controllers
when HBA supports > 8 MSI-x vectors and for SAS3.5 controllers when HBA
supports > 16 MSI-x vectors.

Signed-off-by: Chaitra P B 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 15 ---
 drivers/scsi/mpt3sas/mpt3sas_base.h |  1 +
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index cef480a..668f350 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -2952,10 +2952,9 @@ mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc)
_base_free_irq(ioc);
_base_disable_msix(ioc);
 
-   if (ioc->combined_reply_queue) {
-   kfree(ioc->replyPostRegisterIndex);
-   ioc->replyPostRegisterIndex = NULL;
-   }
+   kfree(ioc->replyPostRegisterIndex);
+   ioc->replyPostRegisterIndex = NULL;
+
 
if (ioc->chip_phys) {
iounmap(ioc->chip);
@@ -3062,7 +3061,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
/* Use the Combined reply queue feature only for SAS3 C0 & higher
 * revision HBAs and also only when reply queue count is greater than 8
 */
-   if (ioc->combined_reply_queue && ioc->reply_queue_count > 8) {
+   if (ioc->combined_reply_queue) {
/* Determine the Supplemental Reply Post Host Index Registers
 * Addresse. Supplemental Reply Post Host Index Registers
 * starts at offset MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET and
@@ -3086,8 +3085,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
 MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET +
 (i * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET));
}
-   } else
-   ioc->combined_reply_queue = 0;
+   }
 
if (ioc->is_warpdrive) {
ioc->reply_post_host_index[0] = (resource_size_t __iomem *)
@@ -5704,6 +5702,9 @@ _base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc)
facts->WhoInit = mpi_reply.WhoInit;
facts->NumberOfPorts = mpi_reply.NumberOfPorts;
facts->MaxMSIxVectors = mpi_reply.MaxMSIxVectors;
+   if (ioc->msix_enable && (facts->MaxMSIxVectors <=
+   MAX_COMBINED_MSIX_VECTORS(ioc->is_gen35_ioc)))
+   ioc->combined_reply_queue = 0;
facts->RequestCredit = le16_to_cpu(mpi_reply.RequestCredit);
facts->MaxReplyDescriptorPostQueueDepth =
le16_to_cpu(mpi_reply.MaxReplyDescriptorPostQueueDepth);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index ec222ad..3d49ead 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -323,6 +323,7 @@
  * There are twelve Supplemental Reply Post Host Index Registers
  * and each register is at offset 0x10 bytes from the previous one.
  */
+#define MAX_COMBINED_MSIX_VECTORS(gen35) ((gen35 == 1) ? 16 : 8)
 #define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G312
 #define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G35   16
 #define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET  (0x10)
-- 
1.8.3.1



[PATCH 4/6] mpt3sas: Fix, False timeout prints for ioctl and other internal commands during controller reset.

2018-05-31 Thread Chaitra P B
When an ioctl is sent to FW and if there is a controller reset issued
before ioctl gets completed, then in controller reset path all the pending
ioctl commands are terminated from "mpt3sas_ctl_reset_handler" function.
And this will wake up the waiting ioctl commands in ioctl path and prints
timeout which is actually not a timeout.

Introduced "mpt3sas_base_check_cmd_timeout" function to check and print
whether command got timed out (or) terminated due to Host reset.

Signed-off-by: Chaitra P B 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c   | 52 +--
 drivers/scsi/mpt3sas/mpt3sas_base.h   |  2 ++
 drivers/scsi/mpt3sas/mpt3sas_config.c |  7 ++---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c| 38 ++---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c  | 16 +--
 5 files changed, 65 insertions(+), 50 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index bf04fa9..cef480a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -102,6 +102,34 @@ static int
 _base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc);
 
 /**
+ * mpt3sas_base_check_cmd_timeout - Function
+ * to check timeout and command termination due
+ * to Host reset.
+ *
+ * @ioc:   per adapter object.
+ * @status:Status of issued command.
+ * @mpi_request:mf request pointer.
+ * @sz:size of buffer.
+ *
+ * @Returns - 1/0 Reset to be done or Not
+ */
+u8
+mpt3sas_base_check_cmd_timeout(struct MPT3SAS_ADAPTER *ioc,
+   u8 status, void *mpi_request, int sz)
+{
+   u8 issue_reset = 0;
+
+   if (!(status & MPT3_CMD_RESET))
+   issue_reset = 1;
+
+   pr_err(MPT3SAS_FMT "Command %s\n", ioc->name,
+   ((issue_reset == 0) ? "terminated due to Host Reset" : "Timeout"));
+   _debug_dump_mf(mpi_request, sz);
+
+   return issue_reset;
+}
+
+/**
  * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug.
  *
  */
@@ -5354,7 +5382,7 @@ mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER 
*ioc,
 {
u16 smid;
u32 ioc_state;
-   bool issue_reset = false;
+   u8 issue_reset = 0;
int rc;
void *request;
u16 wait_state_count;
@@ -5413,12 +5441,10 @@ mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER 
*ioc,
ioc->ioc_link_reset_in_progress)
ioc->ioc_link_reset_in_progress = 0;
if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) {
-   pr_err(MPT3SAS_FMT "%s: timeout\n",
-   ioc->name, __func__);
-   _debug_dump_mf(mpi_request,
-   sizeof(Mpi2SasIoUnitControlRequest_t)/4);
-   if (!(ioc->base_cmds.status & MPT3_CMD_RESET))
-   issue_reset = true;
+   issue_reset =
+   mpt3sas_base_check_cmd_timeout(ioc,
+   ioc->base_cmds.status, mpi_request,
+   sizeof(Mpi2SasIoUnitControlRequest_t)/4);
goto issue_host_reset;
}
if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID)
@@ -5456,7 +5482,7 @@ mpt3sas_base_scsi_enclosure_processor(struct 
MPT3SAS_ADAPTER *ioc,
 {
u16 smid;
u32 ioc_state;
-   bool issue_reset = false;
+   u8 issue_reset = 0;
int rc;
void *request;
u16 wait_state_count;
@@ -5509,12 +5535,10 @@ mpt3sas_base_scsi_enclosure_processor(struct 
MPT3SAS_ADAPTER *ioc,
wait_for_completion_timeout(&ioc->base_cmds.done,
msecs_to_jiffies(1));
if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) {
-   pr_err(MPT3SAS_FMT "%s: timeout\n",
-   ioc->name, __func__);
-   _debug_dump_mf(mpi_request,
-   sizeof(Mpi2SepRequest_t)/4);
-   if (!(ioc->base_cmds.status & MPT3_CMD_RESET))
-   issue_reset = false;
+   issue_reset =
+   mpt3sas_base_check_cmd_timeout(ioc,
+   ioc->base_cmds.status, mpi_request,
+   sizeof(Mpi2SepRequest_t)/4);
goto issue_host_reset;
}
if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index f02974c..ec222ad 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1482,6 +1482,8 @@ int mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc);
 void
 mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc);
 
+u8 mpt3sas_base_check_cmd_timeout(struct MPT3SAS_ADAPTER *ioc,
+   u8 status, void *mpi_request, int sz);
 
 /* scsih shared API */
 struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(str

[PATCH 1/6] mpt3sas: Don't abort I/Os issued to NVMe drives while processing Async Broadcast primitive event.

2018-05-31 Thread Chaitra P B
Linux driver when receives Broadcast Asynchronous Event Notification (BAEN)
from the controller firmware, checks all pending I/Os at the driver level
and issues query task, abort task TMs.This is done in the driver to handle
drives which are connected with multiple initiators and undergoing target
resets.In the BAEN handling code, the I/Os issued to NVMe drives are also
handled and query task and abort task TMs are issued, which are not
necessary as there is no multi-initiator and no BAEN concept with NVMe
drives.Hence when the driver checks for pending I/Os it skips NVMe drives
at this moment.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index b8d131a..d31f0cc 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -7483,6 +7483,10 @@ _scsih_sas_broadcast_primitive_event(struct 
MPT3SAS_ADAPTER *ioc,
if (sas_device_priv_data->sas_target->flags &
MPT_TARGET_FLAGS_VOLUME)
continue;
+/* skip PCIe devices */
+   if (sas_device_priv_data->sas_target->flags &
+   MPT_TARGET_FLAGS_PCIE_DEVICE)
+   continue;
 
handle = sas_device_priv_data->sas_target->handle;
lun = sas_device_priv_data->lun;
-- 
1.8.3.1



[PATCH 2/6] mpt3sas: Incorrect command status was set/marked as not used.

2018-05-31 Thread Chaitra P B
In _scsih_scan_finished driver should mark port_enable_cmd.status as
'command not used', instead base_cmds.status was marked as
'command not used'.so updated code to mark port_enable_cmd.status as
'command not used'.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index d31f0cc..884878b 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -10394,7 +10394,7 @@ scsih_scan_finished(struct Scsi_Host *shost, unsigned 
long time)
}
 
if (time >= (300 * HZ)) {
-   ioc->base_cmds.status = MPT3_CMD_NOT_USED;
+   ioc->port_enable_cmds.status = MPT3_CMD_NOT_USED;
pr_info(MPT3SAS_FMT
"port enable: FAILED with timeout (timeout=300s)\n",
ioc->name);
@@ -10416,7 +10416,7 @@ scsih_scan_finished(struct Scsi_Host *shost, unsigned 
long time)
}
 
pr_info(MPT3SAS_FMT "port enable: SUCCESS\n", ioc->name);
-   ioc->base_cmds.status = MPT3_CMD_NOT_USED;
+   ioc->port_enable_cmds.status = MPT3_CMD_NOT_USED;
 
if (ioc->wait_for_discovery_to_complete) {
ioc->wait_for_discovery_to_complete = 0;
-- 
1.8.3.1



[PATCH 0/6] mpt3sas: Enhancements and Defect fixes.

2018-05-31 Thread Chaitra P B
Chaitra P B (6):
  mpt3sas: Don't abort I/Os issued to NVMe drives while processing
Async  Broadcast primitive event.
  mpt3sas: Incorrect command status was set/marked as not used.
  mpt3sas: Don't access the structure after decrementing it's
instance reference count.
  mpt3sas: Fix, False timeout prints for ioctl and other internal
commands during controller reset.
  mpt3sas: As per MPI-spec, use combined reply queue for SAS3.5
controllers when HBA supports more than 16 MSI-x vectors.
  mpt3sas: Update driver version "26.100.00.00"

 drivers/scsi/mpt3sas/mpt3sas_base.c   | 67 ---
 drivers/scsi/mpt3sas/mpt3sas_base.h   |  7 ++--
 drivers/scsi/mpt3sas/mpt3sas_config.c |  7 ++--
 drivers/scsi/mpt3sas/mpt3sas_ctl.c| 38 
 drivers/scsi/mpt3sas/mpt3sas_scsih.c  | 31 
 5 files changed, 86 insertions(+), 64 deletions(-)

-- 
1.8.3.1



[PATCH v3 07/14] mpt3sas: Increase event log buffer to support 24 port HBA's.

2018-04-24 Thread Chaitra P B
For 24 port HBA's events generated by IOC are more in certain cases and
the current circular buffer may be overwritten.Hence increased the event
log buffer to accommodate more events.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
index a44046c..18b46fa 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
@@ -184,7 +184,7 @@ struct mpt3_ioctl_iocinfo {
 
 
 /* number of event log entries */
-#define MPT3SAS_CTL_EVENT_LOG_SIZE (50)
+#define MPT3SAS_CTL_EVENT_LOG_SIZE (200)
 
 /**
  * struct mpt3_ioctl_eventquery - query event count and type
-- 
1.8.3.1



[PATCH v3 00/14] mpt3sas: Enhancements and Defect fixes.

2018-04-24 Thread Chaitra P B
Chaitra P B (14):
  mpt3sas: Bug fix for big endian systems.
  mpt3sas: Pre-allocate RDPQ Array at driver boot time.
  mpt3sas: Lockless access for chain buffers.
  mpt3sas: Optimize I/O memory consumption in driver.
  mpt3sas: Enhanced handling of Sense Buffer.
  mpt3sas: Added support for SAS Device Discovery Error Event.
  mpt3sas: Increase event log buffer to support 24 port HBA's.
  mpt3sas: Allow processing of events during driver unload.
  mpt3sas: Cache enclosure pages during enclosure add.
  mpt3sas: Report Firmware Package Version from HBA Driver.
  mpt3sas: Update MPI Headers
  mpt3sas: For NVME device, issue a protocol level reset instead of
hot reset and use TM timeout value exposed in PCIe Device Page  2.
  mpt3sas: fix possible memory leak.
  mpt3sas: Update driver version "25.100.00.00"

 drivers/scsi/mpt3sas/mpi/mpi2.h  |   9 +-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  30 +-
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |   2 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |   7 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 475 +++---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  60 +++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  33 ++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.h   |   2 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 491 +--
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |   3 +-
 10 files changed, 816 insertions(+), 296 deletions(-)

-- 
1.8.3.1



[PATCH v3 10/14] mpt3sas: Report Firmware Package Version from HBA Driver.

2018-04-24 Thread Chaitra P B
Added function _base_display_fwpkg_version, which sends FWUpload
request to pull FW package version from FW Image Header.
Now driver prints FW package version in addition to FW
version if the PackageVersion is valid.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index bcd16e4..febd858 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -3825,6 +3825,105 @@ _base_display_OEMs_branding(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * _base_display_fwpkg_version - sends FWUpload request to pull FWPkg
+ * version from FW Image Header.
+ * @ioc: per adapter object
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+   static int
+_base_display_fwpkg_version(struct MPT3SAS_ADAPTER *ioc)
+{
+   Mpi2FWImageHeader_t *FWImgHdr;
+   Mpi25FWUploadRequest_t *mpi_request;
+   Mpi2FWUploadReply_t mpi_reply;
+   int r = 0;
+   void *fwpkg_data = NULL;
+   dma_addr_t fwpkg_data_dma;
+   u16 smid, ioc_status;
+   size_t data_length;
+
+   dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+   __func__));
+
+   if (ioc->base_cmds.status & MPT3_CMD_PENDING) {
+   pr_err(MPT3SAS_FMT "%s: internal command already in use\n",
+   ioc->name, __func__);
+   return -EAGAIN;
+   }
+
+   data_length = sizeof(Mpi2FWImageHeader_t);
+   fwpkg_data = pci_alloc_consistent(ioc->pdev, data_length,
+   &fwpkg_data_dma);
+   if (!fwpkg_data) {
+   pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
+   ioc->name, __FILE__, __LINE__, __func__);
+   return -ENOMEM;
+   }
+
+   smid = mpt3sas_base_get_smid(ioc, ioc->base_cb_idx);
+   if (!smid) {
+   pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
+   ioc->name, __func__);
+   r = -EAGAIN;
+   goto out;
+   }
+
+   ioc->base_cmds.status = MPT3_CMD_PENDING;
+   mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
+   ioc->base_cmds.smid = smid;
+   memset(mpi_request, 0, sizeof(Mpi25FWUploadRequest_t));
+   mpi_request->Function = MPI2_FUNCTION_FW_UPLOAD;
+   mpi_request->ImageType = MPI2_FW_UPLOAD_ITYPE_FW_FLASH;
+   mpi_request->ImageSize = cpu_to_le32(data_length);
+   ioc->build_sg(ioc, &mpi_request->SGL, 0, 0, fwpkg_data_dma,
+   data_length);
+   init_completion(&ioc->base_cmds.done);
+   mpt3sas_base_put_smid_default(ioc, smid);
+   /* Wait for 15 seconds */
+   wait_for_completion_timeout(&ioc->base_cmds.done,
+   FW_IMG_HDR_READ_TIMEOUT*HZ);
+   pr_info(MPT3SAS_FMT "%s: complete\n",
+   ioc->name, __func__);
+   if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) {
+   pr_err(MPT3SAS_FMT "%s: timeout\n",
+   ioc->name, __func__);
+   _debug_dump_mf(mpi_request,
+   sizeof(Mpi25FWUploadRequest_t)/4);
+   r = -ETIME;
+   } else {
+   memset(&mpi_reply, 0, sizeof(Mpi2FWUploadReply_t));
+   if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) {
+   memcpy(&mpi_reply, ioc->base_cmds.reply,
+   sizeof(Mpi2FWUploadReply_t));
+   ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+   MPI2_IOCSTATUS_MASK;
+   if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
+   FWImgHdr = (Mpi2FWImageHeader_t *)fwpkg_data;
+   if (FWImgHdr->PackageVersion.Word) {
+   pr_info(MPT3SAS_FMT "FW Package Version"
+   "(%02d.%02d.%02d.%02d)\n",
+   ioc->name,
+   FWImgHdr->PackageVersion.Struct.Major,
+   FWImgHdr->PackageVersion.Struct.Minor,
+   FWImgHdr->PackageVersion.Struct.Unit,
+   FWImgHdr->PackageVersion.Struct.Dev);
+   }
+   } else {
+   _debug_dump_mf(&mpi_reply,
+   sizeof(Mpi2FWUploadR

[PATCH v3 13/14] mpt3sas: fix possible memory leak.

2018-04-24 Thread Chaitra P B
In ioctl exit path driver refers ioc_list to free memory associated with
diag buffers and event_log pointer used to save events by driver.
If ctl_exit() func is called after unregistering driver, then ioc_list will
be empty and hence driver will not be able to free the allocated memory
which in turn causes memory leak.
So call ctl_exit() function before unregistering mpt3sas driver.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 8ba72a2..8fc2922 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -11276,10 +11276,10 @@ _mpt3sas_exit(void)
pr_info("mpt3sas version %s unloading\n",
MPT3SAS_DRIVER_VERSION);
 
-   pci_unregister_driver(&mpt3sas_driver);
-
mpt3sas_ctl_exit(hbas_to_enumerate);
 
+   pci_unregister_driver(&mpt3sas_driver);
+
scsih_exit();
 }
 
-- 
1.8.3.1



[PATCH v3 14/14] mpt3sas: Update driver version "25.100.00.00"

2018-04-24 Thread Chaitra P B
Update driver version to match OOB/internal driver version.

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 43d66c5..f2debe1 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 "17.100.00.00"
-#define MPT3SAS_MAJOR_VERSION  17
+#define MPT3SAS_DRIVER_VERSION "25.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  25
 #define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
-- 
1.8.3.1



[PATCH v3 02/14] mpt3sas: Pre-allocate RDPQ Array at driver boot time.

2018-04-24 Thread Chaitra P B
Instead of allocating RDPQ array (This stores the address's of each RDPQ
pools) at run time, now it will be allocated once during driver load time
and same will be reused during host reset operation also (instead of
allocating & freeing this buffer on the fly during every host reset
operation) and then freed during driver unload.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 9c00185..b23a2eb 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4159,7 +4159,14 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
}
} while (ioc->rdpq_array_enable &&
   (++i < ioc->reply_queue_count));
-
+   if (ioc->reply_post_free_array &&
+   ioc->rdpq_array_enable) {
+   dma_pool_free(ioc->reply_post_free_array_dma_pool,
+   ioc->reply_post_free_array,
+   ioc->reply_post_free_array_dma);
+   ioc->reply_post_free_array = NULL;
+   }
+   dma_pool_destroy(ioc->reply_post_free_array_dma_pool);
dma_pool_destroy(ioc->reply_post_free_dma_pool);
kfree(ioc->reply_post);
}
@@ -4209,7 +4216,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
struct mpt3sas_facts *facts;
u16 max_sge_elements;
u16 chains_needed_per_io;
-   u32 sz, total_sz, reply_post_free_sz;
+   u32 sz, total_sz, reply_post_free_sz, reply_post_free_array_sz;
u32 retry_sz;
u16 max_request_credit, nvme_blocks_needed;
unsigned short sg_tablesize;
@@ -4681,6 +4688,28 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->name, (unsigned long long)ioc->reply_free_dma));
total_sz += sz;
 
+   if (ioc->rdpq_array_enable) {
+   reply_post_free_array_sz = ioc->reply_queue_count *
+   sizeof(Mpi2IOCInitRDPQArrayEntry);
+   ioc->reply_post_free_array_dma_pool =
+   dma_pool_create("reply_post_free_array pool",
+   &ioc->pdev->dev, reply_post_free_array_sz, 16, 0);
+   if (!ioc->reply_post_free_array_dma_pool) {
+   dinitprintk(ioc,
+   pr_info(MPT3SAS_FMT "reply_post_free_array pool: "
+   "dma_pool_create failed\n", ioc->name));
+   goto out;
+   }
+   ioc->reply_post_free_array =
+   dma_pool_alloc(ioc->reply_post_free_array_dma_pool,
+   GFP_KERNEL, &ioc->reply_post_free_array_dma);
+   if (!ioc->reply_post_free_array) {
+   dinitprintk(ioc,
+   pr_info(MPT3SAS_FMT "reply_post_free_array pool: "
+   "dma_pool_alloc failed\n", ioc->name));
+   goto out;
+   }
+   }
ioc->config_page_sz = 512;
ioc->config_page = pci_alloc_consistent(ioc->pdev,
ioc->config_page_sz, &ioc->config_page_dma);
@@ -5487,8 +5516,6 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc)
ktime_t current_time;
u16 ioc_status;
u32 reply_post_free_array_sz = 0;
-   Mpi2IOCInitRDPQArrayEntry *reply_post_free_array = NULL;
-   dma_addr_t reply_post_free_array_dma;
 
dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
__func__));
@@ -5522,23 +5549,14 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc)
if (ioc->rdpq_array_enable) {
reply_post_free_array_sz = ioc->reply_queue_count *
sizeof(Mpi2IOCInitRDPQArrayEntry);
-   reply_post_free_array = pci_alloc_consistent(ioc->pdev,
-   reply_post_free_array_sz, &reply_post_free_array_dma);
-   if (!reply_post_free_array) {
-   pr_err(MPT3SAS_FMT
-   "reply_post_free_array: pci_alloc_consistent failed\n",
-   ioc->name);
-   r = -ENOMEM;
-   goto out;
-   }
-   memset(reply_post_free_array, 0, reply_post_free_array_sz);
+   memset(ioc->reply_post_free_array, 0, reply_post_free_array_sz);
for (i = 0; i < ioc->reply_queue_count; i++)
-   reply_post_free_array[i].RDPQBaseAddress =

[PATCH v3 04/14] mpt3sas: Optimize I/O memory consumption in driver.

2018-04-24 Thread Chaitra P B
For every IO, memory of PAGE size is allocated for handling NVMe native
PRPS. And in addition to that for every IO (chains need per IO * chain
buffer size, e.g. 38 * 128byte) amount of memory is allocated for chain
buffers.

However, at any point of time; the IO request can be for NVMe target device
(where PRP's page is used for framing PRP's) or can be for SCSI target
device (where chain buffers are used for framing chain SGE's). This patch
modifies the driver to reuse same pre-allocated PRP page buffers as a chain
buffer for IO's targeted for SCSI target devices. No need to allocate
separate buffers for chain SGE's buffers.

Suppose if the number of chain buffers need for IO doesn't fit in the PRP
Page size then driver maintain's separate buffers for those extra chain
buffers that exceeds the PRP page size. For example consider PRP page size
as 4K and chain buffer size as 128 bytes, then number of chain buffers that
can fit in PRP page is 4096/128 => 32. if the number of chain buffer need
per IO exceeds 32; for example consider number of chains need per IO is 36
then for remaining 4 chain buffer's driver allocates them individual.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 438da7c..415e7f0 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4188,7 +4188,8 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
kfree(ioc->internal_lookup);
if (ioc->chain_lookup) {
for (i = 0; i < ioc->scsiio_depth; i++) {
-   for (j = 0; j < ioc->chains_needed_per_io; j++) {
+   for (j = ioc->chains_per_prp_buffer;
+   j < ioc->chains_needed_per_io; j++) {
ct = &ioc->chain_lookup[i].chains_per_smid[j];
if (ct && ct->chain_buffer)
dma_pool_free(ioc->chain_dma_pool,
@@ -4506,7 +4507,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->chain_lookup = kzalloc(sz, GFP_KERNEL);
if (!ioc->chain_lookup) {
pr_err(MPT3SAS_FMT "chain_lookup: __get_free_pages "
-   "failed\n", ioc->name);
+   "failed\n", ioc->name);
goto out;
}
 
@@ -4520,33 +4521,6 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
}
}
 
-   ioc->chain_dma_pool = dma_pool_create("chain pool", &ioc->pdev->dev,
-   ioc->chain_segment_sz, 16, 0);
-   if (!ioc->chain_dma_pool) {
-   pr_err(MPT3SAS_FMT "chain_dma_pool: dma_pool_create failed\n",
-   ioc->name);
-   goto out;
-   }
-   for (i = 0; i < ioc->scsiio_depth; i++) {
-   for (j = 0; j < ioc->chains_needed_per_io; j++) {
-   ct = &ioc->chain_lookup[i].chains_per_smid[j];
-   ct->chain_buffer = dma_pool_alloc(
-   ioc->chain_dma_pool , GFP_KERNEL,
-   &ct->chain_buffer_dma);
-   if (!ct->chain_buffer) {
-   pr_err(MPT3SAS_FMT "chain_lookup: "
-   " pci_pool_alloc failed\n", ioc->name);
-   goto out;
-   }
-   }
-   total_sz += ioc->chain_segment_sz;
-   }
-
-   dinitprintk(ioc, pr_info(MPT3SAS_FMT
-   "chain pool depth(%d), frame_size(%d), pool_size(%d kB)\n",
-   ioc->name, ioc->chain_depth, ioc->chain_segment_sz,
-   ((ioc->chain_depth *  ioc->chain_segment_sz))/1024));
-
/* initialize hi-priority queue smid's */
ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth,
sizeof(struct request_tracker), GFP_KERNEL);
@@ -4587,6 +4561,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 * be required for NVMe PRP's, only each set of NVMe blocks will be
 * contiguous, so a new set is allocated for each possible I/O.
 */
+   ioc->chains_per_prp_buffer = 0;
if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_NVME_DEVICES) {
nvme_blocks_needed =
(ioc->shost->sg_tablesize * NVME_PRP_SIZE) - 1;
@@ -4609,6 +4584,11 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->name);
goto out;
  

[PATCH v3 06/14] mpt3sas: Added support for SAS Device Discovery Error Event.

2018-04-24 Thread Chaitra P B
The SAS Device Discovery Error Event is sent to the host when
discovery for a particular device is failed during discovery,
even after maximum retries by the IOC.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  4 
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 42 
 2 files changed, 46 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 0b44ff7..93bf710 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1030,6 +1030,9 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
desc = "Cable Event";
break;
+   case MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
+   desc = "SAS Device Discovery Error";
+   break;
case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
desc = "PCIE Device Status Change";
break;
@@ -6596,6 +6599,7 @@ 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);
+   _base_unmask_events(ioc, MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR);
if (ioc->hba_mpi_version_belonged == MPI26_VERSION) {
if (ioc->is_gen35_ioc) {
_base_unmask_events(ioc,
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index c9cce65..796bf33 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -7524,6 +7524,44 @@ _scsih_sas_discovery_event(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _scsih_sas_device_discovery_error_event - display SAS device discovery error
+ * events
+ * @ioc: per adapter object
+ * @fw_event: The fw_event_work object
+ * Context: user.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_sas_device_discovery_error_event(struct MPT3SAS_ADAPTER *ioc,
+   struct fw_event_work *fw_event)
+{
+   Mpi25EventDataSasDeviceDiscoveryError_t *event_data =
+   (Mpi25EventDataSasDeviceDiscoveryError_t *)fw_event->event_data;
+
+   switch (event_data->ReasonCode) {
+   case MPI25_EVENT_SAS_DISC_ERR_SMP_FAILED:
+   pr_warn(MPT3SAS_FMT "SMP command sent to the expander"
+   "(handle:0x%04x, sas_address:0x%016llx,"
+   "physical_port:0x%02x) has failed",
+   ioc->name, le16_to_cpu(event_data->DevHandle),
+   (unsigned long long)le64_to_cpu(event_data->SASAddress),
+   event_data->PhysicalPort);
+   break;
+   case MPI25_EVENT_SAS_DISC_ERR_SMP_TIMEOUT:
+   pr_warn(MPT3SAS_FMT "SMP command sent to the expander"
+   "(handle:0x%04x, sas_address:0x%016llx,"
+   "physical_port:0x%02x) has timed out",
+   ioc->name, le16_to_cpu(event_data->DevHandle),
+   (unsigned long long)le64_to_cpu(event_data->SASAddress),
+   event_data->PhysicalPort);
+   break;
+   default:
+   break;
+   }
+}
+
+/**
  * _scsih_pcie_enumeration_event - handle enumeration events
  * @ioc: per adapter object
  * @fw_event: The fw_event_work object
@@ -9350,6 +9388,9 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct 
fw_event_work *fw_event)
case MPI2_EVENT_SAS_DISCOVERY:
_scsih_sas_discovery_event(ioc, fw_event);
break;
+   case MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
+   _scsih_sas_device_discovery_error_event(ioc, fw_event);
+   break;
case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
_scsih_sas_broadcast_primitive_event(ioc, fw_event);
break;
@@ -9534,6 +9575,7 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, 
u8 msix_index,
case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
case MPI2_EVENT_IR_OPERATION_STATUS:
case MPI2_EVENT_SAS_DISCOVERY:
+   case MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
case MPI2_EVENT_IR_PHYSICAL_DISK:
case MPI2_EVENT_PCIE_ENUMERATION:
-- 
1.8.3.1



[PATCH v3 05/14] mpt3sas: Enhanced handling of Sense Buffer.

2018-04-24 Thread Chaitra P B
Enhanced DMA allocation for Sense Buffer, if the allocation does not fit
within same 4GB.Introduced is_MSB_are_same function to check if allocted
buffer within 4GB range or not.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 56 +
 1 file changed, 56 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 415e7f0..0b44ff7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4205,6 +4205,31 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * is_MSB_are_same - checks whether all reply queues in a set are
+ * having same upper 32bits in their base memory address.
+ * @reply_pool_start_address: Base address of a reply queue set
+ * @pool_sz: Size of single Reply Descriptor Post Queues pool size
+ *
+ * Returns 1 if reply queues in a set have a same upper 32bits
+ * in their base memory address,
+ * else 0
+ */
+
+static int
+is_MSB_are_same(long reply_pool_start_address, u32 pool_sz)
+{
+   long reply_pool_end_address;
+
+   reply_pool_end_address = reply_pool_start_address + pool_sz;
+
+   if (upper_32_bits(reply_pool_start_address) ==
+   upper_32_bits(reply_pool_end_address))
+   return 1;
+   else
+   return 0;
+}
+
+/**
  * _base_allocate_memory_pools - allocate start of day memory pools
  * @ioc: per adapter object
  *
@@ -4664,6 +4689,37 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->name);
goto out;
}
+   /* sense buffer requires to be in same 4 gb region.
+* Below function will check the same.
+* In case of failure, new pci pool will be created with updated
+* alignment. Older allocation and pool will be destroyed.
+* Alignment will be used such a way that next allocation if
+* success, will always meet same 4gb region requirement.
+* Actual requirement is not alignment, but we need start and end of
+* DMA address must have same upper 32 bit address.
+*/
+   if (!is_MSB_are_same((long)ioc->sense, sz)) {
+   //Release Sense pool & Reallocate
+   dma_pool_free(ioc->sense_dma_pool, ioc->sense, ioc->sense_dma);
+   dma_pool_destroy(ioc->sense_dma_pool);
+   ioc->sense = NULL;
+
+   ioc->sense_dma_pool =
+   dma_pool_create("sense pool", &ioc->pdev->dev, sz,
+   roundup_pow_of_two(sz), 0);
+   if (!ioc->sense_dma_pool) {
+   pr_err(MPT3SAS_FMT "sense pool: pci_pool_create 
failed\n",
+   ioc->name);
+   goto out;
+   }
+   ioc->sense = dma_pool_alloc(ioc->sense_dma_pool, GFP_KERNEL,
+   &ioc->sense_dma);
+   if (!ioc->sense) {
+   pr_err(MPT3SAS_FMT "sense pool: pci_pool_alloc 
failed\n",
+   ioc->name);
+   goto out;
+   }
+   }
dinitprintk(ioc, pr_info(MPT3SAS_FMT
"sense pool(0x%p): depth(%d), element_size(%d), pool_size"
"(%d kB)\n", ioc->name, ioc->sense, ioc->scsiio_depth,
-- 
1.8.3.1



[PATCH v3 01/14] mpt3sas: Bug fix for big endian systems.

2018-04-24 Thread Chaitra P B
This patch fixes bug for big endian systems.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |  2 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 55 -
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  4 +--
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 11 +++---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 59 +++-
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |  3 +-
 6 files changed, 71 insertions(+), 63 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_init.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_init.h
index 948a3ba..6213ce6 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_init.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_init.h
@@ -75,7 +75,7 @@
 
 typedef struct _MPI2_SCSI_IO_CDB_EEDP32 {
U8 CDB[20]; /*0x00 */
-   U32 PrimaryReferenceTag;/*0x14 */
+   __be32 PrimaryReferenceTag; /*0x14 */
U16 PrimaryApplicationTag;  /*0x18 */
U16 PrimaryApplicationTagMask;  /*0x1A */
U32 TransferLength; /*0x1C */
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 0a0e7aa..9c00185 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -394,13 +394,14 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
buff_ptr_phys = buffer_iomem_phys;
WARN_ON(buff_ptr_phys > U32_MAX);
 
-   if (sgel->FlagsLength &
+   if (le32_to_cpu(sgel->FlagsLength) &
(MPI2_SGE_FLAGS_HOST_TO_IOC << MPI2_SGE_FLAGS_SHIFT))
is_write = 1;
 
for (i = 0; i < MPT_MIN_PHYS_SEGMENTS + ioc->facts.MaxChainDepth; i++) {
 
-   sgl_flags = (sgel->FlagsLength >> MPI2_SGE_FLAGS_SHIFT);
+   sgl_flags =
+   (le32_to_cpu(sgel->FlagsLength) >> MPI2_SGE_FLAGS_SHIFT);
 
switch (sgl_flags & MPI2_SGE_FLAGS_ELEMENT_MASK) {
case MPI2_SGE_FLAGS_CHAIN_ELEMENT:
@@ -411,7 +412,7 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
 */
sgel_next =
_base_get_chain_buffer_dma_to_chain_buffer(ioc,
-   sgel->Address);
+   le32_to_cpu(sgel->Address));
if (sgel_next == NULL)
return;
/*
@@ -426,7 +427,8 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
dst_addr_phys = _base_get_chain_phys(ioc,
smid, sge_chain_count);
WARN_ON(dst_addr_phys > U32_MAX);
-   sgel->Address = (u32)dst_addr_phys;
+   sgel->Address =
+   cpu_to_le32(lower_32_bits(dst_addr_phys));
sgel = sgel_next;
sge_chain_count++;
break;
@@ -435,22 +437,28 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
if (is_scsiio_req) {
_base_clone_to_sys_mem(buff_ptr,
sg_virt(sg_scmd),
-   (sgel->FlagsLength & 0x00ff));
+   (le32_to_cpu(sgel->FlagsLength) &
+   0x00ff));
/*
 * FIXME: this relies on a a zero
 * PCI mem_offset.
 */
-   sgel->Address = (u32)buff_ptr_phys;
+   sgel->Address =
+   cpu_to_le32((u32)buff_ptr_phys);
} else {
_base_clone_to_sys_mem(buff_ptr,
ioc->config_vaddr,
-   (sgel->FlagsLength & 0x00ff));
-   sgel->Address = (u32)buff_ptr_phys;
+   (le32_to_cpu(sgel->FlagsLength) &
+   0x00ff));
+   sgel->Address =
+   cpu_to_le32((u32)buff_ptr_phys);
}
}
-   buff_ptr += (sgel->FlagsLength & 0x00ff);
-   buff_ptr_phys += (sgel->FlagsLength & 0x00ff);
-   if ((sgel->FlagsLength &
+   buff_ptr +

[PATCH v3 12/14] mpt3sas: For NVME device, issue a protocol level reset instead of hot reset and use TM timeout value exposed in PCIe Device Page 2.

2018-04-24 Thread Chaitra P B
1)Manufacturing Page 11 contains parameters to control
internal firmware behavior. Based on AddlFlags2 field
FW/Driver behaviour can be changed, (flag tm_custom_handling
is used for this)

a) For PCIe device, protocol level reset should be used if
flag tm_custom_handling is 0.
Since Abort Task Set, LUN reset and Target reset will result
in a protocol level reset. Drivers should issue only one type
of this reset, if that fails then it should escalate to a controller
reset (diag reset/OCR).
b) If the driver has control over the TM reset timeout value, then
driver should use the value exposed in PCIe Device Page 2 for pcie device
(field ControllerResetTO).

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 13 ++
 drivers/scsi/mpt3sas/mpt3sas_base.h  | 26 ++--
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 22 +--
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 76 ++--
 4 files changed, 116 insertions(+), 21 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index febd858..600c717 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4139,6 +4139,7 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
Mpi2ConfigReply_t mpi_reply;
u32 iounit_pg1_flags;
 
+   ioc->nvme_abort_timeout = 30;
mpt3sas_config_get_manufacturing_pg0(ioc, &mpi_reply, &ioc->manu_pg0);
if (ioc->ir_firmware)
mpt3sas_config_get_manufacturing_pg10(ioc, &mpi_reply,
@@ -4157,6 +4158,18 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
mpt3sas_config_set_manufacturing_pg11(ioc, &mpi_reply,
&ioc->manu_pg11);
}
+   if (ioc->manu_pg11.AddlFlags2 & NVME_TASK_MNGT_CUSTOM_MASK)
+   ioc->tm_custom_handling = 1;
+   else {
+   ioc->tm_custom_handling = 0;
+   if (ioc->manu_pg11.NVMeAbortTO < NVME_TASK_ABORT_MIN_TIMEOUT)
+   ioc->nvme_abort_timeout = NVME_TASK_ABORT_MIN_TIMEOUT;
+   else if (ioc->manu_pg11.NVMeAbortTO >
+   NVME_TASK_ABORT_MAX_TIMEOUT)
+   ioc->nvme_abort_timeout = NVME_TASK_ABORT_MAX_TIMEOUT;
+   else
+   ioc->nvme_abort_timeout = ioc->manu_pg11.NVMeAbortTO;
+   }
 
mpt3sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2);
mpt3sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 49333b9..43d66c5 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -146,8 +146,12 @@
 #defineNVME_CMD_PRP1_OFFSET24  /* PRP1 offset in NVMe 
cmd */
 #defineNVME_CMD_PRP2_OFFSET32  /* PRP2 offset in NVMe 
cmd */
 #defineNVME_ERROR_RESPONSE_SIZE16  /* Max NVME Error 
Response */
+#define NVME_TASK_ABORT_MIN_TIMEOUT6
+#define NVME_TASK_ABORT_MAX_TIMEOUT60
+#define NVME_TASK_MNGT_CUSTOM_MASK (0x0010)
 #defineNVME_PRP_PAGE_SIZE  4096/* Page size */
 
+
 /*
  * reset phases
  */
@@ -363,7 +367,15 @@ struct Mpi2ManufacturingPage11_t {
u8  EEDPTagMode;/* 09h */
u8  Reserved3;  /* 0Ah */
u8  Reserved4;  /* 0Bh */
-   __le32  Reserved5[23];  /* 0Ch-60h*/
+   __le32  Reserved5[8];   /* 0Ch-2Ch */
+   u16 AddlFlags2; /* 2Ch */
+   u8  AddlFlags3; /* 2Eh */
+   u8  Reserved6;  /* 2Fh */
+   __le32  Reserved7[7];   /* 30h - 4Bh */
+   u8  NVMeAbortTO;/* 4Ch */
+   u8  Reserved8;  /* 4Dh */
+   u16 Reserved9;  /* 4Eh */
+   __le32  Reserved10[4];  /* 50h - 60h */
 };
 
 /**
@@ -573,6 +585,7 @@ struct _pcie_device {
u8  enclosure_level;
u8  connector_name[4];
u8  *serial_number;
+   u8  reset_timeout;
struct kref refcount;
 };
 /**
@@ -1211,6 +1224,10 @@ struct MPT3SAS_ADAPTER {
void*event_log;
u32 event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
 
+   u8  tm_custom_handling;
+   u8  nvme_abort_timeout;
+
+
/* static config pages */
struct mpt3sas_facts facts;
struct mpt3sas_port_facts *pfacts;
@@ -1470,10 +1487,11 @@ u8 mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER 
*ioc, u8 msix_index,
u32 reply);
 void mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase);

[PATCH v3 09/14] mpt3sas: Cache enclosure pages during enclosure add.

2018-04-24 Thread Chaitra P B
In function _scsih_add_device,
for each device connected to an enclosure, driver reads the
enclosure page(To get details like enclosure handle,
enclosure logical ID, enclosure level etc.)

With this patch, instead of reading enclosure page everytime,
driver maintains a list for enclosure device(During enclosure
add event, enclosure device is added to the list and removed
from the list on delete events) and uses the enclosure page
from the list.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  22 +++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  14 ++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 296 +++
 3 files changed, 236 insertions(+), 96 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 93bf710..bcd16e4 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4087,6 +4087,27 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * mpt3sas_free_enclosure_list - release memory
+ * @ioc: per adapter object
+ *
+ * Free memory allocated during encloure add.
+ *
+ * Return nothing.
+ */
+void
+mpt3sas_free_enclosure_list(struct MPT3SAS_ADAPTER *ioc)
+{
+   struct _enclosure_node *enclosure_dev, *enclosure_dev_next;
+
+   /* Free enclosure list */
+   list_for_each_entry_safe(enclosure_dev,
+   enclosure_dev_next, &ioc->enclosure_list, list) {
+   list_del(&enclosure_dev->list);
+   kfree(enclosure_dev);
+   }
+}
+
+/**
  * _base_release_memory_pools - release memory
  * @ioc: per adapter object
  *
@@ -,6 +6687,7 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc)
mpt3sas_base_stop_watchdog(ioc);
mpt3sas_base_free_resources(ioc);
_base_release_memory_pools(ioc);
+   mpt3sas_free_enclosure_list(ioc);
pci_set_drvdata(ioc->pdev, NULL);
kfree(ioc->cpu_msix_table);
if (ioc->is_warpdrive)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 01eb910..ee8ce7e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -741,6 +741,17 @@ struct _sas_node {
struct list_head sas_port_list;
 };
 
+
+/**
+ * struct _enclosure_node - enclosure information
+ * @list: list of enclosures
+ * @pg0: enclosure pg0;
+ */
+struct _enclosure_node {
+   struct list_head list;
+   Mpi2SasEnclosurePage0_t pg0;
+};
+
 /**
  * enum reset_type - reset state
  * @FORCE_BIG_HAMMER: issue diagnostic reset
@@ -1013,6 +1024,7 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct 
MPT3SAS_ADAPTER *ioc);
  * @iounit_pg8: static iounit page 8
  * @sas_hba: sas host object
  * @sas_expander_list: expander object list
+ * @enclosure_list: enclosure object list
  * @sas_node_lock:
  * @sas_device_list: sas device object list
  * @sas_device_init_list: sas device object list (used only at init time)
@@ -1218,6 +1230,7 @@ struct MPT3SAS_ADAPTER {
/* sas hba, expander, and device list */
struct _sas_node sas_hba;
struct list_head sas_expander_list;
+   struct list_head enclosure_list;
spinlock_t  sas_node_lock;
struct list_head sas_device_list;
struct list_head sas_device_init_list;
@@ -1391,6 +1404,7 @@ int mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc);
 int mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc);
+void mpt3sas_free_enclosure_list(struct MPT3SAS_ADAPTER *ioc);
 int mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
enum reset_type type);
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 33587a8..bc8e7f0 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1362,6 +1362,30 @@ mpt3sas_scsih_expander_find_by_handle(struct 
MPT3SAS_ADAPTER *ioc, u16 handle)
 }
 
 /**
+ * mpt3sas_scsih_enclosure_find_by_handle - exclosure device search
+ * @ioc: per adapter object
+ * @handle: enclosure handle (assigned by firmware)
+ * Context: Calling function should acquire ioc->sas_device_lock
+ *
+ * This searches for enclosure device based on handle, then returns the
+ * enclosure object.
+ */
+static struct _enclosure_node *
+mpt3sas_scsih_enclosure_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+   struct _enclosure_node *enclosure_dev, *r;
+
+   r = NULL;
+   list_for_each_entry(enclosure_dev, &ioc->enclosure_list, list) {
+   if (le16_to_cpu(enclosure_dev->pg0.EnclosureHandle) != handle)
+   continue;
+   r = enclosure_dev;
+   goto out;
+   }
+out:
+   return r;
+}
+/**
  * mpt3sas_scsih_expander_find_by_sas_address - expander device

[PATCH v3 08/14] mpt3sas: Allow processing of events during driver unload.

2018-04-24 Thread Chaitra P B
Events were not processed during driver unload, hence unloading of driver
doesn't complete when drives are disconnected while unloading of driver.
So don't block events in ISR path, i,e., remove the flag ioc->remove_host
so that events are getting processed during driver unload.
Thus allowing driver unload to complete by processing drive removal events
during driver unload.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 796bf33..33587a8 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3677,11 +3677,7 @@ _scsih_tm_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 
smid, u8 msix_index,
u32 ioc_state;
struct _sc_list *delayed_sc;
 
-   if (ioc->remove_host) {
-   dewtprintk(ioc, pr_info(MPT3SAS_FMT
-   "%s: host has been removed\n", __func__, ioc->name));
-   return 1;
-   } else if (ioc->pci_error_recovery) {
+   if (ioc->pci_error_recovery) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: host in pci error recovery\n", __func__,
ioc->name));
@@ -3803,8 +3799,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
u16 smid;
struct _tr_list *delayed_tr;
 
-   if (ioc->shost_recovery || ioc->remove_host ||
-   ioc->pci_error_recovery) {
+   if (ioc->pci_error_recovery) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: host reset in progress!\n",
__func__, ioc->name));
@@ -3857,8 +3852,7 @@ _scsih_tm_volume_tr_complete(struct MPT3SAS_ADAPTER *ioc, 
u16 smid,
Mpi2SCSITaskManagementReply_t *mpi_reply =
mpt3sas_base_get_reply_virt_addr(ioc, reply);
 
-   if (ioc->shost_recovery || ioc->remove_host ||
-   ioc->pci_error_recovery) {
+   if (ioc->shost_recovery || ioc->pci_error_recovery) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: host reset in progress!\n",
__func__, ioc->name));
@@ -9468,8 +9462,8 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, 
u8 msix_index,
u16 sz;
Mpi26EventDataActiveCableExcept_t *ActiveCableEventData;
 
-   /* events turned off due to host reset or driver unloading */
-   if (ioc->remove_host || ioc->pci_error_recovery)
+   /* events turned off due to host reset */
+   if (ioc->pci_error_recovery)
return 1;
 
mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
-- 
1.8.3.1



[PATCH v3 03/14] mpt3sas: Lockless access for chain buffers.

2018-04-24 Thread Chaitra P B
Introduces Chain lookup table/tracker and implements accessing chain buffer
using smid.
Removed link list based access of chain buffer which requires lock and
allocated as many chains needed.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index b23a2eb..438da7c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -297,12 +297,15 @@ static void *
 _base_get_chain_buffer_dma_to_chain_buffer(struct MPT3SAS_ADAPTER *ioc,
dma_addr_t chain_buffer_dma)
 {
-   u16 index;
-
-   for (index = 0; index < ioc->chain_depth; index++) {
-   if (ioc->chain_lookup[index].chain_buffer_dma ==
-   chain_buffer_dma)
-   return ioc->chain_lookup[index].chain_buffer;
+   u16 index, j;
+   struct chain_tracker *ct;
+
+   for (index = 0; index < ioc->scsiio_depth; index++) {
+   for (j = 0; j < ioc->chains_needed_per_io; j++) {
+   ct = &ioc->chain_lookup[index].chains_per_smid[j];
+   if (ct && ct->chain_buffer_dma == chain_buffer_dma)
+   return ct->chain_buffer;
+   }
}
pr_info(MPT3SAS_FMT
"Provided chain_buffer_dma address is not in the lookup list\n",
@@ -1679,7 +1682,8 @@ _base_add_sg_single_64(void *paddr, u32 flags_length, 
dma_addr_t dma_addr)
  * @ioc: per adapter object
  * @scmd: SCSI commands of the IO request
  *
- * Returns chain tracker(from ioc->free_chain_list)
+ * Returns chain tracker from chain_lookup table using key as
+ * smid and smid's chain_offset.
  */
 static struct chain_tracker *
 _base_get_chain_buffer_tracker(struct MPT3SAS_ADAPTER *ioc,
@@ -1687,20 +1691,15 @@ _base_get_chain_buffer_tracker(struct MPT3SAS_ADAPTER 
*ioc,
 {
struct chain_tracker *chain_req;
struct scsiio_tracker *st = scsi_cmd_priv(scmd);
-   unsigned long flags;
+   u16 smid = st->smid;
+   u8 chain_offset =
+  atomic_read(&ioc->chain_lookup[smid - 1].chain_offset);
 
-   spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-   if (list_empty(&ioc->free_chain_list)) {
-   spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-   dfailprintk(ioc, pr_warn(MPT3SAS_FMT
-   "chain buffers not available\n", ioc->name));
+   if (chain_offset == ioc->chains_needed_per_io)
return NULL;
-   }
-   chain_req = list_entry(ioc->free_chain_list.next,
-   struct chain_tracker, tracker_list);
-   list_del_init(&chain_req->tracker_list);
-   list_add_tail(&chain_req->tracker_list, &st->chain_list);
-   spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
+
+   chain_req = &ioc->chain_lookup[smid - 1].chains_per_smid[chain_offset];
+   atomic_inc(&ioc->chain_lookup[smid - 1].chain_offset);
return chain_req;
 }
 
@@ -3278,13 +3277,7 @@ void mpt3sas_base_clear_st(struct MPT3SAS_ADAPTER *ioc,
return;
st->cb_idx = 0xFF;
st->direct_io = 0;
-   if (!list_empty(&st->chain_list)) {
-   unsigned long flags;
-
-   spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-   list_splice_init(&st->chain_list, &ioc->free_chain_list);
-   spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-   }
+   atomic_set(&ioc->chain_lookup[st->smid - 1].chain_offset, 0);
 }
 
 /**
@@ -4102,6 +4095,8 @@ static void
 _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 {
int i = 0;
+   int j = 0;
+   struct chain_tracker *ct;
struct reply_post_struct *rps;
 
dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
@@ -4192,14 +4187,18 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
kfree(ioc->hpr_lookup);
kfree(ioc->internal_lookup);
if (ioc->chain_lookup) {
-   for (i = 0; i < ioc->chain_depth; i++) {
-   if (ioc->chain_lookup[i].chain_buffer)
-   dma_pool_free(ioc->chain_dma_pool,
-   ioc->chain_lookup[i].chain_buffer,
-   ioc->chain_lookup[i].chain_buffer_dma);
+   for (i = 0; i < ioc->scsiio_depth; i++) {
+   for (j = 0; j < ioc->chains_needed_per_io; j++) {
+   ct = &ioc->chain_lookup[i].chains

[PATCH v3 11/14] mpt3sas: Update MPI Headers

2018-04-24 Thread Chaitra P B
Update MPI Files to support protocol level reset for NVMe device.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2.h  |  9 ++---
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 30 --
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |  7 ++-
 3 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h
index b015c30..1e45268 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2.h
@@ -9,7 +9,7 @@
  * scatter/gather formats.
  * Creation Date:  June 21, 2006
  *
- * mpi2.h Version:  02.00.48
+ *  mpi2.h Version:  02.00.50
  *
  * 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
@@ -114,6 +114,8 @@
  * 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.
+ * 06-13-17  02.00.49  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 09-29-17  02.00.50  Bumped MPI2_HEADER_VERSION_UNIT.
  * --
  */
 
@@ -152,8 +154,9 @@
MPI26_VERSION_MINOR)
 #define MPI2_VERSION_02_06 (0x0206)
 
-/*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT(0x30)
+
+/* Unit and Dev versioning for this MPI header set */
+#define MPI2_HEADER_VERSION_UNIT(0x32)
 #define MPI2_HEADER_VERSION_DEV (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK   (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT  (8)
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
index 0ad88de..5122920 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
@@ -7,7 +7,7 @@
  * Title:  MPI Configuration messages and pages
  * Creation Date:  November 10, 2006
  *
- *   mpi2_cnfg.h Version:  02.00.40
+ *mpi2_cnfg.h Version:  02.00.42
  *
  * 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
@@ -219,6 +219,18 @@
  * Added ChassisSlot field to SAS Enclosure Page 0.
  * Added ChassisSlot Valid bit (bit 5) to the Flags field
  * in SAS Enclosure Page 0.
+ * 06-13-17  02.00.41  Added MPI26_MFGPAGE_DEVID_SAS3816 and
+ * MPI26_MFGPAGE_DEVID_SAS3916 defines.
+ * Removed MPI26_MFGPAGE_DEVID_SAS4008 define.
+ * Added MPI26_PCIEIOUNIT1_LINKFLAGS_SRNS_EN define.
+ * Renamed PI26_PCIEIOUNIT1_LINKFLAGS_EN_SRIS to
+ * PI26_PCIEIOUNIT1_LINKFLAGS_SRIS_EN.
+ * Renamed MPI26_PCIEIOUNIT1_LINKFLAGS_DIS_SRIS to
+ * MPI26_PCIEIOUNIT1_LINKFLAGS_DIS_SEPARATE_REFCLK.
+ * 09-29-17  02.00.42  Added ControllerResetTO field to PCIe Device Page 2.
+ * Added NOIOB field to PCIe Device Page 2.
+ * Added MPI26_PCIEDEV2_CAP_DATA_BLK_ALIGN_AND_GRAN to
+ * the Capabilities field of PCIe Device Page 2.
  * --
  */
 
@@ -556,7 +568,8 @@ typedef struct _MPI2_CONFIG_REPLY {
 #define MPI26_MFGPAGE_DEVID_SAS3616 (0x00D1)
 #define MPI26_MFGPAGE_DEVID_SAS3708 (0x00D2)
 
-#define MPI26_MFGPAGE_DEVID_SAS4008 (0x00A1)
+#define MPI26_MFGPAGE_DEVID_SAS3816 (0x00A1)
+#define MPI26_MFGPAGE_DEVID_SAS3916 (0x00A0)
 
 
 /*Manufacturing Page 0 */
@@ -3864,20 +3877,25 @@ typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_0 {
 typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_2 {
MPI2_CONFIG_EXTENDED_PAGE_HEADERHeader; /*0x00 */
U16 DevHandle;  /*0x08 */
-   U16 Reserved1;  /*0x0A */
-   U32 MaximumDataTransferSize;/*0x0C */
+   U8  ControllerResetTO;  /* 0x0A */
+   U8  Reserved1;  /* 0x0B */
+   U32 MaximumDataTransferSize;/*0x0C */
U32 Capabilities;   /*0x10 */
-   U32 Reserved2;  /*0x14 */
+   U16 NOIOB;  /* 0x14 */
+   U16 Reserved2;  /* 0x16 */
 } MPI26_CONFIG_PAGE_PCIEDEV_2, *PTR_MPI26_CONFIG_PAGE_PCIEDEV_2,
Mpi26PCIeDevicePage2_t, *pMpi26PCIeDevicePage2_t;
 
-#define MPI26_PCIEDEVICE2_PAGEVERSION   (0x00)
+#define MPI26_PCIEDEVICE2_PAGEVERSION   (0x01)
 
 /*defines for PCIe Device Page 2 Capabilities field */
+#define MPI26_PCIEDEV2_CAP_DATA_BLK_ALIGN_AND_GRAN (0x0008)
 #define MPI26_PCIEDEV2_CAP_SGL_FORMAT  (0x0004)
 #define

[PATCH v2 11/14] mpt3sas: Update MPI Headers

2018-04-09 Thread Chaitra P B
Update MPI Files to support protocol level reset for NVMe device.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2.h  |  9 ++---
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 30 --
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |  7 ++-
 3 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h
index b015c30..1e45268 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2.h
@@ -9,7 +9,7 @@
  * scatter/gather formats.
  * Creation Date:  June 21, 2006
  *
- * mpi2.h Version:  02.00.48
+ *  mpi2.h Version:  02.00.50
  *
  * 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
@@ -114,6 +114,8 @@
  * 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.
+ * 06-13-17  02.00.49  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 09-29-17  02.00.50  Bumped MPI2_HEADER_VERSION_UNIT.
  * --
  */
 
@@ -152,8 +154,9 @@
MPI26_VERSION_MINOR)
 #define MPI2_VERSION_02_06 (0x0206)
 
-/*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT(0x30)
+
+/* Unit and Dev versioning for this MPI header set */
+#define MPI2_HEADER_VERSION_UNIT(0x32)
 #define MPI2_HEADER_VERSION_DEV (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK   (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT  (8)
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
index 0ad88de..5122920 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
@@ -7,7 +7,7 @@
  * Title:  MPI Configuration messages and pages
  * Creation Date:  November 10, 2006
  *
- *   mpi2_cnfg.h Version:  02.00.40
+ *mpi2_cnfg.h Version:  02.00.42
  *
  * 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
@@ -219,6 +219,18 @@
  * Added ChassisSlot field to SAS Enclosure Page 0.
  * Added ChassisSlot Valid bit (bit 5) to the Flags field
  * in SAS Enclosure Page 0.
+ * 06-13-17  02.00.41  Added MPI26_MFGPAGE_DEVID_SAS3816 and
+ * MPI26_MFGPAGE_DEVID_SAS3916 defines.
+ * Removed MPI26_MFGPAGE_DEVID_SAS4008 define.
+ * Added MPI26_PCIEIOUNIT1_LINKFLAGS_SRNS_EN define.
+ * Renamed PI26_PCIEIOUNIT1_LINKFLAGS_EN_SRIS to
+ * PI26_PCIEIOUNIT1_LINKFLAGS_SRIS_EN.
+ * Renamed MPI26_PCIEIOUNIT1_LINKFLAGS_DIS_SRIS to
+ * MPI26_PCIEIOUNIT1_LINKFLAGS_DIS_SEPARATE_REFCLK.
+ * 09-29-17  02.00.42  Added ControllerResetTO field to PCIe Device Page 2.
+ * Added NOIOB field to PCIe Device Page 2.
+ * Added MPI26_PCIEDEV2_CAP_DATA_BLK_ALIGN_AND_GRAN to
+ * the Capabilities field of PCIe Device Page 2.
  * --
  */
 
@@ -556,7 +568,8 @@ typedef struct _MPI2_CONFIG_REPLY {
 #define MPI26_MFGPAGE_DEVID_SAS3616 (0x00D1)
 #define MPI26_MFGPAGE_DEVID_SAS3708 (0x00D2)
 
-#define MPI26_MFGPAGE_DEVID_SAS4008 (0x00A1)
+#define MPI26_MFGPAGE_DEVID_SAS3816 (0x00A1)
+#define MPI26_MFGPAGE_DEVID_SAS3916 (0x00A0)
 
 
 /*Manufacturing Page 0 */
@@ -3864,20 +3877,25 @@ typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_0 {
 typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_2 {
MPI2_CONFIG_EXTENDED_PAGE_HEADERHeader; /*0x00 */
U16 DevHandle;  /*0x08 */
-   U16 Reserved1;  /*0x0A */
-   U32 MaximumDataTransferSize;/*0x0C */
+   U8  ControllerResetTO;  /* 0x0A */
+   U8  Reserved1;  /* 0x0B */
+   U32 MaximumDataTransferSize;/*0x0C */
U32 Capabilities;   /*0x10 */
-   U32 Reserved2;  /*0x14 */
+   U16 NOIOB;  /* 0x14 */
+   U16 Reserved2;  /* 0x16 */
 } MPI26_CONFIG_PAGE_PCIEDEV_2, *PTR_MPI26_CONFIG_PAGE_PCIEDEV_2,
Mpi26PCIeDevicePage2_t, *pMpi26PCIeDevicePage2_t;
 
-#define MPI26_PCIEDEVICE2_PAGEVERSION   (0x00)
+#define MPI26_PCIEDEVICE2_PAGEVERSION   (0x01)
 
 /*defines for PCIe Device Page 2 Capabilities field */
+#define MPI26_PCIEDEV2_CAP_DATA_BLK_ALIGN_AND_GRAN (0x0008)
 #define MPI26_PCIEDEV2_CAP_SGL_FORMAT  (0x0004)
 #define

[PATCH v2 08/14] mpt3sas: Allow processing of events during driver unload.

2018-04-09 Thread Chaitra P B
Events were not processed during driver unload, hence unloading of driver
doesn't complete when drives are disconnected while unloading of driver.
So don't block events in ISR path, i,e., remove the flag ioc->remove_host
so that events are getting processed during driver unload.
Thus allowing driver unload to complete by processing drive removal events
during driver unload.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 796bf33..33587a8 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3677,11 +3677,7 @@ _scsih_tm_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 
smid, u8 msix_index,
u32 ioc_state;
struct _sc_list *delayed_sc;
 
-   if (ioc->remove_host) {
-   dewtprintk(ioc, pr_info(MPT3SAS_FMT
-   "%s: host has been removed\n", __func__, ioc->name));
-   return 1;
-   } else if (ioc->pci_error_recovery) {
+   if (ioc->pci_error_recovery) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: host in pci error recovery\n", __func__,
ioc->name));
@@ -3803,8 +3799,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
u16 smid;
struct _tr_list *delayed_tr;
 
-   if (ioc->shost_recovery || ioc->remove_host ||
-   ioc->pci_error_recovery) {
+   if (ioc->pci_error_recovery) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: host reset in progress!\n",
__func__, ioc->name));
@@ -3857,8 +3852,7 @@ _scsih_tm_volume_tr_complete(struct MPT3SAS_ADAPTER *ioc, 
u16 smid,
Mpi2SCSITaskManagementReply_t *mpi_reply =
mpt3sas_base_get_reply_virt_addr(ioc, reply);
 
-   if (ioc->shost_recovery || ioc->remove_host ||
-   ioc->pci_error_recovery) {
+   if (ioc->shost_recovery || ioc->pci_error_recovery) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: host reset in progress!\n",
__func__, ioc->name));
@@ -9468,8 +9462,8 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, 
u8 msix_index,
u16 sz;
Mpi26EventDataActiveCableExcept_t *ActiveCableEventData;
 
-   /* events turned off due to host reset or driver unloading */
-   if (ioc->remove_host || ioc->pci_error_recovery)
+   /* events turned off due to host reset */
+   if (ioc->pci_error_recovery)
return 1;
 
mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
-- 
1.8.3.1



[PATCH v2 02/14] mpt3sas: Pre-allocate RDPQ Array at driver boot time.

2018-04-09 Thread Chaitra P B
Instead of allocating RDPQ array (This stores the address's of each RDPQ
pools) at run time, now it will be allocated once during driver load time
and same will be reused during host reset operation also (instead of
allocating & freeing this buffer on the fly during every host reset
operation) and then freed during driver unload.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 4767690..a79c6df 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4159,7 +4159,14 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
}
} while (ioc->rdpq_array_enable &&
   (++i < ioc->reply_queue_count));
-
+   if (ioc->reply_post_free_array &&
+   ioc->rdpq_array_enable) {
+   dma_pool_free(ioc->reply_post_free_array_dma_pool,
+   ioc->reply_post_free_array,
+   ioc->reply_post_free_array_dma);
+   ioc->reply_post_free_array = NULL;
+   }
+   dma_pool_destroy(ioc->reply_post_free_array_dma_pool);
dma_pool_destroy(ioc->reply_post_free_dma_pool);
kfree(ioc->reply_post);
}
@@ -4209,7 +4216,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
struct mpt3sas_facts *facts;
u16 max_sge_elements;
u16 chains_needed_per_io;
-   u32 sz, total_sz, reply_post_free_sz;
+   u32 sz, total_sz, reply_post_free_sz, reply_post_free_array_sz;
u32 retry_sz;
u16 max_request_credit, nvme_blocks_needed;
unsigned short sg_tablesize;
@@ -4681,6 +4688,28 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->name, (unsigned long long)ioc->reply_free_dma));
total_sz += sz;
 
+   if (ioc->rdpq_array_enable) {
+   reply_post_free_array_sz = ioc->reply_queue_count *
+   sizeof(Mpi2IOCInitRDPQArrayEntry);
+   ioc->reply_post_free_array_dma_pool =
+   dma_pool_create("reply_post_free_array pool",
+   &ioc->pdev->dev, reply_post_free_array_sz, 16, 0);
+   if (!ioc->reply_post_free_array_dma_pool) {
+   dinitprintk(ioc,
+   pr_info(MPT3SAS_FMT "reply_post_free_array pool: "
+   "dma_pool_create failed\n", ioc->name));
+   goto out;
+   }
+   ioc->reply_post_free_array =
+   dma_pool_alloc(ioc->reply_post_free_array_dma_pool,
+   GFP_KERNEL, &ioc->reply_post_free_array_dma);
+   if (!ioc->reply_post_free_array) {
+   dinitprintk(ioc,
+   pr_info(MPT3SAS_FMT "reply_post_free_array pool: "
+   "dma_pool_alloc failed\n", ioc->name));
+   goto out;
+   }
+   }
ioc->config_page_sz = 512;
ioc->config_page = pci_alloc_consistent(ioc->pdev,
ioc->config_page_sz, &ioc->config_page_dma);
@@ -5487,8 +5516,6 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc)
ktime_t current_time;
u16 ioc_status;
u32 reply_post_free_array_sz = 0;
-   Mpi2IOCInitRDPQArrayEntry *reply_post_free_array = NULL;
-   dma_addr_t reply_post_free_array_dma;
 
dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
__func__));
@@ -5522,23 +5549,14 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc)
if (ioc->rdpq_array_enable) {
reply_post_free_array_sz = ioc->reply_queue_count *
sizeof(Mpi2IOCInitRDPQArrayEntry);
-   reply_post_free_array = pci_alloc_consistent(ioc->pdev,
-   reply_post_free_array_sz, &reply_post_free_array_dma);
-   if (!reply_post_free_array) {
-   pr_err(MPT3SAS_FMT
-   "reply_post_free_array: pci_alloc_consistent failed\n",
-   ioc->name);
-   r = -ENOMEM;
-   goto out;
-   }
-   memset(reply_post_free_array, 0, reply_post_free_array_sz);
+   memset(ioc->reply_post_free_array, 0, reply_post_free_array_sz);
for (i = 0; i < ioc->reply_queue_count; i++)
-   reply_post_free_array[i].RDPQBaseAddress =

[PATCH v2 00/14] mpt3sas: Enhancements and Defect fixes.

2018-04-09 Thread Chaitra P B
Chaitra P B (14):
  mpt3sas: Bug fix for big endian systems.
  mpt3sas: Pre-allocate RDPQ Array at driver boot time.
  mpt3sas: Lockless access for chain buffers.
  mpt3sas: Optimize I/O memory consumption in driver.
  mpt3sas: Enhanced handling of Sense Buffer.
  mpt3sas: Added support for SAS Device Discovery Error Event.
  mpt3sas: Increase event log buffer to support 24 port HBA's.
  mpt3sas: Allow processing of events during driver unload.
  mpt3sas: Cache enclosure pages during enclosure add.
  mpt3sas: Report Firmware Package Version from HBA Driver.
  mpt3sas: Update MPI Headers
  mpt3sas: For NVME device, issue a protocol level reset instead of
hot reset and use TM timeout value exposed in PCIe Device Page 2.
  mpt3sas: fix possible memory leak.
  mpt3sas: Update driver version "25.100.00.00"

 drivers/scsi/mpt3sas/mpi/mpi2.h  |   9 +-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  30 +-
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |   2 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |   7 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 477 +++---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  62 +++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  33 ++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.h   |   2 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 491 +--
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |   3 +-
 10 files changed, 818 insertions(+), 298 deletions(-)

-- 
1.8.3.1



[PATCH v2 14/14] mpt3sas: Update driver version "25.100.00.00"

2018-04-09 Thread Chaitra P B
Update driver version to match OOB/internal driver version.

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 6a9657e..693b04b 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 "17.100.00.00"
-#define MPT3SAS_MAJOR_VERSION  17
+#define MPT3SAS_DRIVER_VERSION "25.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  25
 #define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
-- 
1.8.3.1



[PATCH v2 03/14] mpt3sas: Lockless access for chain buffers.

2018-04-09 Thread Chaitra P B
Introduces Chain lookup table/tracker and implements accessing chain buffer
using smid.
Removed link list based access of chain buffer which requires lock and
allocated as many chains needed.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index a79c6df..1e8e399 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -297,12 +297,15 @@ static void *
 _base_get_chain_buffer_dma_to_chain_buffer(struct MPT3SAS_ADAPTER *ioc,
dma_addr_t chain_buffer_dma)
 {
-   u16 index;
-
-   for (index = 0; index < ioc->chain_depth; index++) {
-   if (ioc->chain_lookup[index].chain_buffer_dma ==
-   chain_buffer_dma)
-   return ioc->chain_lookup[index].chain_buffer;
+   u16 index, j;
+   struct chain_tracker *ct;
+
+   for (index = 0; index < ioc->scsiio_depth; index++) {
+   for (j = 0; j < ioc->chains_needed_per_io; j++) {
+   ct = &ioc->chain_lookup[index].chains_per_smid[j];
+   if (ct && ct->chain_buffer_dma == chain_buffer_dma)
+   return ct->chain_buffer;
+   }
}
pr_info(MPT3SAS_FMT
"Provided chain_buffer_dma address is not in the lookup list\n",
@@ -1678,7 +1681,8 @@ _base_add_sg_single_64(void *paddr, u32 flags_length, 
dma_addr_t dma_addr)
  * @ioc: per adapter object
  * @scmd: SCSI commands of the IO request
  *
- * Returns chain tracker(from ioc->free_chain_list)
+ * Returns chain tracker from chain_lookup table using key as
+ * smid and smid's chain_offset.
  */
 static struct chain_tracker *
 _base_get_chain_buffer_tracker(struct MPT3SAS_ADAPTER *ioc,
@@ -1686,20 +1690,15 @@ _base_get_chain_buffer_tracker(struct MPT3SAS_ADAPTER 
*ioc,
 {
struct chain_tracker *chain_req;
struct scsiio_tracker *st = scsi_cmd_priv(scmd);
-   unsigned long flags;
+   u16 smid = st->smid;
+   u8 chain_offset =
+  atomic_read(&ioc->chain_lookup[smid - 1].chain_offset);
 
-   spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-   if (list_empty(&ioc->free_chain_list)) {
-   spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-   dfailprintk(ioc, pr_warn(MPT3SAS_FMT
-   "chain buffers not available\n", ioc->name));
+   if (chain_offset == ioc->chains_needed_per_io)
return NULL;
-   }
-   chain_req = list_entry(ioc->free_chain_list.next,
-   struct chain_tracker, tracker_list);
-   list_del_init(&chain_req->tracker_list);
-   list_add_tail(&chain_req->tracker_list, &st->chain_list);
-   spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
+
+   chain_req = &ioc->chain_lookup[smid - 1].chains_per_smid[chain_offset];
+   atomic_inc(&ioc->chain_lookup[smid - 1].chain_offset);
return chain_req;
 }
 
@@ -3278,13 +3277,7 @@ void mpt3sas_base_clear_st(struct MPT3SAS_ADAPTER *ioc,
return;
st->cb_idx = 0xFF;
st->direct_io = 0;
-   if (!list_empty(&st->chain_list)) {
-   unsigned long flags;
-
-   spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-   list_splice_init(&st->chain_list, &ioc->free_chain_list);
-   spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-   }
+   atomic_set(&ioc->chain_lookup[st->smid - 1].chain_offset, 0);
 }
 
 /**
@@ -4102,6 +4095,8 @@ static void
 _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 {
int i = 0;
+   int j = 0;
+   struct chain_tracker *ct;
struct reply_post_struct *rps;
 
dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
@@ -4192,14 +4187,18 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
kfree(ioc->hpr_lookup);
kfree(ioc->internal_lookup);
if (ioc->chain_lookup) {
-   for (i = 0; i < ioc->chain_depth; i++) {
-   if (ioc->chain_lookup[i].chain_buffer)
-   dma_pool_free(ioc->chain_dma_pool,
-   ioc->chain_lookup[i].chain_buffer,
-   ioc->chain_lookup[i].chain_buffer_dma);
+   for (i = 0; i < ioc->scsiio_depth; i++) {
+   for (j = 0; j < ioc->chains_needed_per_io; j++) {
+   ct = &ioc->chain_lookup[i].chains

[PATCH v2 05/14] mpt3sas: Enhanced handling of Sense Buffer.

2018-04-09 Thread Chaitra P B
Enhanced DMA allocation for Sense Buffer, if the allocation does not fit
within same 4GB.Introduced is_MSB_are_same function to check if allocted
buffer within 4GB range or not.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 56 +
 1 file changed, 56 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 701e1e7..bd1beaf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4205,6 +4205,31 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * is_MSB_are_same - checks whether all reply queues in a set are
+ * having same upper 32bits in their base memory address.
+ * @reply_pool_start_address: Base address of a reply queue set
+ * @pool_sz: Size of single Reply Descriptor Post Queues pool size
+ *
+ * Returns 1 if reply queues in a set have a same upper 32bits
+ * in their base memory address,
+ * else 0
+ */
+
+static int
+is_MSB_are_same(long reply_pool_start_address, u32 pool_sz)
+{
+   long reply_pool_end_address;
+
+   reply_pool_end_address = reply_pool_start_address + pool_sz;
+
+   if (upper_32_bits(reply_pool_start_address) ==
+   upper_32_bits(reply_pool_end_address))
+   return 1;
+   else
+   return 0;
+}
+
+/**
  * _base_allocate_memory_pools - allocate start of day memory pools
  * @ioc: per adapter object
  *
@@ -4664,6 +4689,37 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->name);
goto out;
}
+   /* sense buffer requires to be in same 4 gb region.
+* Below function will check the same.
+* In case of failure, new pci pool will be created with updated
+* alignment. Older allocation and pool will be destroyed.
+* Alignment will be used such a way that next allocation if
+* success, will always meet same 4gb region requirement.
+* Actual requirement is not alignment, but we need start and end of
+* DMA address must have same upper 32 bit address.
+*/
+   if (!is_MSB_are_same((long)ioc->sense, sz)) {
+   //Release Sense pool & Reallocate
+   dma_pool_free(ioc->sense_dma_pool, ioc->sense, ioc->sense_dma);
+   dma_pool_destroy(ioc->sense_dma_pool);
+   ioc->sense = NULL;
+
+   ioc->sense_dma_pool =
+   dma_pool_create("sense pool", &ioc->pdev->dev, sz,
+   roundup_pow_of_two(sz), 0);
+   if (!ioc->sense_dma_pool) {
+   pr_err(MPT3SAS_FMT "sense pool: pci_pool_create 
failed\n",
+   ioc->name);
+   goto out;
+   }
+   ioc->sense = dma_pool_alloc(ioc->sense_dma_pool, GFP_KERNEL,
+   &ioc->sense_dma);
+   if (!ioc->sense) {
+   pr_err(MPT3SAS_FMT "sense pool: pci_pool_alloc 
failed\n",
+   ioc->name);
+   goto out;
+   }
+   }
dinitprintk(ioc, pr_info(MPT3SAS_FMT
"sense pool(0x%p): depth(%d), element_size(%d), pool_size"
"(%d kB)\n", ioc->name, ioc->sense, ioc->scsiio_depth,
-- 
1.8.3.1



[PATCH v2 13/14] mpt3sas: fix possible memory leak.

2018-04-09 Thread Chaitra P B
In ioctl exit path driver refers ioc_list to free memory associated with
diag buffers and event_log pointer used to save events by driver.
If ctl_exit() func is called after unregistering driver, then ioc_list will
be empty and hence driver will not be able to free the allocated memory
which in turn causes memory leak.
So call ctl_exit() function before unregistering mpt3sas driver.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 8ba72a2..8fc2922 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -11276,10 +11276,10 @@ _mpt3sas_exit(void)
pr_info("mpt3sas version %s unloading\n",
MPT3SAS_DRIVER_VERSION);
 
-   pci_unregister_driver(&mpt3sas_driver);
-
mpt3sas_ctl_exit(hbas_to_enumerate);
 
+   pci_unregister_driver(&mpt3sas_driver);
+
scsih_exit();
 }
 
-- 
1.8.3.1



[PATCH v2 06/14] mpt3sas: Added support for SAS Device Discovery Error Event.

2018-04-09 Thread Chaitra P B
The SAS Device Discovery Error Event is sent to the host when
discovery for a particular device is failed during discovery,
even after maximum retries by the IOC.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  4 
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 42 
 2 files changed, 46 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index bd1beaf..f9bacd2 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1029,6 +1029,9 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
desc = "Cable Event";
break;
+   case MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
+   desc = "SAS Device Discovery Error";
+   break;
case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
desc = "PCIE Device Status Change";
break;
@@ -6596,6 +6599,7 @@ 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);
+   _base_unmask_events(ioc, MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR);
if (ioc->hba_mpi_version_belonged == MPI26_VERSION) {
if (ioc->is_gen35_ioc) {
_base_unmask_events(ioc,
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index c9cce65..796bf33 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -7524,6 +7524,44 @@ _scsih_sas_discovery_event(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _scsih_sas_device_discovery_error_event - display SAS device discovery error
+ * events
+ * @ioc: per adapter object
+ * @fw_event: The fw_event_work object
+ * Context: user.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_sas_device_discovery_error_event(struct MPT3SAS_ADAPTER *ioc,
+   struct fw_event_work *fw_event)
+{
+   Mpi25EventDataSasDeviceDiscoveryError_t *event_data =
+   (Mpi25EventDataSasDeviceDiscoveryError_t *)fw_event->event_data;
+
+   switch (event_data->ReasonCode) {
+   case MPI25_EVENT_SAS_DISC_ERR_SMP_FAILED:
+   pr_warn(MPT3SAS_FMT "SMP command sent to the expander"
+   "(handle:0x%04x, sas_address:0x%016llx,"
+   "physical_port:0x%02x) has failed",
+   ioc->name, le16_to_cpu(event_data->DevHandle),
+   (unsigned long long)le64_to_cpu(event_data->SASAddress),
+   event_data->PhysicalPort);
+   break;
+   case MPI25_EVENT_SAS_DISC_ERR_SMP_TIMEOUT:
+   pr_warn(MPT3SAS_FMT "SMP command sent to the expander"
+   "(handle:0x%04x, sas_address:0x%016llx,"
+   "physical_port:0x%02x) has timed out",
+   ioc->name, le16_to_cpu(event_data->DevHandle),
+   (unsigned long long)le64_to_cpu(event_data->SASAddress),
+   event_data->PhysicalPort);
+   break;
+   default:
+   break;
+   }
+}
+
+/**
  * _scsih_pcie_enumeration_event - handle enumeration events
  * @ioc: per adapter object
  * @fw_event: The fw_event_work object
@@ -9350,6 +9388,9 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct 
fw_event_work *fw_event)
case MPI2_EVENT_SAS_DISCOVERY:
_scsih_sas_discovery_event(ioc, fw_event);
break;
+   case MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
+   _scsih_sas_device_discovery_error_event(ioc, fw_event);
+   break;
case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
_scsih_sas_broadcast_primitive_event(ioc, fw_event);
break;
@@ -9534,6 +9575,7 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, 
u8 msix_index,
case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
case MPI2_EVENT_IR_OPERATION_STATUS:
case MPI2_EVENT_SAS_DISCOVERY:
+   case MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
case MPI2_EVENT_IR_PHYSICAL_DISK:
case MPI2_EVENT_PCIE_ENUMERATION:
-- 
1.8.3.1



[PATCH v2 10/14] mpt3sas: Report Firmware Package Version from HBA Driver.

2018-04-09 Thread Chaitra P B
Added function _base_display_fwpkg_version, which sends FWUpload
request to pull FW package version from FW Image Header.
Now driver prints FW package version in addition to FW
version if the PackageVersion is valid.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index fccf5d1..7f438be 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -3825,6 +3825,105 @@ _base_display_OEMs_branding(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * _base_display_fwpkg_version - sends FWUpload request to pull FWPkg
+ * version from FW Image Header.
+ * @ioc: per adapter object
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+   static int
+_base_display_fwpkg_version(struct MPT3SAS_ADAPTER *ioc)
+{
+   Mpi2FWImageHeader_t *FWImgHdr;
+   Mpi25FWUploadRequest_t *mpi_request;
+   Mpi2FWUploadReply_t mpi_reply;
+   int r = 0;
+   void *fwpkg_data = NULL;
+   dma_addr_t fwpkg_data_dma;
+   u16 smid, ioc_status;
+   size_t data_length;
+
+   dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+   __func__));
+
+   if (ioc->base_cmds.status & MPT3_CMD_PENDING) {
+   pr_err(MPT3SAS_FMT "%s: internal command already in use\n",
+   ioc->name, __func__);
+   return -EAGAIN;
+   }
+
+   data_length = sizeof(Mpi2FWImageHeader_t);
+   fwpkg_data = pci_alloc_consistent(ioc->pdev, data_length,
+   &fwpkg_data_dma);
+   if (!fwpkg_data) {
+   pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
+   ioc->name, __FILE__, __LINE__, __func__);
+   return -ENOMEM;
+   }
+
+   smid = mpt3sas_base_get_smid(ioc, ioc->base_cb_idx);
+   if (!smid) {
+   pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
+   ioc->name, __func__);
+   r = -EAGAIN;
+   goto out;
+   }
+
+   ioc->base_cmds.status = MPT3_CMD_PENDING;
+   mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
+   ioc->base_cmds.smid = smid;
+   memset(mpi_request, 0, sizeof(Mpi25FWUploadRequest_t));
+   mpi_request->Function = MPI2_FUNCTION_FW_UPLOAD;
+   mpi_request->ImageType = MPI2_FW_UPLOAD_ITYPE_FW_FLASH;
+   mpi_request->ImageSize = cpu_to_le32(data_length);
+   ioc->build_sg(ioc, &mpi_request->SGL, 0, 0, fwpkg_data_dma,
+   data_length);
+   init_completion(&ioc->base_cmds.done);
+   mpt3sas_base_put_smid_default(ioc, smid);
+   /* Wait for 15 seconds */
+   wait_for_completion_timeout(&ioc->base_cmds.done,
+   FW_IMG_HDR_READ_TIMEOUT*HZ);
+   pr_info(MPT3SAS_FMT "%s: complete\n",
+   ioc->name, __func__);
+   if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) {
+   pr_err(MPT3SAS_FMT "%s: timeout\n",
+   ioc->name, __func__);
+   _debug_dump_mf(mpi_request,
+   sizeof(Mpi25FWUploadRequest_t)/4);
+   r = -ETIME;
+   } else {
+   memset(&mpi_reply, 0, sizeof(Mpi2FWUploadReply_t));
+   if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) {
+   memcpy(&mpi_reply, ioc->base_cmds.reply,
+   sizeof(Mpi2FWUploadReply_t));
+   ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+   MPI2_IOCSTATUS_MASK;
+   if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
+   FWImgHdr = (Mpi2FWImageHeader_t *)fwpkg_data;
+   if (FWImgHdr->PackageVersion.Word) {
+   pr_info(MPT3SAS_FMT "FW Package Version"
+   "(%02d.%02d.%02d.%02d)\n",
+   ioc->name,
+   FWImgHdr->PackageVersion.Struct.Major,
+   FWImgHdr->PackageVersion.Struct.Minor,
+   FWImgHdr->PackageVersion.Struct.Unit,
+   FWImgHdr->PackageVersion.Struct.Dev);
+   }
+   } else {
+   _debug_dump_mf(&mpi_reply,
+   sizeof(Mpi2FWUploadR

[PATCH v2 12/14] mpt3sas: For NVME device, issue a protocol level reset instead of hot reset and use TM timeout value exposed in PCIe Device Page 2.

2018-04-09 Thread Chaitra P B
1)Manufacturing Page 11 contains parameters to control
internal firmware behavior. Based on AddlFlags2 field
FW/Driver behaviour can be changed, (flag tm_custom_handling
is used for this)

a) For PCIe device, protocol level reset should be used if
flag tm_custom_handling is 0.
Since Abort Task Set, LUN reset and Target reset will result
in a protocol level reset. Drivers should issue only one type
of this reset, if that fails then it should escalate to a controller
reset (diag reset/OCR).
b) If the driver has control over the TM reset timeout value, then
driver should use the value exposed in PCIe Device Page 2 for pcie device
(field ControllerResetTO).

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 13 ++
 drivers/scsi/mpt3sas/mpt3sas_base.h  | 26 ++--
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 22 +--
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 76 ++--
 4 files changed, 116 insertions(+), 21 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 7f438be..eaeace0 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4139,6 +4139,7 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
Mpi2ConfigReply_t mpi_reply;
u32 iounit_pg1_flags;
 
+   ioc->nvme_abort_timeout = 30;
mpt3sas_config_get_manufacturing_pg0(ioc, &mpi_reply, &ioc->manu_pg0);
if (ioc->ir_firmware)
mpt3sas_config_get_manufacturing_pg10(ioc, &mpi_reply,
@@ -4157,6 +4158,18 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
mpt3sas_config_set_manufacturing_pg11(ioc, &mpi_reply,
&ioc->manu_pg11);
}
+   if (ioc->manu_pg11.AddlFlags2 & NVME_TASK_MNGT_CUSTOM_MASK)
+   ioc->tm_custom_handling = 1;
+   else {
+   ioc->tm_custom_handling = 0;
+   if (ioc->manu_pg11.NVMeAbortTO < NVME_TASK_ABORT_MIN_TIMEOUT)
+   ioc->nvme_abort_timeout = NVME_TASK_ABORT_MIN_TIMEOUT;
+   else if (ioc->manu_pg11.NVMeAbortTO >
+   NVME_TASK_ABORT_MAX_TIMEOUT)
+   ioc->nvme_abort_timeout = NVME_TASK_ABORT_MAX_TIMEOUT;
+   else
+   ioc->nvme_abort_timeout = ioc->manu_pg11.NVMeAbortTO;
+   }
 
mpt3sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2);
mpt3sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 20fe90d..6a9657e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -146,8 +146,12 @@
 #defineNVME_CMD_PRP1_OFFSET24  /* PRP1 offset in NVMe 
cmd */
 #defineNVME_CMD_PRP2_OFFSET32  /* PRP2 offset in NVMe 
cmd */
 #defineNVME_ERROR_RESPONSE_SIZE16  /* Max NVME Error 
Response */
+#define NVME_TASK_ABORT_MIN_TIMEOUT6
+#define NVME_TASK_ABORT_MAX_TIMEOUT60
+#define NVME_TASK_MNGT_CUSTOM_MASK (0x0010)
 #defineNVME_PRP_PAGE_SIZE  4096/* Page size */
 
+
 /*
  * reset phases
  */
@@ -363,7 +367,15 @@ struct Mpi2ManufacturingPage11_t {
u8  EEDPTagMode;/* 09h */
u8  Reserved3;  /* 0Ah */
u8  Reserved4;  /* 0Bh */
-   __le32  Reserved5[23];  /* 0Ch-60h*/
+   __le32  Reserved5[8];   /* 0Ch-2Ch */
+   u16 AddlFlags2; /* 2Ch */
+   u8  AddlFlags3; /* 2Eh */
+   u8  Reserved6;  /* 2Fh */
+   __le32  Reserved7[7];   /* 30h - 4Bh */
+   u8  NVMeAbortTO;/* 4Ch */
+   u8  Reserved8;  /* 4Dh */
+   u16 Reserved9;  /* 4Eh */
+   __le32  Reserved10[4];  /* 50h - 60h */
 };
 
 /**
@@ -573,6 +585,7 @@ struct _pcie_device {
u8  enclosure_level;
u8  connector_name[4];
u8  *serial_number;
+   u8  reset_timeout;
struct kref refcount;
 };
 /**
@@ -1211,6 +1224,10 @@ struct MPT3SAS_ADAPTER {
void*event_log;
u32 event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
 
+   u8  tm_custom_handling;
+   u8  nvme_abort_timeout;
+
+
/* static config pages */
struct mpt3sas_facts facts;
struct mpt3sas_port_facts *pfacts;
@@ -1470,10 +1487,11 @@ u8 mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER 
*ioc, u8 msix_index,
u32 reply);
 void mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase);

[PATCH v2 04/14] mpt3sas: Optimize I/O memory consumption in driver.

2018-04-09 Thread Chaitra P B
For every IO, memory of PAGE size is allocated for handling NVMe native
PRPS. And in addition to that for every IO (chains need per IO * chain
buffer size, e.g. 38 * 128byte) amount of memory is allocated for chain
buffers.

However, at any point of time; the IO request can be for NVMe target device
(where PRP's page is used for framing PRP's) or can be for SCSI target
device (where chain buffers are used for framing chain SGE's). This patch
modifies the driver to reuse same pre-allocated PRP page buffers as a chain
buffer for IO's targeted for SCSI target devices. No need to allocate
separate buffers for chain SGE's buffers.

Suppose if the number of chain buffers need for IO doesn't fit in the PRP
Page size then driver maintain's separate buffers for those extra chain
buffers that exceeds the PRP page size. For example consider PRP page size
as 4K and chain buffer size as 128 bytes, then number of chain buffers that
can fit in PRP page is 4096/128 => 32. if the number of chain buffer need
per IO exceeds 32; for example consider number of chains need per IO is 36
then for remaining 4 chain buffer's driver allocates them individual.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 1e8e399..701e1e7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4188,7 +4188,8 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
kfree(ioc->internal_lookup);
if (ioc->chain_lookup) {
for (i = 0; i < ioc->scsiio_depth; i++) {
-   for (j = 0; j < ioc->chains_needed_per_io; j++) {
+   for (j = ioc->chains_per_prp_buffer;
+   j < ioc->chains_needed_per_io; j++) {
ct = &ioc->chain_lookup[i].chains_per_smid[j];
if (ct && ct->chain_buffer)
dma_pool_free(ioc->chain_dma_pool,
@@ -4506,7 +4507,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->chain_lookup = kzalloc(sz, GFP_KERNEL);
if (!ioc->chain_lookup) {
pr_err(MPT3SAS_FMT "chain_lookup: __get_free_pages "
-   "failed\n", ioc->name);
+   "failed\n", ioc->name);
goto out;
}
 
@@ -4520,33 +4521,6 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
}
}
 
-   ioc->chain_dma_pool = dma_pool_create("chain pool", &ioc->pdev->dev,
-   ioc->chain_segment_sz, 16, 0);
-   if (!ioc->chain_dma_pool) {
-   pr_err(MPT3SAS_FMT "chain_dma_pool: dma_pool_create failed\n",
-   ioc->name);
-   goto out;
-   }
-   for (i = 0; i < ioc->scsiio_depth; i++) {
-   for (j = 0; j < ioc->chains_needed_per_io; j++) {
-   ct = &ioc->chain_lookup[i].chains_per_smid[j];
-   ct->chain_buffer = dma_pool_alloc(
-   ioc->chain_dma_pool , GFP_KERNEL,
-   &ct->chain_buffer_dma);
-   if (!ct->chain_buffer) {
-   pr_err(MPT3SAS_FMT "chain_lookup: "
-   " pci_pool_alloc failed\n", ioc->name);
-   goto out;
-   }
-   }
-   total_sz += ioc->chain_segment_sz;
-   }
-
-   dinitprintk(ioc, pr_info(MPT3SAS_FMT
-   "chain pool depth(%d), frame_size(%d), pool_size(%d kB)\n",
-   ioc->name, ioc->chain_depth, ioc->chain_segment_sz,
-   ((ioc->chain_depth *  ioc->chain_segment_sz))/1024));
-
/* initialize hi-priority queue smid's */
ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth,
sizeof(struct request_tracker), GFP_KERNEL);
@@ -4587,6 +4561,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 * be required for NVMe PRP's, only each set of NVMe blocks will be
 * contiguous, so a new set is allocated for each possible I/O.
 */
+   ioc->chains_per_prp_buffer = 0;
if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_NVME_DEVICES) {
nvme_blocks_needed =
(ioc->shost->sg_tablesize * NVME_PRP_SIZE) - 1;
@@ -4609,6 +4584,11 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->name);
goto out;
  

[PATCH v2 09/14] mpt3sas: Cache enclosure pages during enclosure add.

2018-04-09 Thread Chaitra P B
In function _scsih_add_device,
for each device connected to an enclosure, driver reads the
enclosure page(To get details like enclosure handle,
enclosure logical ID, enclosure level etc.)

With this patch, instead of reading enclosure page everytime,
driver maintains a list for enclosure device(During enclosure
add event, enclosure device is added to the list and removed
from the list on delete events) and uses the enclosure page
from the list.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  22 +++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  14 ++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 296 +++
 3 files changed, 236 insertions(+), 96 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index f9bacd2..fccf5d1 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4087,6 +4087,27 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * mpt3sas_free_enclosure_list - release memory
+ * @ioc: per adapter object
+ *
+ * Free memory allocated during encloure add.
+ *
+ * Return nothing.
+ */
+void
+mpt3sas_free_enclosure_list(struct MPT3SAS_ADAPTER *ioc)
+{
+   struct _enclosure_node *enclosure_dev, *enclosure_dev_next;
+
+   /* Free enclosure list */
+   list_for_each_entry_safe(enclosure_dev,
+   enclosure_dev_next, &ioc->enclosure_list, list) {
+   list_del(&enclosure_dev->list);
+   kfree(enclosure_dev);
+   }
+}
+
+/**
  * _base_release_memory_pools - release memory
  * @ioc: per adapter object
  *
@@ -,6 +6687,7 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc)
mpt3sas_base_stop_watchdog(ioc);
mpt3sas_base_free_resources(ioc);
_base_release_memory_pools(ioc);
+   mpt3sas_free_enclosure_list(ioc);
pci_set_drvdata(ioc->pdev, NULL);
kfree(ioc->cpu_msix_table);
if (ioc->is_warpdrive)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index a0fca8a..6f3329e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -741,6 +741,17 @@ struct _sas_node {
struct list_head sas_port_list;
 };
 
+
+/**
+ * struct _enclosure_node - enclosure information
+ * @list: list of enclosures
+ * @pg0: enclosure pg0;
+ */
+struct _enclosure_node {
+   struct list_head list;
+   Mpi2SasEnclosurePage0_t pg0;
+};
+
 /**
  * enum reset_type - reset state
  * @FORCE_BIG_HAMMER: issue diagnostic reset
@@ -1013,6 +1024,7 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct 
MPT3SAS_ADAPTER *ioc);
  * @iounit_pg8: static iounit page 8
  * @sas_hba: sas host object
  * @sas_expander_list: expander object list
+ * @enclosure_list: enclosure object list
  * @sas_node_lock:
  * @sas_device_list: sas device object list
  * @sas_device_init_list: sas device object list (used only at init time)
@@ -1218,6 +1230,7 @@ struct MPT3SAS_ADAPTER {
/* sas hba, expander, and device list */
struct _sas_node sas_hba;
struct list_head sas_expander_list;
+   struct list_head enclosure_list;
spinlock_t  sas_node_lock;
struct list_head sas_device_list;
struct list_head sas_device_init_list;
@@ -1391,6 +1404,7 @@ int mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc);
 int mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc);
+void mpt3sas_free_enclosure_list(struct MPT3SAS_ADAPTER *ioc);
 int mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
enum reset_type type);
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 33587a8..bc8e7f0 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1362,6 +1362,30 @@ mpt3sas_scsih_expander_find_by_handle(struct 
MPT3SAS_ADAPTER *ioc, u16 handle)
 }
 
 /**
+ * mpt3sas_scsih_enclosure_find_by_handle - exclosure device search
+ * @ioc: per adapter object
+ * @handle: enclosure handle (assigned by firmware)
+ * Context: Calling function should acquire ioc->sas_device_lock
+ *
+ * This searches for enclosure device based on handle, then returns the
+ * enclosure object.
+ */
+static struct _enclosure_node *
+mpt3sas_scsih_enclosure_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+   struct _enclosure_node *enclosure_dev, *r;
+
+   r = NULL;
+   list_for_each_entry(enclosure_dev, &ioc->enclosure_list, list) {
+   if (le16_to_cpu(enclosure_dev->pg0.EnclosureHandle) != handle)
+   continue;
+   r = enclosure_dev;
+   goto out;
+   }
+out:
+   return r;
+}
+/**
  * mpt3sas_scsih_expander_find_by_sas_address - expander device

[PATCH v2 07/14] mpt3sas: Increase event log buffer to support 24 port HBA's.

2018-04-09 Thread Chaitra P B
For 24 port HBA's events generated by IOC are more in certain cases and
the current circular buffer may be overwritten.Hence increased the event
log buffer to accommodate more events.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
index a44046c..18b46fa 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
@@ -184,7 +184,7 @@ struct mpt3_ioctl_iocinfo {
 
 
 /* number of event log entries */
-#define MPT3SAS_CTL_EVENT_LOG_SIZE (50)
+#define MPT3SAS_CTL_EVENT_LOG_SIZE (200)
 
 /**
  * struct mpt3_ioctl_eventquery - query event count and type
-- 
1.8.3.1



[PATCH v2 01/14] mpt3sas: Bug fix for big endian systems.

2018-04-09 Thread Chaitra P B
This patch fixes bug for big endian systems.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |  2 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 57 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  6 ++--
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 11 +++---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 59 +++-
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |  3 +-
 6 files changed, 73 insertions(+), 65 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_init.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_init.h
index 948a3ba..6213ce6 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_init.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_init.h
@@ -75,7 +75,7 @@
 
 typedef struct _MPI2_SCSI_IO_CDB_EEDP32 {
U8 CDB[20]; /*0x00 */
-   U32 PrimaryReferenceTag;/*0x14 */
+   __be32 PrimaryReferenceTag; /*0x14 */
U16 PrimaryApplicationTag;  /*0x18 */
U16 PrimaryApplicationTagMask;  /*0x1A */
U32 TransferLength; /*0x1C */
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 0a0e7aa..4767690 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -394,13 +394,14 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
buff_ptr_phys = buffer_iomem_phys;
WARN_ON(buff_ptr_phys > U32_MAX);
 
-   if (sgel->FlagsLength &
+   if (le32_to_cpu(sgel->FlagsLength) &
(MPI2_SGE_FLAGS_HOST_TO_IOC << MPI2_SGE_FLAGS_SHIFT))
is_write = 1;
 
for (i = 0; i < MPT_MIN_PHYS_SEGMENTS + ioc->facts.MaxChainDepth; i++) {
 
-   sgl_flags = (sgel->FlagsLength >> MPI2_SGE_FLAGS_SHIFT);
+   sgl_flags =
+   (le32_to_cpu(sgel->FlagsLength) >> MPI2_SGE_FLAGS_SHIFT);
 
switch (sgl_flags & MPI2_SGE_FLAGS_ELEMENT_MASK) {
case MPI2_SGE_FLAGS_CHAIN_ELEMENT:
@@ -411,7 +412,7 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
 */
sgel_next =
_base_get_chain_buffer_dma_to_chain_buffer(ioc,
-   sgel->Address);
+   le32_to_cpu(sgel->Address));
if (sgel_next == NULL)
return;
/*
@@ -426,7 +427,7 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
dst_addr_phys = _base_get_chain_phys(ioc,
smid, sge_chain_count);
WARN_ON(dst_addr_phys > U32_MAX);
-   sgel->Address = (u32)dst_addr_phys;
+   sgel->Address = cpu_to_le32((u32)dst_addr_phys);
sgel = sgel_next;
sge_chain_count++;
break;
@@ -435,22 +436,28 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
if (is_scsiio_req) {
_base_clone_to_sys_mem(buff_ptr,
sg_virt(sg_scmd),
-   (sgel->FlagsLength & 0x00ff));
+   (le32_to_cpu(sgel->FlagsLength) &
+   0x00ff));
/*
 * FIXME: this relies on a a zero
 * PCI mem_offset.
 */
-   sgel->Address = (u32)buff_ptr_phys;
+   sgel->Address =
+   cpu_to_le32((u32)buff_ptr_phys);
} else {
_base_clone_to_sys_mem(buff_ptr,
ioc->config_vaddr,
-   (sgel->FlagsLength & 0x00ff));
-   sgel->Address = (u32)buff_ptr_phys;
+   (le32_to_cpu(sgel->FlagsLength) &
+   0x00ff));
+   sgel->Address =
+   cpu_to_le32((u32)buff_ptr_phys);
}
}
-   buff_ptr += (sgel->FlagsLength & 0x00ff);
-   buff_ptr_phys += (sgel->FlagsLength & 0x00ff);
-   if ((sgel->FlagsLength &
+   buff_ptr += (le32_to_cpu(sge

[PATCH v1 15/15] mpt3sas: Update driver version "25.100.00.00"

2018-04-05 Thread Chaitra P B
Update driver version to match OOB/internal driver version.

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 6a9657e..693b04b 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 "17.100.00.00"
-#define MPT3SAS_MAJOR_VERSION  17
+#define MPT3SAS_DRIVER_VERSION "25.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  25
 #define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
-- 
1.8.3.1



[PATCH v1 14/15] mpt3sas: fix possible memory leak.

2018-04-05 Thread Chaitra P B
In ioctl exit path driver refers ioc_list to free memory associated with
diag buffers and event_log pointer used to save events by driver.
If ctl_exit() func is called after unregistering driver, then ioc_list will
be empty and hence driver will not be able to free the allocated memory
which in turn causes memory leak.
So call ctl_exit() function before unregistering mpt3sas driver.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index f3e1dc7..f8b5248 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -11283,10 +11283,10 @@ _mpt3sas_exit(void)
pr_info("mpt3sas version %s unloading\n",
MPT3SAS_DRIVER_VERSION);
 
-   pci_unregister_driver(&mpt3sas_driver);
-
mpt3sas_ctl_exit(hbas_to_enumerate);
 
+   pci_unregister_driver(&mpt3sas_driver);
+
scsih_exit();
 }
 
-- 
1.8.3.1



[PATCH v1 10/15] mpt3sas: Cache enclosure pages during enclosure add.

2018-04-05 Thread Chaitra P B
In function _scsih_add_device,
for each device connected to an enclosure, driver reads the
enclosure page(To get details like enclosure handle,
enclosure logical ID, enclosure level etc.)

With this patch, instead of reading enclosure page everytime,
driver maintains a list for enclosure device(During enclosure
add event, enclosure device is added to the list and removed
from the list on delete events) and uses the enclosure page
from the list.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  22 +++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  14 ++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 296 +++
 3 files changed, 236 insertions(+), 96 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index f9bacd2..fccf5d1 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4087,6 +4087,27 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * mpt3sas_free_enclosure_list - release memory
+ * @ioc: per adapter object
+ *
+ * Free memory allocated during encloure add.
+ *
+ * Return nothing.
+ */
+void
+mpt3sas_free_enclosure_list(struct MPT3SAS_ADAPTER *ioc)
+{
+   struct _enclosure_node *enclosure_dev, *enclosure_dev_next;
+
+   /* Free enclosure list */
+   list_for_each_entry_safe(enclosure_dev,
+   enclosure_dev_next, &ioc->enclosure_list, list) {
+   list_del(&enclosure_dev->list);
+   kfree(enclosure_dev);
+   }
+}
+
+/**
  * _base_release_memory_pools - release memory
  * @ioc: per adapter object
  *
@@ -,6 +6687,7 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc)
mpt3sas_base_stop_watchdog(ioc);
mpt3sas_base_free_resources(ioc);
_base_release_memory_pools(ioc);
+   mpt3sas_free_enclosure_list(ioc);
pci_set_drvdata(ioc->pdev, NULL);
kfree(ioc->cpu_msix_table);
if (ioc->is_warpdrive)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index a0fca8a..6f3329e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -741,6 +741,17 @@ struct _sas_node {
struct list_head sas_port_list;
 };
 
+
+/**
+ * struct _enclosure_node - enclosure information
+ * @list: list of enclosures
+ * @pg0: enclosure pg0;
+ */
+struct _enclosure_node {
+   struct list_head list;
+   Mpi2SasEnclosurePage0_t pg0;
+};
+
 /**
  * enum reset_type - reset state
  * @FORCE_BIG_HAMMER: issue diagnostic reset
@@ -1013,6 +1024,7 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct 
MPT3SAS_ADAPTER *ioc);
  * @iounit_pg8: static iounit page 8
  * @sas_hba: sas host object
  * @sas_expander_list: expander object list
+ * @enclosure_list: enclosure object list
  * @sas_node_lock:
  * @sas_device_list: sas device object list
  * @sas_device_init_list: sas device object list (used only at init time)
@@ -1218,6 +1230,7 @@ struct MPT3SAS_ADAPTER {
/* sas hba, expander, and device list */
struct _sas_node sas_hba;
struct list_head sas_expander_list;
+   struct list_head enclosure_list;
spinlock_t  sas_node_lock;
struct list_head sas_device_list;
struct list_head sas_device_init_list;
@@ -1391,6 +1404,7 @@ int mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc);
 int mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc);
+void mpt3sas_free_enclosure_list(struct MPT3SAS_ADAPTER *ioc);
 int mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
enum reset_type type);
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index f6861a6..2f9121e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1362,6 +1362,30 @@ mpt3sas_scsih_expander_find_by_handle(struct 
MPT3SAS_ADAPTER *ioc, u16 handle)
 }
 
 /**
+ * mpt3sas_scsih_enclosure_find_by_handle - exclosure device search
+ * @ioc: per adapter object
+ * @handle: enclosure handle (assigned by firmware)
+ * Context: Calling function should acquire ioc->sas_device_lock
+ *
+ * This searches for enclosure device based on handle, then returns the
+ * enclosure object.
+ */
+static struct _enclosure_node *
+mpt3sas_scsih_enclosure_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+   struct _enclosure_node *enclosure_dev, *r;
+
+   r = NULL;
+   list_for_each_entry(enclosure_dev, &ioc->enclosure_list, list) {
+   if (le16_to_cpu(enclosure_dev->pg0.EnclosureHandle) != handle)
+   continue;
+   r = enclosure_dev;
+   goto out;
+   }
+out:
+   return r;
+}
+/**
  * mpt3sas_scsih_expander_find_by_sas_address - expander device

[PATCH v1 11/15] mpt3sas: Report Firmware Package Version from HBA Driver.

2018-04-05 Thread Chaitra P B
Added function _base_display_fwpkg_version, which sends FWUpload
request to pull FW package version from FW Image Header.
Now driver prints FW package version in addition to FW
version if the PackageVersion is valid.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index fccf5d1..7f438be 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -3825,6 +3825,105 @@ _base_display_OEMs_branding(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * _base_display_fwpkg_version - sends FWUpload request to pull FWPkg
+ * version from FW Image Header.
+ * @ioc: per adapter object
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+   static int
+_base_display_fwpkg_version(struct MPT3SAS_ADAPTER *ioc)
+{
+   Mpi2FWImageHeader_t *FWImgHdr;
+   Mpi25FWUploadRequest_t *mpi_request;
+   Mpi2FWUploadReply_t mpi_reply;
+   int r = 0;
+   void *fwpkg_data = NULL;
+   dma_addr_t fwpkg_data_dma;
+   u16 smid, ioc_status;
+   size_t data_length;
+
+   dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+   __func__));
+
+   if (ioc->base_cmds.status & MPT3_CMD_PENDING) {
+   pr_err(MPT3SAS_FMT "%s: internal command already in use\n",
+   ioc->name, __func__);
+   return -EAGAIN;
+   }
+
+   data_length = sizeof(Mpi2FWImageHeader_t);
+   fwpkg_data = pci_alloc_consistent(ioc->pdev, data_length,
+   &fwpkg_data_dma);
+   if (!fwpkg_data) {
+   pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
+   ioc->name, __FILE__, __LINE__, __func__);
+   return -ENOMEM;
+   }
+
+   smid = mpt3sas_base_get_smid(ioc, ioc->base_cb_idx);
+   if (!smid) {
+   pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
+   ioc->name, __func__);
+   r = -EAGAIN;
+   goto out;
+   }
+
+   ioc->base_cmds.status = MPT3_CMD_PENDING;
+   mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
+   ioc->base_cmds.smid = smid;
+   memset(mpi_request, 0, sizeof(Mpi25FWUploadRequest_t));
+   mpi_request->Function = MPI2_FUNCTION_FW_UPLOAD;
+   mpi_request->ImageType = MPI2_FW_UPLOAD_ITYPE_FW_FLASH;
+   mpi_request->ImageSize = cpu_to_le32(data_length);
+   ioc->build_sg(ioc, &mpi_request->SGL, 0, 0, fwpkg_data_dma,
+   data_length);
+   init_completion(&ioc->base_cmds.done);
+   mpt3sas_base_put_smid_default(ioc, smid);
+   /* Wait for 15 seconds */
+   wait_for_completion_timeout(&ioc->base_cmds.done,
+   FW_IMG_HDR_READ_TIMEOUT*HZ);
+   pr_info(MPT3SAS_FMT "%s: complete\n",
+   ioc->name, __func__);
+   if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) {
+   pr_err(MPT3SAS_FMT "%s: timeout\n",
+   ioc->name, __func__);
+   _debug_dump_mf(mpi_request,
+   sizeof(Mpi25FWUploadRequest_t)/4);
+   r = -ETIME;
+   } else {
+   memset(&mpi_reply, 0, sizeof(Mpi2FWUploadReply_t));
+   if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) {
+   memcpy(&mpi_reply, ioc->base_cmds.reply,
+   sizeof(Mpi2FWUploadReply_t));
+   ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+   MPI2_IOCSTATUS_MASK;
+   if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
+   FWImgHdr = (Mpi2FWImageHeader_t *)fwpkg_data;
+   if (FWImgHdr->PackageVersion.Word) {
+   pr_info(MPT3SAS_FMT "FW Package Version"
+   "(%02d.%02d.%02d.%02d)\n",
+   ioc->name,
+   FWImgHdr->PackageVersion.Struct.Major,
+   FWImgHdr->PackageVersion.Struct.Minor,
+   FWImgHdr->PackageVersion.Struct.Unit,
+   FWImgHdr->PackageVersion.Struct.Dev);
+   }
+   } else {
+   _debug_dump_mf(&mpi_reply,
+   sizeof(Mpi2FWUploadR

[PATCH v1 13/15] mpt3sas: For NVME device, issue a protocol level reset instead of hot reset and use TM timeout value exposed in PCIe Device Page 2.

2018-04-05 Thread Chaitra P B
1)Manufacturing Page 11 contains parameters to control
internal firmware behavior. Based on AddlFlags2 field
FW/Driver behaviour can be changed, (flag tm_custom_handling
is used for this)

a) For PCIe device, protocol level reset should be used if
flag tm_custom_handling is 0.
Since Abort Task Set, LUN reset and Target reset will result
in a protocol level reset. Drivers should issue only one type
of this reset, if that fails then it should escalate to a controller
reset (diag reset/OCR).
b) If the driver has control over the TM reset timeout value, then
driver should use the value exposed in PCIe Device Page 2 for pcie device
(field ControllerResetTO).

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 13 ++
 drivers/scsi/mpt3sas/mpt3sas_base.h  | 26 ++--
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 22 +--
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 76 ++--
 4 files changed, 116 insertions(+), 21 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 7f438be..eaeace0 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4139,6 +4139,7 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
Mpi2ConfigReply_t mpi_reply;
u32 iounit_pg1_flags;
 
+   ioc->nvme_abort_timeout = 30;
mpt3sas_config_get_manufacturing_pg0(ioc, &mpi_reply, &ioc->manu_pg0);
if (ioc->ir_firmware)
mpt3sas_config_get_manufacturing_pg10(ioc, &mpi_reply,
@@ -4157,6 +4158,18 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
mpt3sas_config_set_manufacturing_pg11(ioc, &mpi_reply,
&ioc->manu_pg11);
}
+   if (ioc->manu_pg11.AddlFlags2 & NVME_TASK_MNGT_CUSTOM_MASK)
+   ioc->tm_custom_handling = 1;
+   else {
+   ioc->tm_custom_handling = 0;
+   if (ioc->manu_pg11.NVMeAbortTO < NVME_TASK_ABORT_MIN_TIMEOUT)
+   ioc->nvme_abort_timeout = NVME_TASK_ABORT_MIN_TIMEOUT;
+   else if (ioc->manu_pg11.NVMeAbortTO >
+   NVME_TASK_ABORT_MAX_TIMEOUT)
+   ioc->nvme_abort_timeout = NVME_TASK_ABORT_MAX_TIMEOUT;
+   else
+   ioc->nvme_abort_timeout = ioc->manu_pg11.NVMeAbortTO;
+   }
 
mpt3sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2);
mpt3sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 20fe90d..6a9657e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -146,8 +146,12 @@
 #defineNVME_CMD_PRP1_OFFSET24  /* PRP1 offset in NVMe 
cmd */
 #defineNVME_CMD_PRP2_OFFSET32  /* PRP2 offset in NVMe 
cmd */
 #defineNVME_ERROR_RESPONSE_SIZE16  /* Max NVME Error 
Response */
+#define NVME_TASK_ABORT_MIN_TIMEOUT6
+#define NVME_TASK_ABORT_MAX_TIMEOUT60
+#define NVME_TASK_MNGT_CUSTOM_MASK (0x0010)
 #defineNVME_PRP_PAGE_SIZE  4096/* Page size */
 
+
 /*
  * reset phases
  */
@@ -363,7 +367,15 @@ struct Mpi2ManufacturingPage11_t {
u8  EEDPTagMode;/* 09h */
u8  Reserved3;  /* 0Ah */
u8  Reserved4;  /* 0Bh */
-   __le32  Reserved5[23];  /* 0Ch-60h*/
+   __le32  Reserved5[8];   /* 0Ch-2Ch */
+   u16 AddlFlags2; /* 2Ch */
+   u8  AddlFlags3; /* 2Eh */
+   u8  Reserved6;  /* 2Fh */
+   __le32  Reserved7[7];   /* 30h - 4Bh */
+   u8  NVMeAbortTO;/* 4Ch */
+   u8  Reserved8;  /* 4Dh */
+   u16 Reserved9;  /* 4Eh */
+   __le32  Reserved10[4];  /* 50h - 60h */
 };
 
 /**
@@ -573,6 +585,7 @@ struct _pcie_device {
u8  enclosure_level;
u8  connector_name[4];
u8  *serial_number;
+   u8  reset_timeout;
struct kref refcount;
 };
 /**
@@ -1211,6 +1224,10 @@ struct MPT3SAS_ADAPTER {
void*event_log;
u32 event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
 
+   u8  tm_custom_handling;
+   u8  nvme_abort_timeout;
+
+
/* static config pages */
struct mpt3sas_facts facts;
struct mpt3sas_port_facts *pfacts;
@@ -1470,10 +1487,11 @@ u8 mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER 
*ioc, u8 msix_index,
u32 reply);
 void mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase);

[PATCH v1 09/15] mpt3sas: Allow processing of events during driver unload.

2018-04-05 Thread Chaitra P B
Events were not processed during driver unload, hence unloading of driver
doesn't complete when drives are disconnected while unloading of driver.
So don't block events in ISR path, i,e., remove the flag ioc->remove_host
so that events are getting processed during driver unload.
Thus allowing driver unload to complete by processing drive removal events
during driver unload.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 0e06d19..f6861a6 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3677,11 +3677,7 @@ _scsih_tm_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 
smid, u8 msix_index,
u32 ioc_state;
struct _sc_list *delayed_sc;
 
-   if (ioc->remove_host) {
-   dewtprintk(ioc, pr_info(MPT3SAS_FMT
-   "%s: host has been removed\n", __func__, ioc->name));
-   return 1;
-   } else if (ioc->pci_error_recovery) {
+   if (ioc->pci_error_recovery) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: host in pci error recovery\n", __func__,
ioc->name));
@@ -3803,8 +3799,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
u16 smid;
struct _tr_list *delayed_tr;
 
-   if (ioc->shost_recovery || ioc->remove_host ||
-   ioc->pci_error_recovery) {
+   if (ioc->pci_error_recovery) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: host reset in progress!\n",
__func__, ioc->name));
@@ -3857,8 +3852,7 @@ _scsih_tm_volume_tr_complete(struct MPT3SAS_ADAPTER *ioc, 
u16 smid,
Mpi2SCSITaskManagementReply_t *mpi_reply =
mpt3sas_base_get_reply_virt_addr(ioc, reply);
 
-   if (ioc->shost_recovery || ioc->remove_host ||
-   ioc->pci_error_recovery) {
+   if (ioc->shost_recovery || ioc->pci_error_recovery) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: host reset in progress!\n",
__func__, ioc->name));
@@ -9475,8 +9469,8 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, 
u8 msix_index,
u16 sz;
Mpi26EventDataActiveCableExcept_t *ActiveCableEventData;
 
-   /* events turned off due to host reset or driver unloading */
-   if (ioc->remove_host || ioc->pci_error_recovery)
+   /* events turned off due to host reset */
+   if (ioc->pci_error_recovery)
return 1;
 
mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
-- 
1.8.3.1



[PATCH v1 12/15] mpt3sas: Update MPI Headers

2018-04-05 Thread Chaitra P B
Update MPI Files to support protocol level reset for NVMe device.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2.h  |  9 ++---
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 30 --
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |  7 ++-
 3 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h
index b015c30..1e45268 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2.h
@@ -9,7 +9,7 @@
  * scatter/gather formats.
  * Creation Date:  June 21, 2006
  *
- * mpi2.h Version:  02.00.48
+ *  mpi2.h Version:  02.00.50
  *
  * 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
@@ -114,6 +114,8 @@
  * 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.
+ * 06-13-17  02.00.49  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 09-29-17  02.00.50  Bumped MPI2_HEADER_VERSION_UNIT.
  * --
  */
 
@@ -152,8 +154,9 @@
MPI26_VERSION_MINOR)
 #define MPI2_VERSION_02_06 (0x0206)
 
-/*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT(0x30)
+
+/* Unit and Dev versioning for this MPI header set */
+#define MPI2_HEADER_VERSION_UNIT(0x32)
 #define MPI2_HEADER_VERSION_DEV (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK   (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT  (8)
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
index 0ad88de..5122920 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
@@ -7,7 +7,7 @@
  * Title:  MPI Configuration messages and pages
  * Creation Date:  November 10, 2006
  *
- *   mpi2_cnfg.h Version:  02.00.40
+ *mpi2_cnfg.h Version:  02.00.42
  *
  * 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
@@ -219,6 +219,18 @@
  * Added ChassisSlot field to SAS Enclosure Page 0.
  * Added ChassisSlot Valid bit (bit 5) to the Flags field
  * in SAS Enclosure Page 0.
+ * 06-13-17  02.00.41  Added MPI26_MFGPAGE_DEVID_SAS3816 and
+ * MPI26_MFGPAGE_DEVID_SAS3916 defines.
+ * Removed MPI26_MFGPAGE_DEVID_SAS4008 define.
+ * Added MPI26_PCIEIOUNIT1_LINKFLAGS_SRNS_EN define.
+ * Renamed PI26_PCIEIOUNIT1_LINKFLAGS_EN_SRIS to
+ * PI26_PCIEIOUNIT1_LINKFLAGS_SRIS_EN.
+ * Renamed MPI26_PCIEIOUNIT1_LINKFLAGS_DIS_SRIS to
+ * MPI26_PCIEIOUNIT1_LINKFLAGS_DIS_SEPARATE_REFCLK.
+ * 09-29-17  02.00.42  Added ControllerResetTO field to PCIe Device Page 2.
+ * Added NOIOB field to PCIe Device Page 2.
+ * Added MPI26_PCIEDEV2_CAP_DATA_BLK_ALIGN_AND_GRAN to
+ * the Capabilities field of PCIe Device Page 2.
  * --
  */
 
@@ -556,7 +568,8 @@ typedef struct _MPI2_CONFIG_REPLY {
 #define MPI26_MFGPAGE_DEVID_SAS3616 (0x00D1)
 #define MPI26_MFGPAGE_DEVID_SAS3708 (0x00D2)
 
-#define MPI26_MFGPAGE_DEVID_SAS4008 (0x00A1)
+#define MPI26_MFGPAGE_DEVID_SAS3816 (0x00A1)
+#define MPI26_MFGPAGE_DEVID_SAS3916 (0x00A0)
 
 
 /*Manufacturing Page 0 */
@@ -3864,20 +3877,25 @@ typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_0 {
 typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_2 {
MPI2_CONFIG_EXTENDED_PAGE_HEADERHeader; /*0x00 */
U16 DevHandle;  /*0x08 */
-   U16 Reserved1;  /*0x0A */
-   U32 MaximumDataTransferSize;/*0x0C */
+   U8  ControllerResetTO;  /* 0x0A */
+   U8  Reserved1;  /* 0x0B */
+   U32 MaximumDataTransferSize;/*0x0C */
U32 Capabilities;   /*0x10 */
-   U32 Reserved2;  /*0x14 */
+   U16 NOIOB;  /* 0x14 */
+   U16 Reserved2;  /* 0x16 */
 } MPI26_CONFIG_PAGE_PCIEDEV_2, *PTR_MPI26_CONFIG_PAGE_PCIEDEV_2,
Mpi26PCIeDevicePage2_t, *pMpi26PCIeDevicePage2_t;
 
-#define MPI26_PCIEDEVICE2_PAGEVERSION   (0x00)
+#define MPI26_PCIEDEVICE2_PAGEVERSION   (0x01)
 
 /*defines for PCIe Device Page 2 Capabilities field */
+#define MPI26_PCIEDEV2_CAP_DATA_BLK_ALIGN_AND_GRAN (0x0008)
 #define MPI26_PCIEDEV2_CAP_SGL_FORMAT  (0x0004)
 #define

[PATCH v1 07/15] mpt3sas: Added support for SAS Device Discovery Error Event.

2018-04-05 Thread Chaitra P B
The SAS Device Discovery Error Event is sent to the host when
discovery for a particular device is failed during discovery,
even after maximum retries by the IOC.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  4 
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 42 
 2 files changed, 46 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index bd1beaf..f9bacd2 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1029,6 +1029,9 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
desc = "Cable Event";
break;
+   case MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
+   desc = "SAS Device Discovery Error";
+   break;
case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
desc = "PCIE Device Status Change";
break;
@@ -6596,6 +6599,7 @@ 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);
+   _base_unmask_events(ioc, MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR);
if (ioc->hba_mpi_version_belonged == MPI26_VERSION) {
if (ioc->is_gen35_ioc) {
_base_unmask_events(ioc,
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 6b1aaa0..0e06d19 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -7531,6 +7531,44 @@ _scsih_sas_discovery_event(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _scsih_sas_device_discovery_error_event - display SAS device discovery error
+ * events
+ * @ioc: per adapter object
+ * @fw_event: The fw_event_work object
+ * Context: user.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_sas_device_discovery_error_event(struct MPT3SAS_ADAPTER *ioc,
+   struct fw_event_work *fw_event)
+{
+   Mpi25EventDataSasDeviceDiscoveryError_t *event_data =
+   (Mpi25EventDataSasDeviceDiscoveryError_t *)fw_event->event_data;
+
+   switch (event_data->ReasonCode) {
+   case MPI25_EVENT_SAS_DISC_ERR_SMP_FAILED:
+   pr_warn(MPT3SAS_FMT "SMP command sent to the expander"
+   "(handle:0x%04x, sas_address:0x%016llx,"
+   "physical_port:0x%02x) has failed",
+   ioc->name, le16_to_cpu(event_data->DevHandle),
+   (unsigned long long)le64_to_cpu(event_data->SASAddress),
+   event_data->PhysicalPort);
+   break;
+   case MPI25_EVENT_SAS_DISC_ERR_SMP_TIMEOUT:
+   pr_warn(MPT3SAS_FMT "SMP command sent to the expander"
+   "(handle:0x%04x, sas_address:0x%016llx,"
+   "physical_port:0x%02x) has timed out",
+   ioc->name, le16_to_cpu(event_data->DevHandle),
+   (unsigned long long)le64_to_cpu(event_data->SASAddress),
+   event_data->PhysicalPort);
+   break;
+   default:
+   break;
+   }
+}
+
+/**
  * _scsih_pcie_enumeration_event - handle enumeration events
  * @ioc: per adapter object
  * @fw_event: The fw_event_work object
@@ -9357,6 +9395,9 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct 
fw_event_work *fw_event)
case MPI2_EVENT_SAS_DISCOVERY:
_scsih_sas_discovery_event(ioc, fw_event);
break;
+   case MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
+   _scsih_sas_device_discovery_error_event(ioc, fw_event);
+   break;
case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
_scsih_sas_broadcast_primitive_event(ioc, fw_event);
break;
@@ -9541,6 +9582,7 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, 
u8 msix_index,
case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
case MPI2_EVENT_IR_OPERATION_STATUS:
case MPI2_EVENT_SAS_DISCOVERY:
+   case MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
case MPI2_EVENT_IR_PHYSICAL_DISK:
case MPI2_EVENT_PCIE_ENUMERATION:
-- 
1.8.3.1



[PATCH v1 06/15] mpt3sas: Enhanced handling of Sense Buffer.

2018-04-05 Thread Chaitra P B
Enhanced DMA allocation for Sense Buffer, if the allocation does not fit
within same 4GB.Introduced is_MSB_are_same function to check if allocted
buffer within 4GB range or not.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 56 +
 1 file changed, 56 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 701e1e7..bd1beaf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4205,6 +4205,31 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * is_MSB_are_same - checks whether all reply queues in a set are
+ * having same upper 32bits in their base memory address.
+ * @reply_pool_start_address: Base address of a reply queue set
+ * @pool_sz: Size of single Reply Descriptor Post Queues pool size
+ *
+ * Returns 1 if reply queues in a set have a same upper 32bits
+ * in their base memory address,
+ * else 0
+ */
+
+static int
+is_MSB_are_same(long reply_pool_start_address, u32 pool_sz)
+{
+   long reply_pool_end_address;
+
+   reply_pool_end_address = reply_pool_start_address + pool_sz;
+
+   if (upper_32_bits(reply_pool_start_address) ==
+   upper_32_bits(reply_pool_end_address))
+   return 1;
+   else
+   return 0;
+}
+
+/**
  * _base_allocate_memory_pools - allocate start of day memory pools
  * @ioc: per adapter object
  *
@@ -4664,6 +4689,37 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->name);
goto out;
}
+   /* sense buffer requires to be in same 4 gb region.
+* Below function will check the same.
+* In case of failure, new pci pool will be created with updated
+* alignment. Older allocation and pool will be destroyed.
+* Alignment will be used such a way that next allocation if
+* success, will always meet same 4gb region requirement.
+* Actual requirement is not alignment, but we need start and end of
+* DMA address must have same upper 32 bit address.
+*/
+   if (!is_MSB_are_same((long)ioc->sense, sz)) {
+   //Release Sense pool & Reallocate
+   dma_pool_free(ioc->sense_dma_pool, ioc->sense, ioc->sense_dma);
+   dma_pool_destroy(ioc->sense_dma_pool);
+   ioc->sense = NULL;
+
+   ioc->sense_dma_pool =
+   dma_pool_create("sense pool", &ioc->pdev->dev, sz,
+   roundup_pow_of_two(sz), 0);
+   if (!ioc->sense_dma_pool) {
+   pr_err(MPT3SAS_FMT "sense pool: pci_pool_create 
failed\n",
+   ioc->name);
+   goto out;
+   }
+   ioc->sense = dma_pool_alloc(ioc->sense_dma_pool, GFP_KERNEL,
+   &ioc->sense_dma);
+   if (!ioc->sense) {
+   pr_err(MPT3SAS_FMT "sense pool: pci_pool_alloc 
failed\n",
+   ioc->name);
+   goto out;
+   }
+   }
dinitprintk(ioc, pr_info(MPT3SAS_FMT
"sense pool(0x%p): depth(%d), element_size(%d), pool_size"
"(%d kB)\n", ioc->name, ioc->sense, ioc->scsiio_depth,
-- 
1.8.3.1



[PATCH v1 08/15] mpt3sas: Increase event log buffer to support 24 port HBA's.

2018-04-05 Thread Chaitra P B
For 24 port HBA's events generated by IOC are more in certain cases and
the current circular buffer may be overwritten.Hence increased the event
log buffer to accommodate more events.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
index a44046c..18b46fa 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
@@ -184,7 +184,7 @@ struct mpt3_ioctl_iocinfo {
 
 
 /* number of event log entries */
-#define MPT3SAS_CTL_EVENT_LOG_SIZE (50)
+#define MPT3SAS_CTL_EVENT_LOG_SIZE (200)
 
 /**
  * struct mpt3_ioctl_eventquery - query event count and type
-- 
1.8.3.1



[PATCH v1 03/15] mpt3sas: Add sanity checks for scsi tracker before accessing it.

2018-04-05 Thread Chaitra P B
Check scsi tracker 'st' for NULL and st->smid for zero (as driver uses smid
starting from one) before accessing it.
These checks are added as there are possibilities for getting valid
scsi_cmd when driver calls scsi_host_find_tag() API when it loops using
smid(i.e tag) from one to hba queue depth but still scsi tracker st for
this corresponding scsi_cmd is not yet initialized.

For example below are such scenario:
Sometimes it is possible that scsi_cmd might have created at SML but it
might not be issued to the driver (or driver might have returned the
command with Host busy status) as the host reset operation / TMs is in
progress.In such case where the scsi_cmd is not yet processed by driver
then the scsi tracker 'st' of that scsi_cmd & the fields of this 'st' will
be uninitialized.
And hence this patch add checks for 'st' in IOCTL path for TMs issued from
applications and also in host reset path where driver flushes all the
outstanding commands as part of host reset operation.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index c1b17d6..2f27d5c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -590,7 +590,8 @@ _ctl_set_task_mid(struct MPT3SAS_ADAPTER *ioc, struct 
mpt3_ioctl_command *karg,
struct scsiio_tracker *st;
 
scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid);
-   if (!scmd)
+   if (scmd == NULL || scmd->device == NULL ||
+   scmd->device->hostdata == NULL)
continue;
if (lun != scmd->device->lun)
continue;
@@ -600,6 +601,8 @@ _ctl_set_task_mid(struct MPT3SAS_ADAPTER *ioc, struct 
mpt3_ioctl_command *karg,
if (priv_data->sas_target->handle != handle)
continue;
st = scsi_cmd_priv(scmd);
+   if ((!st) || (st->smid == 0))
+   continue;
tm_request->TaskMID = cpu_to_le16(st->smid);
found = 1;
}
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index c9cce65..6b1aaa0 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1465,7 +1465,7 @@ mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER 
*ioc, u16 smid)
scmd = scsi_host_find_tag(ioc->shost, unique_tag);
if (scmd) {
st = scsi_cmd_priv(scmd);
-   if (st->cb_idx == 0xFF)
+   if ((!st) || (st->cb_idx == 0xFF) || (st->smid == 0))
scmd = NULL;
}
}
@@ -4451,6 +4451,13 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc)
count++;
_scsih_set_satl_pending(scmd, false);
st = scsi_cmd_priv(scmd);
+   /*
+* It may be possible that SCSI scmd got prepared by SML
+* but it has not issued to the driver, for these type of
+* scmd's don't do anything"
+*/
+   if (st && st->smid == 0)
+   continue;
mpt3sas_base_clear_st(ioc, st);
scsi_dma_unmap(scmd);
if (ioc->pci_error_recovery)
-- 
1.8.3.1



[PATCH v1 05/15] mpt3sas: Optimize I/O memory consumption in driver.

2018-04-05 Thread Chaitra P B
For every IO, memory of PAGE size is allocated for handling NVMe native
PRPS. And in addition to that for every IO (chains need per IO * chain
buffer size, e.g. 38 * 128byte) amount of memory is allocated for chain
buffers.

However, at any point of time; the IO request can be for NVMe target device
(where PRP's page is used for framing PRP's) or can be for SCSI target
device (where chain buffers are used for framing chain SGE's). This patch
modifies the driver to reuse same pre-allocated PRP page buffers as a chain
buffer for IO's targeted for SCSI target devices. No need to allocate
separate buffers for chain SGE's buffers.

Suppose if the number of chain buffers need for IO doesn't fit in the PRP
Page size then driver maintain's separate buffers for those extra chain
buffers that exceeds the PRP page size. For example consider PRP page size
as 4K and chain buffer size as 128 bytes, then number of chain buffers that
can fit in PRP page is 4096/128 => 32. if the number of chain buffer need
per IO exceeds 32; for example consider number of chains need per IO is 36
then for remaining 4 chain buffer's driver allocates them individual.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 1e8e399..701e1e7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4188,7 +4188,8 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
kfree(ioc->internal_lookup);
if (ioc->chain_lookup) {
for (i = 0; i < ioc->scsiio_depth; i++) {
-   for (j = 0; j < ioc->chains_needed_per_io; j++) {
+   for (j = ioc->chains_per_prp_buffer;
+   j < ioc->chains_needed_per_io; j++) {
ct = &ioc->chain_lookup[i].chains_per_smid[j];
if (ct && ct->chain_buffer)
dma_pool_free(ioc->chain_dma_pool,
@@ -4506,7 +4507,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->chain_lookup = kzalloc(sz, GFP_KERNEL);
if (!ioc->chain_lookup) {
pr_err(MPT3SAS_FMT "chain_lookup: __get_free_pages "
-   "failed\n", ioc->name);
+   "failed\n", ioc->name);
goto out;
}
 
@@ -4520,33 +4521,6 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
}
}
 
-   ioc->chain_dma_pool = dma_pool_create("chain pool", &ioc->pdev->dev,
-   ioc->chain_segment_sz, 16, 0);
-   if (!ioc->chain_dma_pool) {
-   pr_err(MPT3SAS_FMT "chain_dma_pool: dma_pool_create failed\n",
-   ioc->name);
-   goto out;
-   }
-   for (i = 0; i < ioc->scsiio_depth; i++) {
-   for (j = 0; j < ioc->chains_needed_per_io; j++) {
-   ct = &ioc->chain_lookup[i].chains_per_smid[j];
-   ct->chain_buffer = dma_pool_alloc(
-   ioc->chain_dma_pool , GFP_KERNEL,
-   &ct->chain_buffer_dma);
-   if (!ct->chain_buffer) {
-   pr_err(MPT3SAS_FMT "chain_lookup: "
-   " pci_pool_alloc failed\n", ioc->name);
-   goto out;
-   }
-   }
-   total_sz += ioc->chain_segment_sz;
-   }
-
-   dinitprintk(ioc, pr_info(MPT3SAS_FMT
-   "chain pool depth(%d), frame_size(%d), pool_size(%d kB)\n",
-   ioc->name, ioc->chain_depth, ioc->chain_segment_sz,
-   ((ioc->chain_depth *  ioc->chain_segment_sz))/1024));
-
/* initialize hi-priority queue smid's */
ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth,
sizeof(struct request_tracker), GFP_KERNEL);
@@ -4587,6 +4561,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 * be required for NVMe PRP's, only each set of NVMe blocks will be
 * contiguous, so a new set is allocated for each possible I/O.
 */
+   ioc->chains_per_prp_buffer = 0;
if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_NVME_DEVICES) {
nvme_blocks_needed =
(ioc->shost->sg_tablesize * NVME_PRP_SIZE) - 1;
@@ -4609,6 +4584,11 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->name);
goto out;
  

[PATCH v1 00/15] mpt3sas: Enhancements and Defect fixes.

2018-04-05 Thread Chaitra P B
Chaitra P B (15):
  mpt3sas: Bug fix for big endian systems.
  mpt3sas: Pre-allocate RDPQ Array at driver boot time.
  mpt3sas: Add sanity checks for scsi tracker before accessing it.
  mpt3sas: Lockless access for chain buffers.
  mpt3sas: Optimize I/O memory consumption in driver.
  mpt3sas: Enhanced handling of Sense Buffer.
  mpt3sas: Added support for SAS Device Discovery Error Event.
  mpt3sas: Increase event log buffer to support 24 port HBA's.
  mpt3sas: Allow processing of events during driver unload.
  mpt3sas: Cache enclosure pages during enclosure add.
  mpt3sas: Report Firmware Package Version from HBA Driver.
  mpt3sas: Update MPI Headers
  mpt3sas: For NVME device, issue a protocol level reset instead of
hot reset and use TM timeout value exposed in PCIe Device Page  2.
  mpt3sas: fix possible memory leak.
  mpt3sas: Update driver version "25.100.00.00"

 drivers/scsi/mpt3sas/mpi/mpi2.h  |   9 +-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  30 +-
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |   2 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |   7 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 477 ++---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  62 +++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  38 ++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.h   |   2 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 500 +--
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |   3 +-
 10 files changed, 830 insertions(+), 300 deletions(-)

-- 
1.8.3.1



[PATCH v1 04/15] mpt3sas: Lockless access for chain buffers.

2018-04-05 Thread Chaitra P B
Introduces Chain lookup table/tracker and implements accessing chain buffer
using smid.
Removed link list based access of chain buffer which requires lock and
allocated as many chains needed.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index a79c6df..1e8e399 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -297,12 +297,15 @@ static void *
 _base_get_chain_buffer_dma_to_chain_buffer(struct MPT3SAS_ADAPTER *ioc,
dma_addr_t chain_buffer_dma)
 {
-   u16 index;
-
-   for (index = 0; index < ioc->chain_depth; index++) {
-   if (ioc->chain_lookup[index].chain_buffer_dma ==
-   chain_buffer_dma)
-   return ioc->chain_lookup[index].chain_buffer;
+   u16 index, j;
+   struct chain_tracker *ct;
+
+   for (index = 0; index < ioc->scsiio_depth; index++) {
+   for (j = 0; j < ioc->chains_needed_per_io; j++) {
+   ct = &ioc->chain_lookup[index].chains_per_smid[j];
+   if (ct && ct->chain_buffer_dma == chain_buffer_dma)
+   return ct->chain_buffer;
+   }
}
pr_info(MPT3SAS_FMT
"Provided chain_buffer_dma address is not in the lookup list\n",
@@ -1678,7 +1681,8 @@ _base_add_sg_single_64(void *paddr, u32 flags_length, 
dma_addr_t dma_addr)
  * @ioc: per adapter object
  * @scmd: SCSI commands of the IO request
  *
- * Returns chain tracker(from ioc->free_chain_list)
+ * Returns chain tracker from chain_lookup table using key as
+ * smid and smid's chain_offset.
  */
 static struct chain_tracker *
 _base_get_chain_buffer_tracker(struct MPT3SAS_ADAPTER *ioc,
@@ -1686,20 +1690,15 @@ _base_get_chain_buffer_tracker(struct MPT3SAS_ADAPTER 
*ioc,
 {
struct chain_tracker *chain_req;
struct scsiio_tracker *st = scsi_cmd_priv(scmd);
-   unsigned long flags;
+   u16 smid = st->smid;
+   u8 chain_offset =
+  atomic_read(&ioc->chain_lookup[smid - 1].chain_offset);
 
-   spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-   if (list_empty(&ioc->free_chain_list)) {
-   spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-   dfailprintk(ioc, pr_warn(MPT3SAS_FMT
-   "chain buffers not available\n", ioc->name));
+   if (chain_offset == ioc->chains_needed_per_io)
return NULL;
-   }
-   chain_req = list_entry(ioc->free_chain_list.next,
-   struct chain_tracker, tracker_list);
-   list_del_init(&chain_req->tracker_list);
-   list_add_tail(&chain_req->tracker_list, &st->chain_list);
-   spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
+
+   chain_req = &ioc->chain_lookup[smid - 1].chains_per_smid[chain_offset];
+   atomic_inc(&ioc->chain_lookup[smid - 1].chain_offset);
return chain_req;
 }
 
@@ -3278,13 +3277,7 @@ void mpt3sas_base_clear_st(struct MPT3SAS_ADAPTER *ioc,
return;
st->cb_idx = 0xFF;
st->direct_io = 0;
-   if (!list_empty(&st->chain_list)) {
-   unsigned long flags;
-
-   spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-   list_splice_init(&st->chain_list, &ioc->free_chain_list);
-   spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-   }
+   atomic_set(&ioc->chain_lookup[st->smid - 1].chain_offset, 0);
 }
 
 /**
@@ -4102,6 +4095,8 @@ static void
 _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 {
int i = 0;
+   int j = 0;
+   struct chain_tracker *ct;
struct reply_post_struct *rps;
 
dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
@@ -4192,14 +4187,18 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
kfree(ioc->hpr_lookup);
kfree(ioc->internal_lookup);
if (ioc->chain_lookup) {
-   for (i = 0; i < ioc->chain_depth; i++) {
-   if (ioc->chain_lookup[i].chain_buffer)
-   dma_pool_free(ioc->chain_dma_pool,
-   ioc->chain_lookup[i].chain_buffer,
-   ioc->chain_lookup[i].chain_buffer_dma);
+   for (i = 0; i < ioc->scsiio_depth; i++) {
+   for (j = 0; j < ioc->chains_needed_per_io; j++) {
+   ct = &ioc->chain_lookup[i].chains

[PATCH v1 02/15] mpt3sas: Pre-allocate RDPQ Array at driver boot time.

2018-04-05 Thread Chaitra P B
Instead of allocating RDPQ array (This stores the address's of each RDPQ
pools) at run time, now it will be allocated once during driver load time
and same will be reused during host reset operation also (instead of
allocating & freeing this buffer on the fly during every host reset
operation) and then freed during driver unload.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 4767690..a79c6df 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4159,7 +4159,14 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
}
} while (ioc->rdpq_array_enable &&
   (++i < ioc->reply_queue_count));
-
+   if (ioc->reply_post_free_array &&
+   ioc->rdpq_array_enable) {
+   dma_pool_free(ioc->reply_post_free_array_dma_pool,
+   ioc->reply_post_free_array,
+   ioc->reply_post_free_array_dma);
+   ioc->reply_post_free_array = NULL;
+   }
+   dma_pool_destroy(ioc->reply_post_free_array_dma_pool);
dma_pool_destroy(ioc->reply_post_free_dma_pool);
kfree(ioc->reply_post);
}
@@ -4209,7 +4216,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
struct mpt3sas_facts *facts;
u16 max_sge_elements;
u16 chains_needed_per_io;
-   u32 sz, total_sz, reply_post_free_sz;
+   u32 sz, total_sz, reply_post_free_sz, reply_post_free_array_sz;
u32 retry_sz;
u16 max_request_credit, nvme_blocks_needed;
unsigned short sg_tablesize;
@@ -4681,6 +4688,28 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->name, (unsigned long long)ioc->reply_free_dma));
total_sz += sz;
 
+   if (ioc->rdpq_array_enable) {
+   reply_post_free_array_sz = ioc->reply_queue_count *
+   sizeof(Mpi2IOCInitRDPQArrayEntry);
+   ioc->reply_post_free_array_dma_pool =
+   dma_pool_create("reply_post_free_array pool",
+   &ioc->pdev->dev, reply_post_free_array_sz, 16, 0);
+   if (!ioc->reply_post_free_array_dma_pool) {
+   dinitprintk(ioc,
+   pr_info(MPT3SAS_FMT "reply_post_free_array pool: "
+   "dma_pool_create failed\n", ioc->name));
+   goto out;
+   }
+   ioc->reply_post_free_array =
+   dma_pool_alloc(ioc->reply_post_free_array_dma_pool,
+   GFP_KERNEL, &ioc->reply_post_free_array_dma);
+   if (!ioc->reply_post_free_array) {
+   dinitprintk(ioc,
+   pr_info(MPT3SAS_FMT "reply_post_free_array pool: "
+   "dma_pool_alloc failed\n", ioc->name));
+   goto out;
+   }
+   }
ioc->config_page_sz = 512;
ioc->config_page = pci_alloc_consistent(ioc->pdev,
ioc->config_page_sz, &ioc->config_page_dma);
@@ -5487,8 +5516,6 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc)
ktime_t current_time;
u16 ioc_status;
u32 reply_post_free_array_sz = 0;
-   Mpi2IOCInitRDPQArrayEntry *reply_post_free_array = NULL;
-   dma_addr_t reply_post_free_array_dma;
 
dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
__func__));
@@ -5522,23 +5549,14 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc)
if (ioc->rdpq_array_enable) {
reply_post_free_array_sz = ioc->reply_queue_count *
sizeof(Mpi2IOCInitRDPQArrayEntry);
-   reply_post_free_array = pci_alloc_consistent(ioc->pdev,
-   reply_post_free_array_sz, &reply_post_free_array_dma);
-   if (!reply_post_free_array) {
-   pr_err(MPT3SAS_FMT
-   "reply_post_free_array: pci_alloc_consistent failed\n",
-   ioc->name);
-   r = -ENOMEM;
-   goto out;
-   }
-   memset(reply_post_free_array, 0, reply_post_free_array_sz);
+   memset(ioc->reply_post_free_array, 0, reply_post_free_array_sz);
for (i = 0; i < ioc->reply_queue_count; i++)
-   reply_post_free_array[i].RDPQBaseAddress =

[PATCH v1 01/15] mpt3sas: Bug fix for big endian systems.

2018-04-05 Thread Chaitra P B
This patch fixes bug for big endian systems.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |  2 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 57 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  6 ++--
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 11 +++---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 59 +++-
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |  3 +-
 6 files changed, 73 insertions(+), 65 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_init.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_init.h
index 948a3ba..6213ce6 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_init.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_init.h
@@ -75,7 +75,7 @@
 
 typedef struct _MPI2_SCSI_IO_CDB_EEDP32 {
U8 CDB[20]; /*0x00 */
-   U32 PrimaryReferenceTag;/*0x14 */
+   __be32 PrimaryReferenceTag; /*0x14 */
U16 PrimaryApplicationTag;  /*0x18 */
U16 PrimaryApplicationTagMask;  /*0x1A */
U32 TransferLength; /*0x1C */
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 0a0e7aa..4767690 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -394,13 +394,14 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
buff_ptr_phys = buffer_iomem_phys;
WARN_ON(buff_ptr_phys > U32_MAX);
 
-   if (sgel->FlagsLength &
+   if (le32_to_cpu(sgel->FlagsLength) &
(MPI2_SGE_FLAGS_HOST_TO_IOC << MPI2_SGE_FLAGS_SHIFT))
is_write = 1;
 
for (i = 0; i < MPT_MIN_PHYS_SEGMENTS + ioc->facts.MaxChainDepth; i++) {
 
-   sgl_flags = (sgel->FlagsLength >> MPI2_SGE_FLAGS_SHIFT);
+   sgl_flags =
+   (le32_to_cpu(sgel->FlagsLength) >> MPI2_SGE_FLAGS_SHIFT);
 
switch (sgl_flags & MPI2_SGE_FLAGS_ELEMENT_MASK) {
case MPI2_SGE_FLAGS_CHAIN_ELEMENT:
@@ -411,7 +412,7 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
 */
sgel_next =
_base_get_chain_buffer_dma_to_chain_buffer(ioc,
-   sgel->Address);
+   le32_to_cpu(sgel->Address));
if (sgel_next == NULL)
return;
/*
@@ -426,7 +427,7 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
dst_addr_phys = _base_get_chain_phys(ioc,
smid, sge_chain_count);
WARN_ON(dst_addr_phys > U32_MAX);
-   sgel->Address = (u32)dst_addr_phys;
+   sgel->Address = cpu_to_le32((u32)dst_addr_phys);
sgel = sgel_next;
sge_chain_count++;
break;
@@ -435,22 +436,28 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
if (is_scsiio_req) {
_base_clone_to_sys_mem(buff_ptr,
sg_virt(sg_scmd),
-   (sgel->FlagsLength & 0x00ff));
+   (le32_to_cpu(sgel->FlagsLength) &
+   0x00ff));
/*
 * FIXME: this relies on a a zero
 * PCI mem_offset.
 */
-   sgel->Address = (u32)buff_ptr_phys;
+   sgel->Address =
+   cpu_to_le32((u32)buff_ptr_phys);
} else {
_base_clone_to_sys_mem(buff_ptr,
ioc->config_vaddr,
-   (sgel->FlagsLength & 0x00ff));
-   sgel->Address = (u32)buff_ptr_phys;
+   (le32_to_cpu(sgel->FlagsLength) &
+   0x00ff));
+   sgel->Address =
+   cpu_to_le32((u32)buff_ptr_phys);
}
}
-   buff_ptr += (sgel->FlagsLength & 0x00ff);
-   buff_ptr_phys += (sgel->FlagsLength & 0x00ff);
-   if ((sgel->FlagsLength &
+   buff_ptr += (le32_to_cpu(sge

[PATCH 03/15] mpt3sas: Add sanity checks for scsi tracker before accessing it.

2018-03-30 Thread Chaitra P B
Check scsi tracker for NULL before accessing it.
And in some places there are possibilities for getting valid st
but still other fields are not set.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index c1b17d6..2f27d5c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -590,7 +590,8 @@ _ctl_set_task_mid(struct MPT3SAS_ADAPTER *ioc, struct 
mpt3_ioctl_command *karg,
struct scsiio_tracker *st;
 
scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid);
-   if (!scmd)
+   if (scmd == NULL || scmd->device == NULL ||
+   scmd->device->hostdata == NULL)
continue;
if (lun != scmd->device->lun)
continue;
@@ -600,6 +601,8 @@ _ctl_set_task_mid(struct MPT3SAS_ADAPTER *ioc, struct 
mpt3_ioctl_command *karg,
if (priv_data->sas_target->handle != handle)
continue;
st = scsi_cmd_priv(scmd);
+   if ((!st) || (st->smid == 0))
+   continue;
tm_request->TaskMID = cpu_to_le16(st->smid);
found = 1;
}
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index c9cce65..6b1aaa0 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1465,7 +1465,7 @@ mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER 
*ioc, u16 smid)
scmd = scsi_host_find_tag(ioc->shost, unique_tag);
if (scmd) {
st = scsi_cmd_priv(scmd);
-   if (st->cb_idx == 0xFF)
+   if ((!st) || (st->cb_idx == 0xFF) || (st->smid == 0))
scmd = NULL;
}
}
@@ -4451,6 +4451,13 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc)
count++;
_scsih_set_satl_pending(scmd, false);
st = scsi_cmd_priv(scmd);
+   /*
+* It may be possible that SCSI scmd got prepared by SML
+* but it has not issued to the driver, for these type of
+* scmd's don't do anything"
+*/
+   if (st && st->smid == 0)
+   continue;
mpt3sas_base_clear_st(ioc, st);
scsi_dma_unmap(scmd);
if (ioc->pci_error_recovery)
-- 
1.8.3.1



[PATCH 02/15] mpt3sas: Pre-allocate RDPQ Array at driver boot time.

2018-03-30 Thread Chaitra P B
Instead of allocating RDPQ array (This stores the address's of each RDPQ
pools) at run time, now it will be allocated once during driver load time
and same will be reused during host reset operation also (instead of
allocating & freeing this buffer on the fly during every host reset
operation) and then freed during driver unload.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 4767690..a79c6df 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4159,7 +4159,14 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
}
} while (ioc->rdpq_array_enable &&
   (++i < ioc->reply_queue_count));
-
+   if (ioc->reply_post_free_array &&
+   ioc->rdpq_array_enable) {
+   dma_pool_free(ioc->reply_post_free_array_dma_pool,
+   ioc->reply_post_free_array,
+   ioc->reply_post_free_array_dma);
+   ioc->reply_post_free_array = NULL;
+   }
+   dma_pool_destroy(ioc->reply_post_free_array_dma_pool);
dma_pool_destroy(ioc->reply_post_free_dma_pool);
kfree(ioc->reply_post);
}
@@ -4209,7 +4216,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
struct mpt3sas_facts *facts;
u16 max_sge_elements;
u16 chains_needed_per_io;
-   u32 sz, total_sz, reply_post_free_sz;
+   u32 sz, total_sz, reply_post_free_sz, reply_post_free_array_sz;
u32 retry_sz;
u16 max_request_credit, nvme_blocks_needed;
unsigned short sg_tablesize;
@@ -4681,6 +4688,28 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->name, (unsigned long long)ioc->reply_free_dma));
total_sz += sz;
 
+   if (ioc->rdpq_array_enable) {
+   reply_post_free_array_sz = ioc->reply_queue_count *
+   sizeof(Mpi2IOCInitRDPQArrayEntry);
+   ioc->reply_post_free_array_dma_pool =
+   dma_pool_create("reply_post_free_array pool",
+   &ioc->pdev->dev, reply_post_free_array_sz, 16, 0);
+   if (!ioc->reply_post_free_array_dma_pool) {
+   dinitprintk(ioc,
+   pr_info(MPT3SAS_FMT "reply_post_free_array pool: "
+   "dma_pool_create failed\n", ioc->name));
+   goto out;
+   }
+   ioc->reply_post_free_array =
+   dma_pool_alloc(ioc->reply_post_free_array_dma_pool,
+   GFP_KERNEL, &ioc->reply_post_free_array_dma);
+   if (!ioc->reply_post_free_array) {
+   dinitprintk(ioc,
+   pr_info(MPT3SAS_FMT "reply_post_free_array pool: "
+   "dma_pool_alloc failed\n", ioc->name));
+   goto out;
+   }
+   }
ioc->config_page_sz = 512;
ioc->config_page = pci_alloc_consistent(ioc->pdev,
ioc->config_page_sz, &ioc->config_page_dma);
@@ -5487,8 +5516,6 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc)
ktime_t current_time;
u16 ioc_status;
u32 reply_post_free_array_sz = 0;
-   Mpi2IOCInitRDPQArrayEntry *reply_post_free_array = NULL;
-   dma_addr_t reply_post_free_array_dma;
 
dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
__func__));
@@ -5522,23 +5549,14 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc)
if (ioc->rdpq_array_enable) {
reply_post_free_array_sz = ioc->reply_queue_count *
sizeof(Mpi2IOCInitRDPQArrayEntry);
-   reply_post_free_array = pci_alloc_consistent(ioc->pdev,
-   reply_post_free_array_sz, &reply_post_free_array_dma);
-   if (!reply_post_free_array) {
-   pr_err(MPT3SAS_FMT
-   "reply_post_free_array: pci_alloc_consistent failed\n",
-   ioc->name);
-   r = -ENOMEM;
-   goto out;
-   }
-   memset(reply_post_free_array, 0, reply_post_free_array_sz);
+   memset(ioc->reply_post_free_array, 0, reply_post_free_array_sz);
for (i = 0; i < ioc->reply_queue_count; i++)
-   reply_post_free_array[i].RDPQBaseAddress =

[PATCH 06/15] mpt3sas: Enhanced handling of Sense Buffer.

2018-03-30 Thread Chaitra P B
Enhanced DMA allocation for Sense Buffer, if the allocation does not fit
within same 4GB.Introduced is_MSB_are_same function to check if allocted
buffer within 4GB range or not.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 57 +
 1 file changed, 57 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 701e1e7..7f3b684 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4205,6 +4205,32 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * is_MSB_are_same - checks whether all reply queues in a set are
+ * having same upper 32bits in their base memory address.
+ * @reply_pool_start_address: Base address of a reply queue set
+ * @pool_sz: Size of single Reply Descriptor Post Queues pool size
+ *
+ * Returns 1 if reply queues in a set have a same upper 32bits
+ * in their base memory address,
+ * else 0
+ */
+
+static int
+is_MSB_are_same(long reply_pool_start_address, u32 pool_sz)
+{
+   long reply_pool_end_address;
+   unsigned long bit_divisor_16 = 0x1;
+
+   reply_pool_end_address = reply_pool_start_address + pool_sz;
+
+   if (((reply_pool_start_address / bit_divisor_16) / (bit_divisor_16)) ==
+   ((reply_pool_end_address / bit_divisor_16) / bit_divisor_16))
+   return 1;
+   else
+   return 0;
+}
+
+/**
  * _base_allocate_memory_pools - allocate start of day memory pools
  * @ioc: per adapter object
  *
@@ -4664,6 +4690,37 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->name);
goto out;
}
+   /* sense buffer requires to be in same 4 gb region.
+* Below function will check the same.
+* In case of failure, new pci pool will be created with updated
+* alignment. Older allocation and pool will be destroyed.
+* Alignment will be used such a way that next allocation if
+* success, will always meet same 4gb region requirement.
+* Actual requirement is not alignment, but we need start and end of
+* DMA address must have same upper 32 bit address.
+*/
+   if (!is_MSB_are_same((long)ioc->sense, sz)) {
+   //Release Sense pool & Reallocate
+   dma_pool_free(ioc->sense_dma_pool, ioc->sense, ioc->sense_dma);
+   dma_pool_destroy(ioc->sense_dma_pool);
+   ioc->sense = NULL;
+
+   ioc->sense_dma_pool =
+   dma_pool_create("sense pool", &ioc->pdev->dev, sz,
+   roundup_pow_of_two(sz), 0);
+   if (!ioc->sense_dma_pool) {
+   pr_err(MPT3SAS_FMT "sense pool: pci_pool_create 
failed\n",
+   ioc->name);
+   goto out;
+   }
+   ioc->sense = dma_pool_alloc(ioc->sense_dma_pool, GFP_KERNEL,
+   &ioc->sense_dma);
+   if (!ioc->sense) {
+   pr_err(MPT3SAS_FMT "sense pool: pci_pool_alloc 
failed\n",
+   ioc->name);
+   goto out;
+   }
+   }
dinitprintk(ioc, pr_info(MPT3SAS_FMT
"sense pool(0x%p): depth(%d), element_size(%d), pool_size"
"(%d kB)\n", ioc->name, ioc->sense, ioc->scsiio_depth,
-- 
1.8.3.1



[PATCH 05/15] mpt3sas: Optimize I/O memory consumption in driver.

2018-03-30 Thread Chaitra P B
For every IO, memory of PAGE size is allocated for handling NVMe native
PRPS. And in addition to that for every IO (chains need per IO * chain
buffer size, e.g. 38 * 128byte) amount of memory is allocated for chain
buffers.

However, at any point of time; the IO request can be for NVMe target device
(where PRP's page is used for framing PRP's) or can be for SCSI target
device (where chain buffers are used for framing chain SGE's). This patch
modifies the driver to reuse same pre-allocated PRP page buffers as a chain
buffer for IO's targeted for SCSI target devices. No need to allocate
separate buffers for chain SGE's buffers.

Suppose if the number of chain buffers need for IO doesn't fit in the PRP
Page size then driver maintain's separate buffers for those extra chain
buffers that exceeds the PRP page size. For example consider PRP page size
as 4K and chain buffer size as 128 bytes, then number of chain buffers that
can fit in PRP page is 4096/128 => 32. if the number of chain buffer need
per IO exceeds 32; for example consider number of chains need per IO is 36
then for remaining 4 chain buffer's driver allocates them individual.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 1e8e399..701e1e7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4188,7 +4188,8 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
kfree(ioc->internal_lookup);
if (ioc->chain_lookup) {
for (i = 0; i < ioc->scsiio_depth; i++) {
-   for (j = 0; j < ioc->chains_needed_per_io; j++) {
+   for (j = ioc->chains_per_prp_buffer;
+   j < ioc->chains_needed_per_io; j++) {
ct = &ioc->chain_lookup[i].chains_per_smid[j];
if (ct && ct->chain_buffer)
dma_pool_free(ioc->chain_dma_pool,
@@ -4506,7 +4507,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->chain_lookup = kzalloc(sz, GFP_KERNEL);
if (!ioc->chain_lookup) {
pr_err(MPT3SAS_FMT "chain_lookup: __get_free_pages "
-   "failed\n", ioc->name);
+   "failed\n", ioc->name);
goto out;
}
 
@@ -4520,33 +4521,6 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
}
}
 
-   ioc->chain_dma_pool = dma_pool_create("chain pool", &ioc->pdev->dev,
-   ioc->chain_segment_sz, 16, 0);
-   if (!ioc->chain_dma_pool) {
-   pr_err(MPT3SAS_FMT "chain_dma_pool: dma_pool_create failed\n",
-   ioc->name);
-   goto out;
-   }
-   for (i = 0; i < ioc->scsiio_depth; i++) {
-   for (j = 0; j < ioc->chains_needed_per_io; j++) {
-   ct = &ioc->chain_lookup[i].chains_per_smid[j];
-   ct->chain_buffer = dma_pool_alloc(
-   ioc->chain_dma_pool , GFP_KERNEL,
-   &ct->chain_buffer_dma);
-   if (!ct->chain_buffer) {
-   pr_err(MPT3SAS_FMT "chain_lookup: "
-   " pci_pool_alloc failed\n", ioc->name);
-   goto out;
-   }
-   }
-   total_sz += ioc->chain_segment_sz;
-   }
-
-   dinitprintk(ioc, pr_info(MPT3SAS_FMT
-   "chain pool depth(%d), frame_size(%d), pool_size(%d kB)\n",
-   ioc->name, ioc->chain_depth, ioc->chain_segment_sz,
-   ((ioc->chain_depth *  ioc->chain_segment_sz))/1024));
-
/* initialize hi-priority queue smid's */
ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth,
sizeof(struct request_tracker), GFP_KERNEL);
@@ -4587,6 +4561,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 * be required for NVMe PRP's, only each set of NVMe blocks will be
 * contiguous, so a new set is allocated for each possible I/O.
 */
+   ioc->chains_per_prp_buffer = 0;
if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_NVME_DEVICES) {
nvme_blocks_needed =
(ioc->shost->sg_tablesize * NVME_PRP_SIZE) - 1;
@@ -4609,6 +4584,11 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->name);
goto out;
  

[PATCH 12/15] mpt3sas: Update MPI Headers

2018-03-30 Thread Chaitra P B
Update MPI Files to support protocol level reset for NVMe device.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2.h  |  9 ++---
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 30 --
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |  7 ++-
 3 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h
index b015c30..1e45268 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2.h
@@ -9,7 +9,7 @@
  * scatter/gather formats.
  * Creation Date:  June 21, 2006
  *
- * mpi2.h Version:  02.00.48
+ *  mpi2.h Version:  02.00.50
  *
  * 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
@@ -114,6 +114,8 @@
  * 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.
+ * 06-13-17  02.00.49  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 09-29-17  02.00.50  Bumped MPI2_HEADER_VERSION_UNIT.
  * --
  */
 
@@ -152,8 +154,9 @@
MPI26_VERSION_MINOR)
 #define MPI2_VERSION_02_06 (0x0206)
 
-/*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT(0x30)
+
+/* Unit and Dev versioning for this MPI header set */
+#define MPI2_HEADER_VERSION_UNIT(0x32)
 #define MPI2_HEADER_VERSION_DEV (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK   (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT  (8)
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
index 0ad88de..5122920 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
@@ -7,7 +7,7 @@
  * Title:  MPI Configuration messages and pages
  * Creation Date:  November 10, 2006
  *
- *   mpi2_cnfg.h Version:  02.00.40
+ *mpi2_cnfg.h Version:  02.00.42
  *
  * 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
@@ -219,6 +219,18 @@
  * Added ChassisSlot field to SAS Enclosure Page 0.
  * Added ChassisSlot Valid bit (bit 5) to the Flags field
  * in SAS Enclosure Page 0.
+ * 06-13-17  02.00.41  Added MPI26_MFGPAGE_DEVID_SAS3816 and
+ * MPI26_MFGPAGE_DEVID_SAS3916 defines.
+ * Removed MPI26_MFGPAGE_DEVID_SAS4008 define.
+ * Added MPI26_PCIEIOUNIT1_LINKFLAGS_SRNS_EN define.
+ * Renamed PI26_PCIEIOUNIT1_LINKFLAGS_EN_SRIS to
+ * PI26_PCIEIOUNIT1_LINKFLAGS_SRIS_EN.
+ * Renamed MPI26_PCIEIOUNIT1_LINKFLAGS_DIS_SRIS to
+ * MPI26_PCIEIOUNIT1_LINKFLAGS_DIS_SEPARATE_REFCLK.
+ * 09-29-17  02.00.42  Added ControllerResetTO field to PCIe Device Page 2.
+ * Added NOIOB field to PCIe Device Page 2.
+ * Added MPI26_PCIEDEV2_CAP_DATA_BLK_ALIGN_AND_GRAN to
+ * the Capabilities field of PCIe Device Page 2.
  * --
  */
 
@@ -556,7 +568,8 @@ typedef struct _MPI2_CONFIG_REPLY {
 #define MPI26_MFGPAGE_DEVID_SAS3616 (0x00D1)
 #define MPI26_MFGPAGE_DEVID_SAS3708 (0x00D2)
 
-#define MPI26_MFGPAGE_DEVID_SAS4008 (0x00A1)
+#define MPI26_MFGPAGE_DEVID_SAS3816 (0x00A1)
+#define MPI26_MFGPAGE_DEVID_SAS3916 (0x00A0)
 
 
 /*Manufacturing Page 0 */
@@ -3864,20 +3877,25 @@ typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_0 {
 typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_2 {
MPI2_CONFIG_EXTENDED_PAGE_HEADERHeader; /*0x00 */
U16 DevHandle;  /*0x08 */
-   U16 Reserved1;  /*0x0A */
-   U32 MaximumDataTransferSize;/*0x0C */
+   U8  ControllerResetTO;  /* 0x0A */
+   U8  Reserved1;  /* 0x0B */
+   U32 MaximumDataTransferSize;/*0x0C */
U32 Capabilities;   /*0x10 */
-   U32 Reserved2;  /*0x14 */
+   U16 NOIOB;  /* 0x14 */
+   U16 Reserved2;  /* 0x16 */
 } MPI26_CONFIG_PAGE_PCIEDEV_2, *PTR_MPI26_CONFIG_PAGE_PCIEDEV_2,
Mpi26PCIeDevicePage2_t, *pMpi26PCIeDevicePage2_t;
 
-#define MPI26_PCIEDEVICE2_PAGEVERSION   (0x00)
+#define MPI26_PCIEDEVICE2_PAGEVERSION   (0x01)
 
 /*defines for PCIe Device Page 2 Capabilities field */
+#define MPI26_PCIEDEV2_CAP_DATA_BLK_ALIGN_AND_GRAN (0x0008)
 #define MPI26_PCIEDEV2_CAP_SGL_FORMAT  (0x0004)
 #define

[PATCH 04/15] mpt3sas: Lockless access for chain buffers.

2018-03-30 Thread Chaitra P B
Introduces Chain lookup table/tracker and implements accessing chain buffer
using smid.
Removed link list based access of chain buffer which requires lock and
allocated as many chains needed.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index a79c6df..1e8e399 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -297,12 +297,15 @@ static void *
 _base_get_chain_buffer_dma_to_chain_buffer(struct MPT3SAS_ADAPTER *ioc,
dma_addr_t chain_buffer_dma)
 {
-   u16 index;
-
-   for (index = 0; index < ioc->chain_depth; index++) {
-   if (ioc->chain_lookup[index].chain_buffer_dma ==
-   chain_buffer_dma)
-   return ioc->chain_lookup[index].chain_buffer;
+   u16 index, j;
+   struct chain_tracker *ct;
+
+   for (index = 0; index < ioc->scsiio_depth; index++) {
+   for (j = 0; j < ioc->chains_needed_per_io; j++) {
+   ct = &ioc->chain_lookup[index].chains_per_smid[j];
+   if (ct && ct->chain_buffer_dma == chain_buffer_dma)
+   return ct->chain_buffer;
+   }
}
pr_info(MPT3SAS_FMT
"Provided chain_buffer_dma address is not in the lookup list\n",
@@ -1678,7 +1681,8 @@ _base_add_sg_single_64(void *paddr, u32 flags_length, 
dma_addr_t dma_addr)
  * @ioc: per adapter object
  * @scmd: SCSI commands of the IO request
  *
- * Returns chain tracker(from ioc->free_chain_list)
+ * Returns chain tracker from chain_lookup table using key as
+ * smid and smid's chain_offset.
  */
 static struct chain_tracker *
 _base_get_chain_buffer_tracker(struct MPT3SAS_ADAPTER *ioc,
@@ -1686,20 +1690,15 @@ _base_get_chain_buffer_tracker(struct MPT3SAS_ADAPTER 
*ioc,
 {
struct chain_tracker *chain_req;
struct scsiio_tracker *st = scsi_cmd_priv(scmd);
-   unsigned long flags;
+   u16 smid = st->smid;
+   u8 chain_offset =
+  atomic_read(&ioc->chain_lookup[smid - 1].chain_offset);
 
-   spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-   if (list_empty(&ioc->free_chain_list)) {
-   spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-   dfailprintk(ioc, pr_warn(MPT3SAS_FMT
-   "chain buffers not available\n", ioc->name));
+   if (chain_offset == ioc->chains_needed_per_io)
return NULL;
-   }
-   chain_req = list_entry(ioc->free_chain_list.next,
-   struct chain_tracker, tracker_list);
-   list_del_init(&chain_req->tracker_list);
-   list_add_tail(&chain_req->tracker_list, &st->chain_list);
-   spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
+
+   chain_req = &ioc->chain_lookup[smid - 1].chains_per_smid[chain_offset];
+   atomic_inc(&ioc->chain_lookup[smid - 1].chain_offset);
return chain_req;
 }
 
@@ -3278,13 +3277,7 @@ void mpt3sas_base_clear_st(struct MPT3SAS_ADAPTER *ioc,
return;
st->cb_idx = 0xFF;
st->direct_io = 0;
-   if (!list_empty(&st->chain_list)) {
-   unsigned long flags;
-
-   spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-   list_splice_init(&st->chain_list, &ioc->free_chain_list);
-   spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-   }
+   atomic_set(&ioc->chain_lookup[st->smid - 1].chain_offset, 0);
 }
 
 /**
@@ -4102,6 +4095,8 @@ static void
 _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 {
int i = 0;
+   int j = 0;
+   struct chain_tracker *ct;
struct reply_post_struct *rps;
 
dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
@@ -4192,14 +4187,18 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
kfree(ioc->hpr_lookup);
kfree(ioc->internal_lookup);
if (ioc->chain_lookup) {
-   for (i = 0; i < ioc->chain_depth; i++) {
-   if (ioc->chain_lookup[i].chain_buffer)
-   dma_pool_free(ioc->chain_dma_pool,
-   ioc->chain_lookup[i].chain_buffer,
-   ioc->chain_lookup[i].chain_buffer_dma);
+   for (i = 0; i < ioc->scsiio_depth; i++) {
+   for (j = 0; j < ioc->chains_needed_per_io; j++) {
+   ct = &ioc->chain_lookup[i].chains

[PATCH 13/15] mpt3sas: For NVME device, issue a protocol level reset instead of hot reset and use TM timeout value exposed in PCIe Device Page 2.

2018-03-30 Thread Chaitra P B
1)Manufacturing Page 11 contains parameters to control
internal firmware behavior. Based on AddlFlags2 field
FW/Driver behaviour can be changed, (flag tm_custom_handling
is used for this)

a) For PCIe device, protocol level reset should be used if
flag tm_custom_handling is 0.
Since Abort Task Set, LUN reset and Target reset will result
in a protocol level reset. Drivers should issue only one type
of this reset, if that fails then it should escalate to a controller
reset (diag reset/OCR).
b) If the driver has control over the TM reset timeout value, then
driver should use the value exposed in PCIe Device Page 2 for pcie device
(field ControllerResetTO).

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 13 ++
 drivers/scsi/mpt3sas/mpt3sas_base.h  | 26 ++--
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 22 +--
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 76 ++--
 4 files changed, 116 insertions(+), 21 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 94c69aa..9dd052f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4145,6 +4145,7 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
Mpi2ConfigReply_t mpi_reply;
u32 iounit_pg1_flags;
 
+   ioc->nvme_abort_timeout = 30;
mpt3sas_config_get_manufacturing_pg0(ioc, &mpi_reply, &ioc->manu_pg0);
if (ioc->ir_firmware)
mpt3sas_config_get_manufacturing_pg10(ioc, &mpi_reply,
@@ -4163,6 +4164,18 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
mpt3sas_config_set_manufacturing_pg11(ioc, &mpi_reply,
&ioc->manu_pg11);
}
+   if (ioc->manu_pg11.AddlFlags2 & NVME_TASK_MNGT_CUSTOM_MASK)
+   ioc->tm_custom_handling = 1;
+   else {
+   ioc->tm_custom_handling = 0;
+   if (ioc->manu_pg11.NVMeAbortTO < NVME_TASK_ABORT_MIN_TIMEOUT)
+   ioc->nvme_abort_timeout = NVME_TASK_ABORT_MIN_TIMEOUT;
+   else if (ioc->manu_pg11.NVMeAbortTO >
+   NVME_TASK_ABORT_MAX_TIMEOUT)
+   ioc->nvme_abort_timeout = NVME_TASK_ABORT_MAX_TIMEOUT;
+   else
+   ioc->nvme_abort_timeout = ioc->manu_pg11.NVMeAbortTO;
+   }
 
mpt3sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2);
mpt3sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 20fe90d..6a9657e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -146,8 +146,12 @@
 #defineNVME_CMD_PRP1_OFFSET24  /* PRP1 offset in NVMe 
cmd */
 #defineNVME_CMD_PRP2_OFFSET32  /* PRP2 offset in NVMe 
cmd */
 #defineNVME_ERROR_RESPONSE_SIZE16  /* Max NVME Error 
Response */
+#define NVME_TASK_ABORT_MIN_TIMEOUT6
+#define NVME_TASK_ABORT_MAX_TIMEOUT60
+#define NVME_TASK_MNGT_CUSTOM_MASK (0x0010)
 #defineNVME_PRP_PAGE_SIZE  4096/* Page size */
 
+
 /*
  * reset phases
  */
@@ -363,7 +367,15 @@ struct Mpi2ManufacturingPage11_t {
u8  EEDPTagMode;/* 09h */
u8  Reserved3;  /* 0Ah */
u8  Reserved4;  /* 0Bh */
-   __le32  Reserved5[23];  /* 0Ch-60h*/
+   __le32  Reserved5[8];   /* 0Ch-2Ch */
+   u16 AddlFlags2; /* 2Ch */
+   u8  AddlFlags3; /* 2Eh */
+   u8  Reserved6;  /* 2Fh */
+   __le32  Reserved7[7];   /* 30h - 4Bh */
+   u8  NVMeAbortTO;/* 4Ch */
+   u8  Reserved8;  /* 4Dh */
+   u16 Reserved9;  /* 4Eh */
+   __le32  Reserved10[4];  /* 50h - 60h */
 };
 
 /**
@@ -573,6 +585,7 @@ struct _pcie_device {
u8  enclosure_level;
u8  connector_name[4];
u8  *serial_number;
+   u8  reset_timeout;
struct kref refcount;
 };
 /**
@@ -1211,6 +1224,10 @@ struct MPT3SAS_ADAPTER {
void*event_log;
u32 event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
 
+   u8  tm_custom_handling;
+   u8  nvme_abort_timeout;
+
+
/* static config pages */
struct mpt3sas_facts facts;
struct mpt3sas_port_facts *pfacts;
@@ -1470,10 +1487,11 @@ u8 mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER 
*ioc, u8 msix_index,
u32 reply);
 void mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase);

[PATCH 09/15] mpt3sas: Allow processing of events during driver unload.

2018-03-30 Thread Chaitra P B
Events were not processed during driver unload, hence unloading of driver
doesn't complete when drives are disconnected while unloading of driver.
So don't block events in ISR path, i,e., remove the flag ioc->remove_host
so that events are getting processed during driver unload.
Thus allowing driver unload to complete by processing drive removal events
during driver unload.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index ec86ec5..9d7099d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3677,11 +3677,7 @@ _scsih_tm_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 
smid, u8 msix_index,
u32 ioc_state;
struct _sc_list *delayed_sc;
 
-   if (ioc->remove_host) {
-   dewtprintk(ioc, pr_info(MPT3SAS_FMT
-   "%s: host has been removed\n", __func__, ioc->name));
-   return 1;
-   } else if (ioc->pci_error_recovery) {
+   if (ioc->pci_error_recovery) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: host in pci error recovery\n", __func__,
ioc->name));
@@ -3803,8 +3799,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
u16 smid;
struct _tr_list *delayed_tr;
 
-   if (ioc->shost_recovery || ioc->remove_host ||
-   ioc->pci_error_recovery) {
+   if (ioc->pci_error_recovery) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: host reset in progress!\n",
__func__, ioc->name));
@@ -3857,8 +3852,7 @@ _scsih_tm_volume_tr_complete(struct MPT3SAS_ADAPTER *ioc, 
u16 smid,
Mpi2SCSITaskManagementReply_t *mpi_reply =
mpt3sas_base_get_reply_virt_addr(ioc, reply);
 
-   if (ioc->shost_recovery || ioc->remove_host ||
-   ioc->pci_error_recovery) {
+   if (ioc->shost_recovery || ioc->pci_error_recovery) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: host reset in progress!\n",
__func__, ioc->name));
@@ -9477,8 +9471,8 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, 
u8 msix_index,
u16 sz;
Mpi26EventDataActiveCableExcept_t *ActiveCableEventData;
 
-   /* events turned off due to host reset or driver unloading */
-   if (ioc->remove_host || ioc->pci_error_recovery)
+   /* events turned off due to host reset */
+   if (ioc->pci_error_recovery)
return 1;
 
mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
-- 
1.8.3.1



[PATCH 15/15] mpt3sas: Update driver version "25.100.00.00"

2018-03-30 Thread Chaitra P B
Update driver version to match OOB/internal driver version.

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 6a9657e..693b04b 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 "17.100.00.00"
-#define MPT3SAS_MAJOR_VERSION  17
+#define MPT3SAS_DRIVER_VERSION "25.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  25
 #define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
-- 
1.8.3.1



[PATCH 10/15] mpt3sas: Cache enclosure pages during enclosure add.

2018-03-30 Thread Chaitra P B
In function _scsih_add_device,
for each device connected to an enclosure, driver reads the
enclosure page(To get details like enclosure handle,
enclosure logical ID, enclosure level etc.)

With this patch, instead of reading enclosure page everytime,
driver maintains a list for enclosure device(During enclosure
add event, enclosure device is added to the list and removed
from the list on delete events) and uses the enclosure page
from the list.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  22 +++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  14 ++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 297 ---
 3 files changed, 237 insertions(+), 96 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 3f3f0f0..dca0782 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4087,6 +4087,27 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * mpt3sas_free_enclosure_list - release memory
+ * @ioc: per adapter object
+ *
+ * Free memory allocated during encloure add.
+ *
+ * Return nothing.
+ */
+void
+mpt3sas_free_enclosure_list(struct MPT3SAS_ADAPTER *ioc)
+{
+   struct _enclosure_node *enclosure_dev, *enclosure_dev_next;
+
+   /* Free enclosure list */
+   list_for_each_entry_safe(enclosure_dev,
+   enclosure_dev_next, &ioc->enclosure_list, list) {
+   list_del(&enclosure_dev->list);
+   kfree(enclosure_dev);
+   }
+}
+
+/**
  * _base_release_memory_pools - release memory
  * @ioc: per adapter object
  *
@@ -6667,6 +6688,7 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc)
mpt3sas_base_stop_watchdog(ioc);
mpt3sas_base_free_resources(ioc);
_base_release_memory_pools(ioc);
+   mpt3sas_free_enclosure_list(ioc);
pci_set_drvdata(ioc->pdev, NULL);
kfree(ioc->cpu_msix_table);
if (ioc->is_warpdrive)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index a0fca8a..6f3329e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -741,6 +741,17 @@ struct _sas_node {
struct list_head sas_port_list;
 };
 
+
+/**
+ * struct _enclosure_node - enclosure information
+ * @list: list of enclosures
+ * @pg0: enclosure pg0;
+ */
+struct _enclosure_node {
+   struct list_head list;
+   Mpi2SasEnclosurePage0_t pg0;
+};
+
 /**
  * enum reset_type - reset state
  * @FORCE_BIG_HAMMER: issue diagnostic reset
@@ -1013,6 +1024,7 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct 
MPT3SAS_ADAPTER *ioc);
  * @iounit_pg8: static iounit page 8
  * @sas_hba: sas host object
  * @sas_expander_list: expander object list
+ * @enclosure_list: enclosure object list
  * @sas_node_lock:
  * @sas_device_list: sas device object list
  * @sas_device_init_list: sas device object list (used only at init time)
@@ -1218,6 +1230,7 @@ struct MPT3SAS_ADAPTER {
/* sas hba, expander, and device list */
struct _sas_node sas_hba;
struct list_head sas_expander_list;
+   struct list_head enclosure_list;
spinlock_t  sas_node_lock;
struct list_head sas_device_list;
struct list_head sas_device_init_list;
@@ -1391,6 +1404,7 @@ int mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc);
 int mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc);
+void mpt3sas_free_enclosure_list(struct MPT3SAS_ADAPTER *ioc);
 int mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
enum reset_type type);
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 9d7099d..dabeeaf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1362,6 +1362,30 @@ mpt3sas_scsih_expander_find_by_handle(struct 
MPT3SAS_ADAPTER *ioc, u16 handle)
 }
 
 /**
+ * mpt3sas_scsih_enclosure_find_by_handle - exclosure device search
+ * @ioc: per adapter object
+ * @handle: enclosure handle (assigned by firmware)
+ * Context: Calling function should acquire ioc->sas_device_lock
+ *
+ * This searches for enclosure device based on handle, then returns the
+ * enclosure object.
+ */
+static struct _enclosure_node *
+mpt3sas_scsih_enclosure_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+   struct _enclosure_node *enclosure_dev, *r;
+
+   r = NULL;
+   list_for_each_entry(enclosure_dev, &ioc->enclosure_list, list) {
+   if (le16_to_cpu(enclosure_dev->pg0.EnclosureHandle) != handle)
+   continue;
+   r = enclosure_dev;
+   goto out;
+   }
+out:
+   return r;
+}
+/**
  * mpt3sas_scsih_expander_find_by_sas_address - expander device

[PATCH 11/15] mpt3sas: Report Firmware Package Version from HBA Driver.

2018-03-30 Thread Chaitra P B
Added function _base_display_fwpkg_version, which sends FWUpload
request to pull FW package version from FW Image Header.
Now driver prints FW package version in addition to FW
version if the PackageVersion is valid.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index dca0782..94c69aa 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -3825,6 +3825,111 @@ _base_display_OEMs_branding(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * _base_display_fwpkg_version - sends FWUpload request to pull FWPkg
+ * version from FW Image Header.
+ * @ioc: per adapter object
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+   static int
+_base_display_fwpkg_version(struct MPT3SAS_ADAPTER *ioc)
+{
+   Mpi2FWImageHeader_t *FWImgHdr;
+   Mpi25FWUploadRequest_t *mpi_request;
+   Mpi2FWUploadReply_t mpi_reply;
+   int r = 0;
+   void *fwpkg_data = NULL;
+   dma_addr_t fwpkg_data_dma;
+   u16 smid, ioc_status;
+   size_t data_length;
+
+   dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
+   __func__));
+
+   if (ioc->base_cmds.status & MPT3_CMD_PENDING) {
+   pr_err(MPT3SAS_FMT "%s: internal command already in use\n",
+   ioc->name, __func__);
+   return -EAGAIN;
+   }
+
+   data_length = sizeof(Mpi2FWImageHeader_t);
+   fwpkg_data = pci_alloc_consistent(ioc->pdev, data_length,
+   &fwpkg_data_dma);
+   if (!fwpkg_data) {
+   pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
+   ioc->name, __FILE__, __LINE__, __func__);
+   return -ENOMEM;
+   }
+
+   smid = mpt3sas_base_get_smid(ioc, ioc->base_cb_idx);
+   if (!smid) {
+   pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
+   ioc->name, __func__);
+   r = -EAGAIN;
+   goto out;
+   }
+
+   ioc->base_cmds.status = MPT3_CMD_PENDING;
+   mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
+   ioc->base_cmds.smid = smid;
+   memset(mpi_request, 0, sizeof(Mpi25FWUploadRequest_t));
+   mpi_request->Function = MPI2_FUNCTION_FW_UPLOAD;
+   mpi_request->ImageType = MPI2_FW_UPLOAD_ITYPE_FW_FLASH;
+   mpi_request->ImageSize = data_length;
+   ioc->build_sg(ioc, &mpi_request->SGL, 0, 0, fwpkg_data_dma,
+   data_length);
+   init_completion(&ioc->base_cmds.done);
+   mpt3sas_base_put_smid_default(ioc, smid);
+   /* Wait for 15 seconds */
+   wait_for_completion_timeout(&ioc->base_cmds.done,
+   FW_IMG_HDR_READ_TIMEOUT*HZ);
+   pr_info(MPT3SAS_FMT "%s: complete\n",
+   ioc->name, __func__);
+   if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) {
+   pr_err(MPT3SAS_FMT "%s: timeout\n",
+   ioc->name, __func__);
+   _debug_dump_mf(mpi_request,
+   sizeof(Mpi25FWUploadRequest_t)/4);
+   r = -ETIME;
+   } else {
+   memset(&mpi_reply, 0, sizeof(Mpi2FWUploadReply_t));
+   if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) {
+   memcpy(&mpi_reply, ioc->base_cmds.reply,
+   sizeof(Mpi2FWUploadReply_t));
+   ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+   MPI2_IOCSTATUS_MASK;
+   if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
+   FWImgHdr = (Mpi2FWImageHeader_t *)fwpkg_data;
+   FWImgHdr->PackageVersion.Word =
+   le32_to_cpu(FWImgHdr->PackageVersion.Word);
+   if (FWImgHdr->PackageVersion.Word) {
+   pr_info(MPT3SAS_FMT "FW Package Version"
+   "(%02d.%02d.%02d.%02d)\n",
+   ioc->name,
+   ((FWImgHdr->PackageVersion.Word)
+   & 0xFF00) >> 24,
+   ((FWImgHdr->PackageVersion.Word)
+   & 0x00FF) >> 16

[PATCH 14/15] mpt3sas: fix possible memory leak.

2018-03-30 Thread Chaitra P B
In ioctl exit path driver refers ioc_list to free memory associated with
diag buffers and event_log pointer used to save events by driver.
If ctl_exit() func is called after unregistering driver, then ioc_list will
be empty and hence driver will not be able to free the allocated memory
which in turn causes memory leak.
So call ctl_exit() function before unregistering mpt3sas driver.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index f5344cc..562b13d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -11286,10 +11286,10 @@ _mpt3sas_exit(void)
pr_info("mpt3sas version %s unloading\n",
MPT3SAS_DRIVER_VERSION);
 
-   pci_unregister_driver(&mpt3sas_driver);
-
mpt3sas_ctl_exit(hbas_to_enumerate);
 
+   pci_unregister_driver(&mpt3sas_driver);
+
scsih_exit();
 }
 
-- 
1.8.3.1



[PATCH 08/15] mpt3sas: Increase event log buffer to support 24 port HBA's.

2018-03-30 Thread Chaitra P B
For 24 port HBA's events generated by IOC are more in certain cases and
the current circular buffer may be overwritten.Hence increased the event
log buffer to accommodate more events.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
index a44046c..18b46fa 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
@@ -184,7 +184,7 @@ struct mpt3_ioctl_iocinfo {
 
 
 /* number of event log entries */
-#define MPT3SAS_CTL_EVENT_LOG_SIZE (50)
+#define MPT3SAS_CTL_EVENT_LOG_SIZE (200)
 
 /**
  * struct mpt3_ioctl_eventquery - query event count and type
-- 
1.8.3.1



[PATCH 07/15] mpt3sas: Added support for SAS Device Discovery Error Event.

2018-03-30 Thread Chaitra P B
The SAS Device Discovery Error Event is sent to the host when
discovery for a particular device is failed during discovery,
even after maximum retries by the IOC.

In this patch driver unmask the events and displays the details
associated with the event.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 7f3b684..3f3f0f0 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1029,6 +1029,9 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
desc = "Cable Event";
break;
+   case MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
+   desc = "SAS Device Discovery Error";
+   break;
case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
desc = "PCIE Device Status Change";
break;
@@ -6597,6 +6600,7 @@ 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);
+   _base_unmask_events(ioc, MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR);
if (ioc->hba_mpi_version_belonged == MPI26_VERSION) {
if (ioc->is_gen35_ioc) {
_base_unmask_events(ioc,
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 6b1aaa0..ec86ec5 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -7531,6 +7531,46 @@ _scsih_sas_discovery_event(struct MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _scsih_sas_device_discovery_error_event - display SAS device discovery error
+ * events
+ * @ioc: per adapter object
+ * @fw_event: The fw_event_work object
+ * Context: user.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_sas_device_discovery_error_event(struct MPT3SAS_ADAPTER *ioc,
+   struct fw_event_work *fw_event)
+{
+   Mpi25EventDataSasDeviceDiscoveryError_t *event_data =
+   (Mpi25EventDataSasDeviceDiscoveryError_t *)fw_event->event_data;
+
+   switch (event_data->ReasonCode) {
+
+   case MPI25_EVENT_SAS_DISC_ERR_SMP_FAILED:
+   pr_warn(MPT3SAS_FMT "SMP command sent to the expander"
+   "(handle:0x%04x, sas_address:0x%016llx,"
+   "physical_port:0x%02x) has failed",
+   ioc->name, le16_to_cpu(event_data->DevHandle),
+   (unsigned long long)le64_to_cpu(event_data->SASAddress),
+   event_data->PhysicalPort);
+   break;
+
+   case MPI25_EVENT_SAS_DISC_ERR_SMP_TIMEOUT:
+   pr_warn(MPT3SAS_FMT "SMP command sent to the expander"
+   "(handle:0x%04x, sas_address:0x%016llx,"
+   "physical_port:0x%02x) has timed out",
+   ioc->name, le16_to_cpu(event_data->DevHandle),
+   (unsigned long long)le64_to_cpu(event_data->SASAddress),
+   event_data->PhysicalPort);
+   break;
+   default:
+   break;
+   }
+}
+
+/**
  * _scsih_pcie_enumeration_event - handle enumeration events
  * @ioc: per adapter object
  * @fw_event: The fw_event_work object
@@ -9357,6 +9397,9 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct 
fw_event_work *fw_event)
case MPI2_EVENT_SAS_DISCOVERY:
_scsih_sas_discovery_event(ioc, fw_event);
break;
+   case MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
+   _scsih_sas_device_discovery_error_event(ioc, fw_event);
+   break;
case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
_scsih_sas_broadcast_primitive_event(ioc, fw_event);
break;
@@ -9541,6 +9584,7 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, 
u8 msix_index,
case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
case MPI2_EVENT_IR_OPERATION_STATUS:
case MPI2_EVENT_SAS_DISCOVERY:
+   case MPI2_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
case MPI2_EVENT_IR_PHYSICAL_DISK:
case MPI2_EVENT_PCIE_ENUMERATION:
-- 
1.8.3.1



[PATCH 01/15] mpt3sas: Fixed warnings.

2018-03-30 Thread Chaitra P B
This patch fixes sparse warnings observed during compilation.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |  2 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 57 +-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  6 ++--
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 11 +++---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 59 +++-
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |  3 +-
 6 files changed, 73 insertions(+), 65 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_init.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_init.h
index 948a3ba..6213ce6 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_init.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_init.h
@@ -75,7 +75,7 @@
 
 typedef struct _MPI2_SCSI_IO_CDB_EEDP32 {
U8 CDB[20]; /*0x00 */
-   U32 PrimaryReferenceTag;/*0x14 */
+   __be32 PrimaryReferenceTag; /*0x14 */
U16 PrimaryApplicationTag;  /*0x18 */
U16 PrimaryApplicationTagMask;  /*0x1A */
U32 TransferLength; /*0x1C */
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 0a0e7aa..4767690 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -394,13 +394,14 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
buff_ptr_phys = buffer_iomem_phys;
WARN_ON(buff_ptr_phys > U32_MAX);
 
-   if (sgel->FlagsLength &
+   if (le32_to_cpu(sgel->FlagsLength) &
(MPI2_SGE_FLAGS_HOST_TO_IOC << MPI2_SGE_FLAGS_SHIFT))
is_write = 1;
 
for (i = 0; i < MPT_MIN_PHYS_SEGMENTS + ioc->facts.MaxChainDepth; i++) {
 
-   sgl_flags = (sgel->FlagsLength >> MPI2_SGE_FLAGS_SHIFT);
+   sgl_flags =
+   (le32_to_cpu(sgel->FlagsLength) >> MPI2_SGE_FLAGS_SHIFT);
 
switch (sgl_flags & MPI2_SGE_FLAGS_ELEMENT_MASK) {
case MPI2_SGE_FLAGS_CHAIN_ELEMENT:
@@ -411,7 +412,7 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
 */
sgel_next =
_base_get_chain_buffer_dma_to_chain_buffer(ioc,
-   sgel->Address);
+   le32_to_cpu(sgel->Address));
if (sgel_next == NULL)
return;
/*
@@ -426,7 +427,7 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
dst_addr_phys = _base_get_chain_phys(ioc,
smid, sge_chain_count);
WARN_ON(dst_addr_phys > U32_MAX);
-   sgel->Address = (u32)dst_addr_phys;
+   sgel->Address = cpu_to_le32((u32)dst_addr_phys);
sgel = sgel_next;
sge_chain_count++;
break;
@@ -435,22 +436,28 @@ static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
if (is_scsiio_req) {
_base_clone_to_sys_mem(buff_ptr,
sg_virt(sg_scmd),
-   (sgel->FlagsLength & 0x00ff));
+   (le32_to_cpu(sgel->FlagsLength) &
+   0x00ff));
/*
 * FIXME: this relies on a a zero
 * PCI mem_offset.
 */
-   sgel->Address = (u32)buff_ptr_phys;
+   sgel->Address =
+   cpu_to_le32((u32)buff_ptr_phys);
} else {
_base_clone_to_sys_mem(buff_ptr,
ioc->config_vaddr,
-   (sgel->FlagsLength & 0x00ff));
-   sgel->Address = (u32)buff_ptr_phys;
+   (le32_to_cpu(sgel->FlagsLength) &
+   0x00ff));
+   sgel->Address =
+   cpu_to_le32((u32)buff_ptr_phys);
}
}
-   buff_ptr += (sgel->FlagsLength & 0x00ff);
-   buff_ptr_phys += (sgel->FlagsLength & 0x00ff);
-   if ((sgel->FlagsLength &
+   buff_ptr += (le32_to_cpu(sge

[PATCH 00/15] mpt3sas: Enhancements and Defect fixes.

2018-03-30 Thread Chaitra P B
Chaitra P B (15):
  mpt3sas: Fixed warnings.
  mpt3sas: Pre-allocate RDPQ Array at driver boot time.
  mpt3sas: Add sanity checks for scsi tracker before accessing it.
  mpt3sas: Lockless access for chain buffers.
  mpt3sas: Optimize I/O memory consumption in driver.
  mpt3sas: Enhanced handling of Sense Buffer.
  mpt3sas: Added support for SAS Device Discovery Error Event.
  mpt3sas: Increase event log buffer to support 24 port HBA's.
  mpt3sas: Allow processing of events during driver unload.
  mpt3sas: Cache enclosure pages during enclosure add.
  mpt3sas: Report Firmware Package Version from HBA Driver.
  mpt3sas: Update MPI Headers
  mpt3sas: For NVME device, issue a protocol level reset instead of
hot reset and use TM timeout value exposed in PCIe Device Page  2.
  mpt3sas: fix possible memory leak.
  mpt3sas: Update driver version "25.100.00.00"

 drivers/scsi/mpt3sas/mpi/mpi2.h  |   9 +-
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h |  30 +-
 drivers/scsi/mpt3sas/mpi/mpi2_init.h |   2 +-
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |   7 +-
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 484 ++---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  62 +++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  38 ++-
 drivers/scsi/mpt3sas/mpt3sas_ctl.h   |   2 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 503 +--
 drivers/scsi/mpt3sas/mpt3sas_warpdrive.c |   3 +-
 10 files changed, 840 insertions(+), 300 deletions(-)

-- 
1.8.3.1



[PATCH] mpt3sas: Cache enclosure pages during enclosure add.

2018-03-20 Thread Chaitra P B
In function _scsih_add_device,
for each device connected to a enclosure, driver reads the
enclosure page.(To get details like enclosure handle,
enclosure logical ID, enclosure level etc.)

With this patch, Instead of reading enclosure page everytime,
driver maintains a list for enclosure device.(During enclosure
add event, enclosure device is added to the list and removed
from the list on delete events). and uses the enclosure
page from the list.

1) Enclosure page is read during enclosure add event and
added to the enclosure device list.
2) Introduced function "mpt3sas_scsih_enclosure_find_by_handle",
to get enclosure device and "mpt3sas_free_enclosure_list"
frees the list.
3) And "_scsih_create_enclosure_list_after_reset" reconstructs
the list after reset.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  22 +++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  14 ++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 299 +++
 3 files changed, 238 insertions(+), 97 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 0a0e7aa..fa438e7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4082,6 +4082,27 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * mpt3sas_free_enclosure_list - release memory
+ * @ioc: per adapter object
+ *
+ * Free memory allocated during encloure add.
+ *
+ * Return nothing.
+ */
+void
+mpt3sas_free_enclosure_list(struct MPT3SAS_ADAPTER *ioc)
+{
+   struct _enclosure_node *enclosure_dev, *enclosure_dev_next;
+
+   /* Free enclosure list */
+   list_for_each_entry_safe(enclosure_dev,
+   enclosure_dev_next, &ioc->enclosure_list, list) {
+   list_del(&enclosure_dev->list);
+   kfree(enclosure_dev);
+   }
+}
+
+/**
  * _base_release_memory_pools - release memory
  * @ioc: per adapter object
  *
@@ -6555,6 +6576,7 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc)
mpt3sas_base_stop_watchdog(ioc);
mpt3sas_base_free_resources(ioc);
_base_release_memory_pools(ioc);
+   mpt3sas_free_enclosure_list(ioc);
pci_set_drvdata(ioc->pdev, NULL);
kfree(ioc->cpu_msix_table);
if (ioc->is_warpdrive)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 4de0251..35252c6 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -741,6 +741,17 @@ struct _sas_node {
struct list_head sas_port_list;
 };
 
+
+/**
+ * struct _enclosure_node - enclosure information
+ * @list: list of enclosures
+ * @pg0: enclosure pg0;
+ */
+struct _enclosure_node {
+   struct list_head list;
+   Mpi2SasEnclosurePage0_t pg0;
+};
+
 /**
  * enum reset_type - reset state
  * @FORCE_BIG_HAMMER: issue diagnostic reset
@@ -1009,6 +1020,7 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct 
MPT3SAS_ADAPTER *ioc);
  * @iounit_pg8: static iounit page 8
  * @sas_hba: sas host object
  * @sas_expander_list: expander object list
+ * @enclosure_list: enclosure object list
  * @sas_node_lock:
  * @sas_device_list: sas device object list
  * @sas_device_init_list: sas device object list (used only at init time)
@@ -1214,6 +1226,7 @@ struct MPT3SAS_ADAPTER {
/* sas hba, expander, and device list */
struct _sas_node sas_hba;
struct list_head sas_expander_list;
+   struct list_head enclosure_list;
spinlock_t  sas_node_lock;
struct list_head sas_device_list;
struct list_head sas_device_init_list;
@@ -1384,6 +1397,7 @@ int mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc);
 int mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc);
 void mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc);
+void mpt3sas_free_enclosure_list(struct MPT3SAS_ADAPTER *ioc);
 int mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
enum reset_type type);
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 50efccd..2c03873 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1362,6 +1362,30 @@ mpt3sas_scsih_expander_find_by_handle(struct 
MPT3SAS_ADAPTER *ioc, u16 handle)
 }
 
 /**
+ * mpt3sas_scsih_enclosure_find_by_handle - exclosure device search
+ * @ioc: per adapter object
+ * @handle: enclosure handle (assigned by firmware)
+ * Context: Calling function should acquire ioc->sas_device_lock
+ *
+ * This searches for enclosure device based on handle, then returns the
+ * enclosure object.
+ */
+struct _enclosure_node *
+mpt3sas_scsih_enclosure_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+{
+   struct _enclosure_node *enclosure_dev, *r;
+
+   r = NULL;
+   list_for_each_entry(enclosu

[PATCH] mpt3sas: Proper handling of set/clear of "ATA command pending" flag.

2017-12-27 Thread Chaitra P B
1.In IO path, setting of "ATA command pending" flag early before device
 removal, invalid device handle etc., checks causes any new commands to be
 always returned with SAM_STAT_BUSY and when the driver removes the drive
 the SML issues SYNC Cache command and that command is always returned with
 SAM_STAT_BUSY and thus making SYNC Cache command to requeued.

2.If the driver gets an ATA PT command for a SATA drive then the driver set
 "ATA command pending" flag in device specific data structure not to allow
 any further commands until the ATA PT command is completed. However, after
 setting the flag if the driver decides to return the command back to upper
 layers without actually issuing to the firmware(I,e., returns from qcmd
 failure return paths) then the corresponding flag is not cleared and this
 prevents the driver from sending any new commands to the drive.

 This patch fixes above two issues by setting of "ATA command pending" flag
 after checking for whether device deleted, invalid device handle, device
 busy with task management. And by setting "ATA command pending" flag to
 false in all of the qcmd failure return paths after setting the flag.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 82d5612..74fca18 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4600,19 +4600,6 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd 
*scmd)
return 0;
}
 
-   /*
-* Bug work around for firmware SATL handling.  The loop
-* is based on atomic operations and ensures consistency
-* since we're lockless at this point
-*/
-   do {
-   if (test_bit(0, &sas_device_priv_data->ata_command_pending)) {
-   scmd->result = SAM_STAT_BUSY;
-   scmd->scsi_done(scmd);
-   return 0;
-   }
-   } while (_scsih_set_satl_pending(scmd, true));
-
sas_target_priv_data = sas_device_priv_data->sas_target;
 
/* invalid device handle */
@@ -4638,6 +4625,19 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd 
*scmd)
sas_device_priv_data->block)
return SCSI_MLQUEUE_DEVICE_BUSY;
 
+   /*
+* Bug work around for firmware SATL handling.  The loop
+* is based on atomic operations and ensures consistency
+* since we're lockless at this point
+*/
+   do {
+   if (test_bit(0, &sas_device_priv_data->ata_command_pending)) {
+   scmd->result = SAM_STAT_BUSY;
+   scmd->scsi_done(scmd);
+   return 0;
+   }
+   } while (_scsih_set_satl_pending(scmd, true));
+
if (scmd->sc_data_direction == DMA_FROM_DEVICE)
mpi_control = MPI2_SCSIIO_CONTROL_READ;
else if (scmd->sc_data_direction == DMA_TO_DEVICE)
@@ -4665,6 +4665,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd 
*scmd)
if (!smid) {
pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
ioc->name, __func__);
+   _scsih_set_satl_pending(scmd, false);
goto out;
}
mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
@@ -4696,6 +4697,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd 
*scmd)
pcie_device = sas_target_priv_data->pcie_dev;
if (ioc->build_sg_scmd(ioc, scmd, smid, pcie_device)) {
mpt3sas_base_free_smid(ioc, smid);
+   _scsih_set_satl_pending(scmd, false);
goto out;
}
} else
-- 
1.7.1



[PATCH v3 3/4] mpt3sas: Fix Firmware fault state 0x2100 during heavy 4K RR FIO stress test.

2017-01-23 Thread Chaitra P B
Due existence of loop in the IO path our HBA will receive heavy IOs and
also as driver is not updating the Reply Post Host Index frequently, So
there will be a high chance that our Firmware unable to find any free entry
in the Reply Post Descriptor Queue (i.e. Queue overflow occurs) and can
observe 0x2100 firmware fault.
So to fix this, we have defined a thresh hold value. After continuously
processing this thresh hold number of reply descriptors driver will update
the Reply Descriptor Host Index so that this thresh hold number of reply
descriptors entries will be freed and these entries will be available for
firmware and we won't observe this Firmware fault. We have defined this
threshold value as 1/3rd of the hba queue depth.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 722fab9..a3fe1fb 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1040,6 +1040,25 @@ _base_interrupt(int irq, void *bus_id)
reply_q->reply_post_free[reply_q->reply_post_host_index].
Default.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
completed_cmds++;
+   /* Update the reply post host index after continuously
+* processing the threshold number of Reply Descriptors.
+* So that FW can find enough entries to post the Reply
+* Descriptors in the reply descriptor post queue.
+*/
+   if (completed_cmds > ioc->hba_queue_depth/3) {
+   if (ioc->combined_reply_queue) {
+   writel(reply_q->reply_post_host_index |
+   ((msix_index  & 7) <<
+MPI2_RPHI_MSIX_INDEX_SHIFT),
+   ioc->replyPostRegisterIndex[msix_index/8]);
+   } else {
+   writel(reply_q->reply_post_host_index |
+   (msix_index <<
+MPI2_RPHI_MSIX_INDEX_SHIFT),
+   &ioc->chip->ReplyPostHostIndex);
+   }
+   completed_cmds = 1;
+   }
if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
goto out;
if (!reply_q->reply_post_host_index)
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 2/4] mpt3sas: Fix for Crusader to achieve product targets with SAS devices.

2017-01-23 Thread Chaitra P B
Small glitch/degraded performance in Crusader is improved with SAS
drives by removing unnecessary spinlocks while clearing scsi command
in drivers internal lookup table.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index f00ef88..722fab9 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -5522,6 +5522,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
goto out_free_resources;
 
ioc->non_operational_loop = 0;
+   ioc->got_task_abort_from_ioctl = 0;
return 0;
 
  out_free_resources:
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index dcb33f4..83cfa16 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1000,6 +1000,7 @@ struct MPT3SAS_ADAPTER {
u8  broadcast_aen_busy;
u16 broadcast_aen_pending;
u8  shost_recovery;
+   u8  got_task_abort_from_ioctl;
 
struct mutexreset_in_progress_mutex;
spinlock_t  ioc_reset_in_progress_lock;
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 95f0f24..02fe1c4 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -826,16 +826,18 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct 
mpt3_ioctl_command karg,
"TASK_MGMT: handle(0x%04x), task_type(0x%02x)\n",
ioc->name,
le16_to_cpu(tm_request->DevHandle), tm_request->TaskType));
-
+   ioc->got_task_abort_from_ioctl = 1;
if (tm_request->TaskType ==
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK ||
tm_request->TaskType ==
MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK) {
if (_ctl_set_task_mid(ioc, &karg, tm_request)) {
mpt3sas_base_free_smid(ioc, smid);
+   ioc->got_task_abort_from_ioctl = 0;
goto out;
}
}
+   ioc->got_task_abort_from_ioctl = 0;
 
if (test_bit(device_handle, ioc->device_remove_in_progress)) {
dtmprintk(ioc, pr_info(MPT3SAS_FMT
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 2c6a689..cc05e4f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1074,6 +1074,26 @@ _scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, u16 
smid)
 }
 
 /**
+ * __scsih_scsi_lookup_get_clear - returns scmd entry without
+ * holding any lock.
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Returns the smid stored scmd pointer.
+ * Then will dereference the stored scmd pointer.
+ */
+static inline struct scsi_cmnd *
+__scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc,
+   u16 smid)
+{
+   struct scsi_cmnd *scmd = NULL;
+
+   swap(scmd, ioc->scsi_lookup[smid - 1].scmd);
+
+   return scmd;
+}
+
+/**
  * _scsih_scsi_lookup_get_clear - returns scmd entry
  * @ioc: per adapter object
  * @smid: system request message index
@@ -1088,8 +1108,7 @@ _scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc, 
u16 smid)
struct scsi_cmnd *scmd;
 
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-   scmd = ioc->scsi_lookup[smid - 1].scmd;
-   ioc->scsi_lookup[smid - 1].scmd = NULL;
+   scmd = __scsih_scsi_lookup_get_clear(ioc, smid);
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
 
return scmd;
@@ -4659,7 +4678,13 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index, u32 reply)
unsigned long flags;
 
mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
-   scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
+
+   if (ioc->broadcast_aen_busy || ioc->pci_error_recovery ||
+   ioc->got_task_abort_from_ioctl)
+   scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
+   else
+   scmd = __scsih_scsi_lookup_get_clear(ioc, smid);
+
if (scmd == NULL)
return 1;
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 4/4] mpt3sas: Updating driver version to v15.100.00.00

2017-01-23 Thread Chaitra P B
Updated driver version to "15.100.00.00"

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
Reviewed-by: Johannes Thumshirn 
---
 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 83cfa16..4ab634f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -73,9 +73,9 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies "
 #define MPT3SAS_DESCRIPTION"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION "14.101.00.00"
-#define MPT3SAS_MAJOR_VERSION  14
-#define MPT3SAS_MINOR_VERSION  101
+#define MPT3SAS_DRIVER_VERSION "15.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  15
+#define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/4] mpt3sas: Added print to notify cable running at a degraded speed.

2017-01-23 Thread Chaitra P B
Driver processes the event MPI26_EVENT_ACTIVE_CABLE_DEGRADED
when a cable is present and is running at a degraded speed
(below the SAS3 12 Gb/s rate). Prints added
to inform the user that the cable is not running at
optimal speed.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |2 ++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   25 +
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
index 8bae305..af4be40 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
@@ -624,6 +624,8 @@ typedef struct _MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT {
 
 /* defines for ReasonCode field */
 #define MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER (0x00)
+#define MPI26_EVENT_ACTIVE_CABLE_PRESENT(0x01)
+#define MPI26_EVENT_ACTIVE_CABLE_DEGRADED   (0x02)
 
 /*Hard Reset Received Event data */
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 75f3fce..2c6a689 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -8028,15 +8028,24 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER 
*ioc, u8 msix_index,
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
ActiveCableEventData =
(Mpi26EventDataActiveCableExcept_t *) mpi_reply->EventData;
-   if (ActiveCableEventData->ReasonCode ==
-   MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER) {
-   pr_info(MPT3SAS_FMT "Currently an active cable with 
ReceptacleID %d",
-   ioc->name, ActiveCableEventData->ReceptacleID);
-   pr_info("cannot be powered and devices connected to 
this active cable");
-   pr_info("will not be seen. This active cable");
-   pr_info("requires %d mW of power",
-   ActiveCableEventData->ActiveCablePowerRequirement);
+   switch (ActiveCableEventData->ReasonCode) {
+   case MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER:
+   pr_notice(MPT3SAS_FMT "Receptacle ID %d: This active 
cable"
+ " requires %d mW of power\n", ioc->name,
+ActiveCableEventData->ReceptacleID,
+ActiveCableEventData->ActiveCablePowerRequirement);
+   pr_notice(MPT3SAS_FMT "Receptacle ID %d: Devices 
connected"
+ " to this active cable will not be seen\n",
+ioc->name, ActiveCableEventData->ReceptacleID);
+   break;
+
+   case MPI26_EVENT_ACTIVE_CABLE_DEGRADED:
+   pr_notice(MPT3SAS_FMT "ReceptacleID %d: This cable",
+   ioc->name, ActiveCableEventData->ReceptacleID);
+   pr_notice(" is not running at an optimal speed(12 
Gb/s)\n");
+   break;
}
+
break;
 
default: /* ignore the rest */
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 0/4] mpt3sas driver Enhancements and defect fixes:

2017-01-23 Thread Chaitra P B
Here is the change list:
Posting 4 patches for mpt3sas driver enhancement and defect fixes.
  * Handle cable event for notifying degraded speed.
  * Performance improvement for Crusader.
  * Fix Firmware fault state 0x2100 during heavy 4K RR
FIO stress test.
  * Updated driver version to 15.100.00.00

Chaitra P B (4):
  mpt3sas: Added print to notify cable running at a degraded
speed.
  mpt3sas: Fix for Crusader to achieve product targets with SAS
devices.
  mpt3sas: Fix Firmware fault state 0x2100 during heavy 4K RR   
FIO stress test.
  mpt3sas: Updating driver version to v15.100.00.00

 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |2 +
 drivers/scsi/mpt3sas/mpt3sas_base.c  |   20 
 drivers/scsi/mpt3sas/mpt3sas_base.h  |7 ++--
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |4 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   56 +++---
 5 files changed, 74 insertions(+), 15 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/4] mpt3sas driver Enhancements and

2017-01-20 Thread Chaitra P B
Here is the change list:
Posting 4 patches for mpt3sas driver enhancement and defect fixes.
  * Handle cable event for notifying degraded speed.
  * Performance improvement for Crusader.
  * Fix Firmware fault state 0x2100 during heavy 4K RR
FIO stress test.
  * Updated driver version to 15.100.00.00

Chaitra P B (4):
  mpt3sas: Added print to notify cable running at a degraded
speed.
  mpt3sas: Fix for Crusader to achieve product targets with SAS
devices.
  mpt3sas: Fix Firmware fault state 0x2100 during heavy 4K RR
FIO stress test.
  mpt3sas: Updating driver version to v15.100.00.00

 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |2 +
 drivers/scsi/mpt3sas/mpt3sas_base.c  |   20 +
 drivers/scsi/mpt3sas/mpt3sas_base.h  |7 ++--
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |4 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   51 --
 5 files changed, 71 insertions(+), 13 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/4] mpt3sas: Fix for Crusader to achieve product targets with SAS devices.

2017-01-20 Thread Chaitra P B
Small glitch/degraded performance in Crusader is improved with SAS
drives by removing unnecessary spinlocks while clearing scsi command
in drivers internal lookup table.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index f00ef88..722fab9 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -5522,6 +5522,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
goto out_free_resources;
 
ioc->non_operational_loop = 0;
+   ioc->got_task_abort_from_ioctl = 0;
return 0;
 
  out_free_resources:
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index dcb33f4..83cfa16 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1000,6 +1000,7 @@ struct MPT3SAS_ADAPTER {
u8  broadcast_aen_busy;
u16 broadcast_aen_pending;
u8  shost_recovery;
+   u8  got_task_abort_from_ioctl;
 
struct mutexreset_in_progress_mutex;
spinlock_t  ioc_reset_in_progress_lock;
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 95f0f24..02fe1c4 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -826,16 +826,18 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct 
mpt3_ioctl_command karg,
"TASK_MGMT: handle(0x%04x), task_type(0x%02x)\n",
ioc->name,
le16_to_cpu(tm_request->DevHandle), tm_request->TaskType));
-
+   ioc->got_task_abort_from_ioctl = 1;
if (tm_request->TaskType ==
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK ||
tm_request->TaskType ==
MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK) {
if (_ctl_set_task_mid(ioc, &karg, tm_request)) {
mpt3sas_base_free_smid(ioc, smid);
+   ioc->got_task_abort_from_ioctl = 0;
goto out;
}
}
+   ioc->got_task_abort_from_ioctl = 0;
 
if (test_bit(device_handle, ioc->device_remove_in_progress)) {
dtmprintk(ioc, pr_info(MPT3SAS_FMT
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 0f71f4a..217e0fe 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1074,6 +1074,26 @@ _scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, u16 
smid)
 }
 
 /**
+ * _scsih_scsi_lookup_get_clear_without_lock - returns scmd entry without
+ * holding any lock.
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Returns the smid stored scmd pointer.
+ * Then will dereference the stored scmd pointer.
+ */
+static inline struct scsi_cmnd *
+_scsih_scsi_lookup_get_clear_without_lock(struct MPT3SAS_ADAPTER *ioc,
+   u16 smid)
+{
+   struct scsi_cmnd *scmd = NULL;
+
+   swap(scmd, ioc->scsi_lookup[smid - 1].scmd);
+
+   return scmd;
+}
+
+/**
  * _scsih_scsi_lookup_get_clear - returns scmd entry
  * @ioc: per adapter object
  * @smid: system request message index
@@ -1088,8 +1108,7 @@ _scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc, 
u16 smid)
struct scsi_cmnd *scmd;
 
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-   scmd = ioc->scsi_lookup[smid - 1].scmd;
-   ioc->scsi_lookup[smid - 1].scmd = NULL;
+   scmd = _scsih_scsi_lookup_get_clear_without_lock(ioc, smid);
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
 
return scmd;
@@ -4659,7 +4678,13 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index, u32 reply)
unsigned long flags;
 
mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
-   scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
+
+   if (ioc->broadcast_aen_busy || ioc->pci_error_recovery ||
+   ioc->got_task_abort_from_ioctl)
+   scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
+   else
+   scmd = _scsih_scsi_lookup_get_clear_without_lock(ioc, smid);
+
if (scmd == NULL)
return 1;
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 4/4] mpt3sas: Updating driver version to v15.100.00.00

2017-01-20 Thread Chaitra P B

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 83cfa16..4ab634f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -73,9 +73,9 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies "
 #define MPT3SAS_DESCRIPTION"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION "14.101.00.00"
-#define MPT3SAS_MAJOR_VERSION  14
-#define MPT3SAS_MINOR_VERSION  101
+#define MPT3SAS_DRIVER_VERSION "15.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  15
+#define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/4] mpt3sas: Fix Firmware fault state 0x2100 during heavy 4K RR FIO stress test.

2017-01-20 Thread Chaitra P B
Due existence of loop in the IO path our HBA will receive heavy IOs and
also as driver is not updating the Reply Post Host Index frequently, So
there will be a high chance that our Firmware unable to find any free entry
in the Reply Post Descriptor Queue (i.e. Queue overflow occurs) and can
observe 0x2100 firmware fault.
So to fix this, we have defined a thresh hold value. After continuously
processing this thresh hold number of reply descriptors driver will update
the Reply Descriptor Host Index so that this thresh hold number of reply
descriptors entries will be freed and these entries will be available for
firmware and we won't observe this Firmware fault. We have defined this
threshold value as 1/3rd of the hba queue depth.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 722fab9..a3fe1fb 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1040,6 +1040,25 @@ _base_interrupt(int irq, void *bus_id)
reply_q->reply_post_free[reply_q->reply_post_host_index].
Default.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
completed_cmds++;
+   /* Update the reply post host index after continuously
+* processing the threshold number of Reply Descriptors.
+* So that FW can find enough entries to post the Reply
+* Descriptors in the reply descriptor post queue.
+*/
+   if (completed_cmds > ioc->hba_queue_depth/3) {
+   if (ioc->combined_reply_queue) {
+   writel(reply_q->reply_post_host_index |
+   ((msix_index  & 7) <<
+MPI2_RPHI_MSIX_INDEX_SHIFT),
+   ioc->replyPostRegisterIndex[msix_index/8]);
+   } else {
+   writel(reply_q->reply_post_host_index |
+   (msix_index <<
+MPI2_RPHI_MSIX_INDEX_SHIFT),
+   &ioc->chip->ReplyPostHostIndex);
+   }
+   completed_cmds = 1;
+   }
if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
goto out;
if (!reply_q->reply_post_host_index)
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/4] mpt3sas: Added print to notify cable running at a degraded speed.

2017-01-20 Thread Chaitra P B
Driver processes the event MPI26_EVENT_ACTIVE_CABLE_DEGRADED
when a cable is present and is running at a degraded speed
(below the SAS3 12 Gb/s rate). Prints added
to inform the user that the cable is not running at
optimal speed.

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

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
index 8bae305..af4be40 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
@@ -624,6 +624,8 @@ typedef struct _MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT {
 
 /* defines for ReasonCode field */
 #define MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER (0x00)
+#define MPI26_EVENT_ACTIVE_CABLE_PRESENT(0x01)
+#define MPI26_EVENT_ACTIVE_CABLE_DEGRADED   (0x02)
 
 /*Hard Reset Received Event data */
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 75f3fce..0f71f4a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -8028,15 +8028,23 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER 
*ioc, u8 msix_index,
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
ActiveCableEventData =
(Mpi26EventDataActiveCableExcept_t *) mpi_reply->EventData;
-   if (ActiveCableEventData->ReasonCode ==
-   MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER) {
-   pr_info(MPT3SAS_FMT "Currently an active cable with 
ReceptacleID %d",
+   switch (ActiveCableEventData->ReasonCode) {
+   case MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER:
+   pr_info(MPT3SAS_FMT "Currently an active cable with 
ReceptacleID %d\n",
ioc->name, ActiveCableEventData->ReceptacleID);
-   pr_info("cannot be powered and devices connected to 
this active cable");
-   pr_info("will not be seen. This active cable");
-   pr_info("requires %d mW of power",
+   pr_info(" cannot be powered and devices connected 
to\n");
+   pr_info(" this active cable will not be seen. This\n");
+   pr_info(" cable requires %d mW of power\n",
ActiveCableEventData->ActiveCablePowerRequirement);
+   break;
+
+   case MPI26_EVENT_ACTIVE_CABLE_DEGRADED:
+   pr_info(MPT3SAS_FMT "Currently a cable with 
ReceptacleID %d",
+   ioc->name, ActiveCableEventData->ReceptacleID);
+   pr_info(" is not running at optimal speed(12 Gb/s)\n");
+   break;
}
+
break;
 
default: /* ignore the rest */
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/4] mpt3sas driver Enhancements and

2017-01-19 Thread Chaitra P B
Here is the change list:
Posting 4 patches for mpt3sas driver enhancement and defect fixes.
  * Handle cable event for notifying degraded speed.
  * Performance improvement for Crusader.
  * Fix Firmware fault state 0x2100 during heavy 4K RR
FIO stress test.
  * Updated driver version to 15.100.00.00

Chaitra P B (4):
  mpt3sas: Added print to notify cable running at a  degraded
speed.
  mpt3sas: Fix for Crusader to achieve product targets with  SAS
devices.
  mpt3sas: Fix Firmware fault state 0x2100 during heavy 4K RR  FIO
stress test.
  mpt3sas: Bump driver version to 15.100.00.00

 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |2 +
 drivers/scsi/mpt3sas/mpt3sas_base.c  |   20 ++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |7 +++--
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |4 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   47 +
 5 files changed, 70 insertions(+), 10 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/4] mpt3sas: Fix for Crusader to achieve product targets with SAS devices.

2017-01-19 Thread Chaitra P B
Small glitch/degraded performance in Crusader is improved with SAS
drives by removing unnecessary spinlocks while clearing scsi command
in drivers internal lookup table.

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

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index f00ef88..722fab9 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -5522,6 +5522,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
goto out_free_resources;
 
ioc->non_operational_loop = 0;
+   ioc->got_task_abort_from_ioctl = 0;
return 0;
 
  out_free_resources:
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index dcb33f4..83cfa16 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1000,6 +1000,7 @@ struct MPT3SAS_ADAPTER {
u8  broadcast_aen_busy;
u16 broadcast_aen_pending;
u8  shost_recovery;
+   u8  got_task_abort_from_ioctl;
 
struct mutexreset_in_progress_mutex;
spinlock_t  ioc_reset_in_progress_lock;
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 95f0f24..02fe1c4 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -826,16 +826,18 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct 
mpt3_ioctl_command karg,
"TASK_MGMT: handle(0x%04x), task_type(0x%02x)\n",
ioc->name,
le16_to_cpu(tm_request->DevHandle), tm_request->TaskType));
-
+   ioc->got_task_abort_from_ioctl = 1;
if (tm_request->TaskType ==
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK ||
tm_request->TaskType ==
MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK) {
if (_ctl_set_task_mid(ioc, &karg, tm_request)) {
mpt3sas_base_free_smid(ioc, smid);
+   ioc->got_task_abort_from_ioctl = 0;
goto out;
}
}
+   ioc->got_task_abort_from_ioctl = 0;
 
if (test_bit(device_handle, ioc->device_remove_in_progress)) {
dtmprintk(ioc, pr_info(MPT3SAS_FMT
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 5ffbfb1..b3f9f7a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1096,6 +1096,27 @@ _scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER 
*ioc, u16 smid)
 }
 
 /**
+ * _scsih_scsi_lookup_get_clear_without_lock - returns scmd entry without
+ * holding any lock.
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Returns the smid stored scmd pointer.
+ * Then will derefrence the stored scmd pointer.
+ */
+static inline struct scsi_cmnd *
+_scsih_scsi_lookup_get_clear_without_lock(struct MPT3SAS_ADAPTER *ioc,
+   u16 smid)
+{
+   struct scsi_cmnd *scmd;
+
+   scmd = ioc->scsi_lookup[smid - 1].scmd;
+   ioc->scsi_lookup[smid - 1].scmd = NULL;
+
+   return scmd;
+}
+
+/**
  * _scsih_scsi_lookup_find_by_scmd - scmd lookup
  * @ioc: per adapter object
  * @smid: system request message index
@@ -4659,7 +4680,13 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index, u32 reply)
unsigned long flags;
 
mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
-   scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
+
+   if (ioc->broadcast_aen_busy || ioc->pci_error_recovery ||
+   ioc->got_task_abort_from_ioctl)
+   scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
+   else
+   scmd = _scsih_scsi_lookup_get_clear_without_lock(ioc, smid);
+
if (scmd == NULL)
return 1;
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] mpt3sas: Bump driver version to 15.100.00.00

2017-01-19 Thread Chaitra P B

Signed-off-by: Chaitra P B 
   Suganath Prabu 
---
 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 83cfa16..4ab634f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -73,9 +73,9 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies "
 #define MPT3SAS_DESCRIPTION"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION "14.101.00.00"
-#define MPT3SAS_MAJOR_VERSION  14
-#define MPT3SAS_MINOR_VERSION  101
+#define MPT3SAS_DRIVER_VERSION "15.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  15
+#define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/4] mpt3sas: Fix Firmware fault state 0x2100 during heavy 4K RR FIO stress test.

2017-01-19 Thread Chaitra P B
Due existence of loop in the IO path our HBA will receive heavy IOs and
also as driver is not updating the Reply Post Host Index frequently, So
there will be a high chance that our Firmware unable to find any free entry
in the Reply Post Descriptor Queue (i.e. Queue overflow occurs) and can
observe 0x2100 firmware fault.
So to fix this, we have defined a thresh hold value. After continuously
processing this threshold number of reply descriptors driver will update
the Reply Descriptor Host Index so that this threshold number of reply
descriptors entries will be freed and these entries will be available for
firmware and we won't observe this Firmware fault. We have defined this
threshold value as 1/3rd of the hba queue depth.

Signed-off-by: Chaitra P B 
   Suganath Prabu 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c |   19 +++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 722fab9..a3fe1fb 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1040,6 +1040,25 @@ _base_interrupt(int irq, void *bus_id)
reply_q->reply_post_free[reply_q->reply_post_host_index].
Default.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
completed_cmds++;
+   /* Update the reply post host index after continuously
+* processing the threshold number of Reply Descriptors.
+* So that FW can find enough entries to post the Reply
+* Descriptors in the reply descriptor post queue.
+*/
+   if (completed_cmds > ioc->hba_queue_depth/3) {
+   if (ioc->combined_reply_queue) {
+   writel(reply_q->reply_post_host_index |
+   ((msix_index  & 7) <<
+MPI2_RPHI_MSIX_INDEX_SHIFT),
+   ioc->replyPostRegisterIndex[msix_index/8]);
+   } else {
+   writel(reply_q->reply_post_host_index |
+   (msix_index <<
+MPI2_RPHI_MSIX_INDEX_SHIFT),
+   &ioc->chip->ReplyPostHostIndex);
+   }
+   completed_cmds = 1;
+   }
if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
goto out;
if (!reply_q->reply_post_host_index)
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/4] mpt3sas: Added print to notify cable running at a degraded speed.

2017-01-19 Thread Chaitra P B
Driver processes the event MPI26_EVENT_ACTIVE_CABLE_DEGRADED
when a cable is present and is running at a degraded speed
(below the SAS3 12 Gb/s rate). Prints added
to inform the user that the cable is not running at
optimal speed.

Signed-off-by: Chaitra P B 
   Suganath Prabu 
---
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  |2 ++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |   18 +-
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
index 8bae305..af4be40 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
@@ -624,6 +624,8 @@ typedef struct _MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT {
 
 /* defines for ReasonCode field */
 #define MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER (0x00)
+#define MPI26_EVENT_ACTIVE_CABLE_PRESENT(0x01)
+#define MPI26_EVENT_ACTIVE_CABLE_DEGRADED   (0x02)
 
 /*Hard Reset Received Event data */
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 75f3fce..5ffbfb1 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -8028,15 +8028,23 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER 
*ioc, u8 msix_index,
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
ActiveCableEventData =
(Mpi26EventDataActiveCableExcept_t *) mpi_reply->EventData;
-   if (ActiveCableEventData->ReasonCode ==
-   MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER) {
+   switch (ActiveCableEventData->ReasonCode) {
+   case MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER:
pr_info(MPT3SAS_FMT "Currently an active cable with 
ReceptacleID %d",
ioc->name, ActiveCableEventData->ReceptacleID);
-   pr_info("cannot be powered and devices connected to 
this active cable");
-   pr_info("will not be seen. This active cable");
-   pr_info("requires %d mW of power",
+   pr_info(" cannot be powered and devices connected to");
+   pr_info(" this active cable will not be seen. This");
+   pr_info(" cable requires %d mW of power",
ActiveCableEventData->ActiveCablePowerRequirement);
+   break;
+
+   case MPI26_EVENT_ACTIVE_CABLE_DEGRADED:
+   pr_info(MPT3SAS_FMT "Currently a cable with 
ReceptacleID %d",
+   ioc->name, ActiveCableEventData->ReceptacleID);
+   pr_info(" is not running at optimal speed(12 Gb/s)\n");
+   break;
}
+
break;
 
default: /* ignore the rest */
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/6] mpt3sas: Updating mpt3sas driver version to 13.100.00.00

2016-05-06 Thread Chaitra P B
Bump mpt3sas driver version from 12.100.00.00 to 13.100.00.00

Signed-off-by: Chaitra P B 
---
 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 32580b5..aa918aa 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -73,8 +73,8 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies "
 #define MPT3SAS_DESCRIPTION"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION "12.100.00.00"
-#define MPT3SAS_MAJOR_VERSION  12
+#define MPT3SAS_DRIVER_VERSION "13.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  13
 #define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/6] mpt3sas: Update MPI header to 2.00.42

2016-05-06 Thread Chaitra P B
Updated MPI version and MPI header files.

ChangeList:
* Added SATADeviceWaitTime to SAS IO Unit Page 4
* Added EEDPObservedValue added to SCSI IO Reply message
* Added MPI2_EVENT_ACTIVE_CABLE_EXCEPTION and
  MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT

Signed-off-by: Chaitra P B 
---
 drivers/scsi/mpt3sas/mpi/mpi2.h  |  7 +--
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 18 +++-
 drivers/scsi/mpt3sas/mpi/mpi2_init.h | 15 +++---
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  | 40 +++-
 4 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h
index dfad5b8..a9a659f 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.39
+ * mpi2.h Version:  02.00.42
  *
  * 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
@@ -100,6 +100,9 @@
  * Added MPI2_DIAG_SBR_RELOAD.
  * 03-19-15  02.00.38  Bumped MPI2_HEADER_VERSION_UNIT.
  * 05-25-15  02.00.39  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 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
  * --
  */
 
@@ -139,7 +142,7 @@
 #define MPI2_VERSION_02_06 (0x0206)
 
 /*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT(0x27)
+#define MPI2_HEADER_VERSION_UNIT(0x2A)
 #define MPI2_HEADER_VERSION_DEV (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK   (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT  (8)
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
index 9cf09bf..95356a8 100644
--- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
@@ -6,7 +6,7 @@
  * Title:  MPI Configuration messages and pages
  * Creation Date:  November 10, 2006
  *
- *   mpi2_cnfg.h Version:  02.00.33
+ *   mpi2_cnfg.h Version:  02.00.35
  *
  * 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
@@ -183,9 +183,12 @@
  * Added MPI2_BIOSPAGE1_OPTIONS_ADVANCED_CONFIG.
  * Added AdapterOrderAux fields to BIOS Page 3.
  * 03-16-15  02.00.31  Updated for MPI v2.6.
+ * Added Flags field to IO Unit Page 7.
  * Added new SAS Phy Event codes
  * 05-25-15  02.00.33  Added more defines for the BiosOptions field of
  * MPI2_CONFIG_PAGE_BIOS_1.
+ * 08-25-15  02.00.34  Bumped Header Version.
+ * 12-18-15  02.00.35  Added SATADeviceWaitTime to SAS IO Unit Page 4.
  * --
  */
 
@@ -958,13 +961,16 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
U8  Reserved3;  /*0x17 */
U32 BoardPowerRequirement;  /*0x18 */
U32 PCISlotPowerAllocation; /*0x1C */
-   U32 Reserved6;  /* 0x20 */
-   U32 Reserved7;  /* 0x24 */
+/* reserved prior to MPI v2.6 */
+   U8  Flags;  /* 0x20 */
+   U8  Reserved6;  /* 0x21 */
+   U16 Reserved7;  /* 0x22 */
+   U32 Reserved8;  /* 0x24 */
 } MPI2_CONFIG_PAGE_IO_UNIT_7,
*PTR_MPI2_CONFIG_PAGE_IO_UNIT_7,
Mpi2IOUnitPage7_t, *pMpi2IOUnitPage7_t;
 
-#define MPI2_IOUNITPAGE7_PAGEVERSION   (0x04)
+#define MPI2_IOUNITPAGE7_PAGEVERSION   (0x05)
 
 /*defines for IO Unit Page 7 CurrentPowerMode and PreviousPowerMode fields */
 #define MPI25_IOUNITPAGE7_PM_INIT_MASK  (0xC0)
@@ -1045,6 +1051,8 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
 #define MPI2_IOUNITPAGE7_BOARD_TEMP_FAHRENHEIT  (0x01)
 #define MPI2_IOUNITPAGE7_BOARD_TEMP_CELSIUS (0x02)
 
+/* defines for IO Unit Page 7 Flags field */
+#define MPI2_IOUNITPAGE7_FLAG_CABLE_POWER_EXC   (0x01)
 
 /*IO Unit Page 8 */
 
@@ -2271,7 +2279,7 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_4 {
U8
BootDeviceWaitTime; /*0x24 */
U8
-   Reserved4;  /*0x25 */
+   SATADeviceWaitTime; /*0x25 */
U16
Reserved5;  /*0x26 */
U8
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_init.h 
b/drivers/scsi/mpt3sas/mpi/mpi2_init.h
index c38f624..bba56b6 100644
--- a/drivers/scsi

[PATCH 0/6] mpt3sas: driver update to Phase12.

2016-05-06 Thread Chaitra P B
Here is the change list:
* Updated MPI version and MPI header files.
* Handle active cable exception event for Intruder/Cutlass HBAs.
* Use scsi_prot_ref_tag()API to fill reference tag field in the CDB.
* Updated mpt3sas driver version to Ph12 13.100.00.00
* Set maximum transfer length per IO on RAID volumes to 4MB.
* Use "synchronize_irq()"API to handle Asynchronous TM's completion.

Chaitra P B (6):
  mpt3sas: Update MPI header to 2.00.42
  mpt3sas: Handle active cable exception event
  mpt3sas: Fix initial Reference tag field for 4K PI drives.
  mpt3sas: Updating mpt3sas driver version to 13.100.00.00
  mpt3sas: Set maximum transfer length per IO to 4MB for VDs
  mpt3sas: Used "synchronize_irq()"API to synchronize timed-out IO
& TMs

 drivers/scsi/mpt3sas/mpi/mpi2.h  |  7 +--
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 18 +++-
 drivers/scsi/mpt3sas/mpi/mpi2_init.h | 15 +++---
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  | 40 +++-
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 20 ++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  9 +---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 27 ++--
 7 files changed, 108 insertions(+), 28 deletions(-)

-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/6] mpt3sas: Set maximum transfer length per IO to 4MB for VDs

2016-05-06 Thread Chaitra P B
Set maximum transfer length per IO on RAID volumes
to 4MB by setting VD's queue's max_sector to 8192.

Signed-off-by: Chaitra P B 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  | 2 ++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 8 
 2 files changed, 10 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index aa918aa..e1befba 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -112,6 +112,8 @@
 #define MPT3SAS_SAS_QUEUE_DEPTH254
 #define MPT3SAS_RAID_QUEUE_DEPTH   128
 
+#define MPT3SAS_RAID_MAX_SECTORS   8192
+
 #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 0fea937..abd8717 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1911,6 +1911,14 @@ scsih_slave_configure(struct scsi_device *sdev)
(unsigned long long)raid_device->wwid,
raid_device->num_pds, ds);
 
+   if (shost->max_sectors > MPT3SAS_RAID_MAX_SECTORS) {
+   blk_queue_max_hw_sectors(sdev->request_queue,
+   MPT3SAS_RAID_MAX_SECTORS);
+   sdev_printk(KERN_INFO, sdev,
+   "Set queue's max_sector to: %u\n",
+   MPT3SAS_RAID_MAX_SECTORS);
+   }
+
scsih_change_queue_depth(sdev, qdepth);
 
/* raid transport support */
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/6] mpt3sas: Fix initial Reference tag field for 4K PI drives.

2016-05-06 Thread Chaitra P B
Modified driver code to use scsi_prot_ref_tag() API instead of
scsi_get_lba(), while initializing reference tag field in the CDB.

Signed-off-by: Chaitra P B 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 221f8bf..0fea937 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3961,7 +3961,7 @@ _scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct 
scsi_cmnd *scmd,
MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
mpi_request->CDB.EEDP32.PrimaryReferenceTag =
-   cpu_to_be32(scsi_get_lba(scmd));
+   cpu_to_be32(scsi_prot_ref_tag(scmd));
break;
 
case SCSI_PROT_DIF_TYPE3:
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 6/6] mpt3sas: Used "synchronize_irq()"API to synchronize timed-out IO & TMs

2016-05-06 Thread Chaitra P B
Replaced mpt3sas_base_flush_reply_queues()with
mpt3sas_base_sync_reply_irqs(),as mpt3sas_base_flush_reply_queues()
skips over reply queues that are currently busy (i.e. being handled
by interrupt processing in another core). If a reply queue is busy,
then call to synchronize_irq()in mpt3sas_base_sync_reply_irqs()make
sures the other core has finished flushing the queue and completed
any calls to the mid-layer scsi_done() routine.

Signed-off-by: Chaitra P B 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 15 +++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  3 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  4 +++-
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 4e9142f..fd9002d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1103,18 +1103,16 @@ _base_is_controller_msix_enabled(struct MPT3SAS_ADAPTER 
*ioc)
 }
 
 /**
- * mpt3sas_base_flush_reply_queues - flushing the MSIX reply queues
+ * mpt3sas_base_sync_reply_irqs - flush pending MSIX interrupts
  * @ioc: per adapter object
- * Context: ISR conext
+ * Context: non ISR conext
  *
- * Called when a Task Management request has completed. We want
- * to flush the other reply queues so all the outstanding IO has been
- * completed back to OS before we process the TM completetion.
+ * Called when a Task Management request has completed.
  *
  * Return nothing.
  */
 void
-mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc)
+mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc)
 {
struct adapter_reply_queue *reply_q;
 
@@ -1125,12 +1123,13 @@ mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER 
*ioc)
return;
 
list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
-   if (ioc->shost_recovery)
+   if (ioc->shost_recovery || ioc->remove_host ||
+   ioc->pci_error_recovery)
return;
/* TMs are on msix_index == 0 */
if (reply_q->msix_index == 0)
continue;
-   _base_interrupt(reply_q->vector, (void *)reply_q);
+   synchronize_irq(reply_q->vector);
}
 }
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index e1befba..1a614d7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1236,7 +1236,8 @@ void *mpt3sas_base_get_msg_frame(struct MPT3SAS_ADAPTER 
*ioc, u16 smid);
 void *mpt3sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 __le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc,
u16 smid);
-void mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc);
+
+void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc);
 
 /* hi-priority queue */
 u16 mpt3sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index abd8717..928214f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2126,7 +2126,6 @@ _scsih_tm_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index, u32 reply)
return 1;
if (ioc->tm_cmds.smid != smid)
return 1;
-   mpt3sas_base_flush_reply_queues(ioc);
ioc->tm_cmds.status |= MPT3_CMD_COMPLETE;
mpi_reply =  mpt3sas_base_get_reply_virt_addr(ioc, reply);
if (mpi_reply) {
@@ -2311,6 +2310,9 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 
handle, uint channel,
}
}
 
+   /* sync IRQs in case those were busy during flush. */
+   mpt3sas_base_sync_reply_irqs(ioc);
+
if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) {
mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT);
mpi_reply = ioc->tm_cmds.reply;
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/6] mpt3sas: Handle active cable exception event

2016-05-06 Thread Chaitra P B
In-order to handle this 'MPI2_EVENT_ACTIVE_CABLE_EXCEPTION' event,
driver need to follow below steps,
1. Unmask the 'MPI2_EVENT_ACTIVE_CABLE_EXCEPTION' event,
so that FW can notify this event to host driver.
2. After receiving this event, add this event to AEN event queue,
for notifying this event to applications.
3. Then Print below message in kernel logs if the event data's reason
code is zero,
"Currently an active cable with ReceptacleID  cannot be powered
and devices connected to this active cable will not be seen. This active
cable requires  of power"

This event is only for Intruder/Cutlass HBAs.

Signed-off-by: Chaitra P B 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  5 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 13 +
 2 files changed, 18 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 8c44b9c..4e9142f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -654,6 +654,9 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
case MPI2_EVENT_TEMP_THRESHOLD:
desc = "Temperature Threshold";
break;
+   case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
+   desc = "Active cable exception";
+   break;
}
 
if (!desc)
@@ -5424,6 +5427,8 @@ 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)
+   _base_unmask_events(ioc, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
 
r = _base_make_ioc_operational(ioc, CAN_SLEEP);
if (r)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index e0e4920..221f8bf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -7850,6 +7850,7 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, 
u8 msix_index,
Mpi2EventNotificationReply_t *mpi_reply;
u16 event;
u16 sz;
+   Mpi26EventDataActiveCableExcept_t *ActiveCableEventData;
 
/* events turned off due to host reset or driver unloading */
if (ioc->remove_host || ioc->pci_error_recovery)
@@ -7962,6 +7963,18 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER 
*ioc, u8 msix_index,
(Mpi2EventDataTemperature_t *)
mpi_reply->EventData);
break;
+   case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
+   ActiveCableEventData =
+   (Mpi26EventDataActiveCableExcept_t *) mpi_reply->EventData;
+   if (ActiveCableEventData->ReasonCode ==
+   MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER)
+   pr_info(MPT3SAS_FMT "Currently an active cable with 
ReceptacleID %d",
+   ioc->name, ActiveCableEventData->ReceptacleID);
+   pr_info("cannot be powered and devices connected to 
this active cable");
+   pr_info("will not be seen. This active cable");
+   pr_info("requires %d mW of power",
+   ActiveCableEventData->ActiveCablePowerRequirement);
+   break;
 
default: /* ignore the rest */
return 1;
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/5] mpt3sas: driver update for Phase12

2016-04-22 Thread Chaitra P B
Here is the change list:
* Updated MPI version and MPI header files.
* Handle active cable exception event for Intruder/Cutlass HBAs.
* Use scsi_prot_ref_tag()API to fill reference tag field in the CDB.
* Set maximum transfer length per IO on RAID volumes to 4MB.
* Use "synchronize_irq()"API to handle Asynchronous TM's completion

Chaitra P B (5):
  mpt3sas: Update MPI header to 2.00.42
  mpt3sas: Handle active cable exception event
  mpt3sas: Fix initial Reference tag field for 4K PI drives.
  mpt3sas: Set maximum transfer length per IO to 4MB for VDs
  mpt3sas: Used "synchronize_irq()"API to synchronize timed-out IO &
TMs

 drivers/scsi/mpt3sas/mpi/mpi2.h  |  7 +--
 drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 18 +++-
 drivers/scsi/mpt3sas/mpi/mpi2_init.h | 15 +++---
 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h  | 40 +++-
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 20 ++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  5 -
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 27 ++--
 7 files changed, 106 insertions(+), 26 deletions(-)

-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/5] mpt3sas: Handle active cable exception event

2016-04-22 Thread Chaitra P B
In-order to handle this 'MPI2_EVENT_ACTIVE_CABLE_EXCEPTION' event,
driver need to follow below steps,
1. Unmask the 'MPI2_EVENT_ACTIVE_CABLE_EXCEPTION' event,
so that FW can notify this event to host driver.
2. After receiving this event, add this event to AEN event queue,
for notifying this event to applications.
3. Then Print below message in kernel logs if the event data's reason
code is zero,
"Currently an active cable with ReceptacleID  cannot be powered
and devices connected to this active cable will not be seen. This active
cable requires  of power"

This event is only for Intruder/Cutlass HBAs.

Signed-off-by: Chaitra P B 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  5 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 13 +
 2 files changed, 18 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 8c44b9c..4e9142f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -654,6 +654,9 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
case MPI2_EVENT_TEMP_THRESHOLD:
desc = "Temperature Threshold";
break;
+   case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
+   desc = "Active cable exception";
+   break;
}
 
if (!desc)
@@ -5424,6 +5427,8 @@ 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)
+   _base_unmask_events(ioc, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
 
r = _base_make_ioc_operational(ioc, CAN_SLEEP);
if (r)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index e0e4920..221f8bf 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -7850,6 +7850,7 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, 
u8 msix_index,
Mpi2EventNotificationReply_t *mpi_reply;
u16 event;
u16 sz;
+   Mpi26EventDataActiveCableExcept_t *ActiveCableEventData;
 
/* events turned off due to host reset or driver unloading */
if (ioc->remove_host || ioc->pci_error_recovery)
@@ -7962,6 +7963,18 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER 
*ioc, u8 msix_index,
(Mpi2EventDataTemperature_t *)
mpi_reply->EventData);
break;
+   case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
+   ActiveCableEventData =
+   (Mpi26EventDataActiveCableExcept_t *) mpi_reply->EventData;
+   if (ActiveCableEventData->ReasonCode ==
+   MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER)
+   pr_info(MPT3SAS_FMT "Currently an active cable with 
ReceptacleID %d",
+   ioc->name, ActiveCableEventData->ReceptacleID);
+   pr_info("cannot be powered and devices connected to 
this active cable");
+   pr_info("will not be seen. This active cable");
+   pr_info("requires %d mW of power",
+   ActiveCableEventData->ActiveCablePowerRequirement);
+   break;
 
default: /* ignore the rest */
return 1;
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/5] mpt3sas: Used "synchronize_irq()"API to synchronize timed-out IO & TMs

2016-04-22 Thread Chaitra P B
Replaced mpt3sas_base_flush_reply_queues()with
mpt3sas_base_sync_reply_irqs(),as mpt3sas_base_flush_reply_queues()
skips over reply queues that are currently busy (i.e. being handled
by interrupt processing in another core). If a reply queue is busy,
then call to synchronize_irq()in mpt3sas_base_sync_reply_irqs()make
sures the other core has finished flushing the queue and completed
any calls to the mid-layer scsi_done() routine.

Signed-off-by: Chaitra P B 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 15 +++
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  3 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  4 +++-
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 4e9142f..fd9002d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1103,18 +1103,16 @@ _base_is_controller_msix_enabled(struct MPT3SAS_ADAPTER 
*ioc)
 }
 
 /**
- * mpt3sas_base_flush_reply_queues - flushing the MSIX reply queues
+ * mpt3sas_base_sync_reply_irqs - flush pending MSIX interrupts
  * @ioc: per adapter object
- * Context: ISR conext
+ * Context: non ISR conext
  *
- * Called when a Task Management request has completed. We want
- * to flush the other reply queues so all the outstanding IO has been
- * completed back to OS before we process the TM completetion.
+ * Called when a Task Management request has completed.
  *
  * Return nothing.
  */
 void
-mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc)
+mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc)
 {
struct adapter_reply_queue *reply_q;
 
@@ -1125,12 +1123,13 @@ mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER 
*ioc)
return;
 
list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
-   if (ioc->shost_recovery)
+   if (ioc->shost_recovery || ioc->remove_host ||
+   ioc->pci_error_recovery)
return;
/* TMs are on msix_index == 0 */
if (reply_q->msix_index == 0)
continue;
-   _base_interrupt(reply_q->vector, (void *)reply_q);
+   synchronize_irq(reply_q->vector);
}
 }
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index a16e7f9..fd58c48 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1236,7 +1236,8 @@ void *mpt3sas_base_get_msg_frame(struct MPT3SAS_ADAPTER 
*ioc, u16 smid);
 void *mpt3sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 __le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc,
u16 smid);
-void mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc);
+
+void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc);
 
 /* hi-priority queue */
 u16 mpt3sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index abd8717..928214f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2126,7 +2126,6 @@ _scsih_tm_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index, u32 reply)
return 1;
if (ioc->tm_cmds.smid != smid)
return 1;
-   mpt3sas_base_flush_reply_queues(ioc);
ioc->tm_cmds.status |= MPT3_CMD_COMPLETE;
mpi_reply =  mpt3sas_base_get_reply_virt_addr(ioc, reply);
if (mpi_reply) {
@@ -2311,6 +2310,9 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 
handle, uint channel,
}
}
 
+   /* sync IRQs in case those were busy during flush. */
+   mpt3sas_base_sync_reply_irqs(ioc);
+
if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) {
mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT);
mpi_reply = ioc->tm_cmds.reply;
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/5] mpt3sas: Set maximum transfer length per IO to 4MB for VDs

2016-04-22 Thread Chaitra P B
Set maximum transfer length per IO on RAID volumes
to 4MB by setting VD's queue's max_sector to 8192.

Signed-off-by: Chaitra P B 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  | 2 ++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 8 
 2 files changed, 10 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 32580b5..a16e7f9 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -112,6 +112,8 @@
 #define MPT3SAS_SAS_QUEUE_DEPTH254
 #define MPT3SAS_RAID_QUEUE_DEPTH   128
 
+#define MPT3SAS_RAID_MAX_SECTORS   8192
+
 #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 0fea937..abd8717 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -1911,6 +1911,14 @@ scsih_slave_configure(struct scsi_device *sdev)
(unsigned long long)raid_device->wwid,
raid_device->num_pds, ds);
 
+   if (shost->max_sectors > MPT3SAS_RAID_MAX_SECTORS) {
+   blk_queue_max_hw_sectors(sdev->request_queue,
+   MPT3SAS_RAID_MAX_SECTORS);
+   sdev_printk(KERN_INFO, sdev,
+   "Set queue's max_sector to: %u\n",
+   MPT3SAS_RAID_MAX_SECTORS);
+   }
+
scsih_change_queue_depth(sdev, qdepth);
 
/* raid transport support */
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   >