[GIT PULL] SCSI fixes for 4.10-rc7

2017-02-10 Thread James Bottomley
Six fairly small fixes.  None is a real show stopper, two automation
detected problems: one memory leak, one use after free and four others
each of which fixes something that has been a significant source of
annoyance to someone.

The patch is available here:

git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git scsi-fixes

The short changelog is:

Bart Van Assche (1):
  scsi: qla2xxx: Fix a recently introduced memory leak

Dave Carroll (1):
  scsi: aacraid: Fix INTx/MSI-x issue with older controllers

Mauricio Faria de Oliveira (1):
  scsi: qla2xxx: Avoid that issuing a LIP triggers a kernel crash

Ram Pai (1):
  scsi: mpt3sas: Force request partial completion alignment

Steffen Maier (1):
  scsi: zfcp: fix use-after-free by not tracing WKA port open/close on 
failed send

ojab (1):
  scsi: mpt3sas: disable ASPM for MPI2 controllers

And the diffstat:

 drivers/s390/scsi/zfcp_fsf.c |  8 
 drivers/scsi/aacraid/comminit.c  |  8 ++--
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 18 ++
 drivers/scsi/qla2xxx/qla_isr.c   |  3 ++-
 drivers/scsi/qla2xxx/qla_os.c|  2 +-
 5 files changed, 31 insertions(+), 8 deletions(-)

With full diff below.

James

---

diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 75f820ca..27ff38f 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1583,7 +1583,7 @@ static void zfcp_fsf_open_wka_port_handler(struct 
zfcp_fsf_req *req)
 int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
 {
struct zfcp_qdio *qdio = wka_port->adapter->qdio;
-   struct zfcp_fsf_req *req = NULL;
+   struct zfcp_fsf_req *req;
int retval = -EIO;
 
spin_lock_irq(>req_q_lock);
@@ -1612,7 +1612,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port 
*wka_port)
zfcp_fsf_req_free(req);
 out:
spin_unlock_irq(>req_q_lock);
-   if (req && !IS_ERR(req))
+   if (!retval)
zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id);
return retval;
 }
@@ -1638,7 +1638,7 @@ static void zfcp_fsf_close_wka_port_handler(struct 
zfcp_fsf_req *req)
 int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
 {
struct zfcp_qdio *qdio = wka_port->adapter->qdio;
-   struct zfcp_fsf_req *req = NULL;
+   struct zfcp_fsf_req *req;
int retval = -EIO;
 
spin_lock_irq(>req_q_lock);
@@ -1667,7 +1667,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port 
*wka_port)
zfcp_fsf_req_free(req);
 out:
spin_unlock_irq(>req_q_lock);
-   if (req && !IS_ERR(req))
+   if (!retval)
zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id);
return retval;
 }
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 4f56b10..5b48bed 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -50,9 +50,13 @@ struct aac_common aac_config = {
 
 static inline int aac_is_msix_mode(struct aac_dev *dev)
 {
-   u32 status;
+   u32 status = 0;
 
-   status = src_readl(dev, MUnit.OMR);
+   if (dev->pdev->device == PMC_DEVICE_S6 ||
+   dev->pdev->device == PMC_DEVICE_S7 ||
+   dev->pdev->device == PMC_DEVICE_S8) {
+   status = src_readl(dev, MUnit.OMR);
+   }
return (status & AAC_INT_MODE_MSIX);
 }
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 75f3fce..0b5b423 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -51,6 +51,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -4657,6 +4658,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index, u32 reply)
struct MPT3SAS_DEVICE *sas_device_priv_data;
u32 response_code = 0;
unsigned long flags;
+   unsigned int sector_sz;
 
mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
@@ -4715,6 +4717,20 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 
msix_index, u32 reply)
}
 
xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
+
+   /* In case of bogus fw or device, we could end up having
+* unaligned partial completion. We can force alignment here,
+* then scsi-ml does not need to handle this misbehavior.
+*/
+   sector_sz = scmd->device->sector_size;
+   if (unlikely(scmd->request->cmd_type == REQ_TYPE_FS && sector_sz &&
+xfer_cnt % sector_sz)) {
+   sdev_printk(KERN_INFO, scmd->device,
+   "unaligned partial completion avoided (xfer_cnt=%u, 
sector_sz=%u)\n",
+   xfer_cnt, sector_sz);
+   xfer_cnt = round_down(xfer_cnt, sector_sz);
+   }
+
scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_cnt);

Re: [PATCH net-next v2 00/12] net: dsa: remove unnecessary phy.h include

2017-02-10 Thread Florian Fainelli
On 02/10/2017 10:51 AM, David Miller wrote:
> From: Kalle Valo 
> Date: Thu, 09 Feb 2017 16:10:06 +0200
> 
>> Florian Fainelli  writes:
>>
> If not, for something like this it's a must:
>
> drivers/net/wireless/ath/wil6210/cfg80211.c:24:30: error: expected ‘)’ 
> before ‘bool’
>  module_param(disable_ap_sme, bool, 0444);
>   ^
> drivers/net/wireless/ath/wil6210/cfg80211.c:25:34: error: expected ‘)’ 
> before string constant
>  MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME");
>   ^
> Like like that file needs linux/module.h included.

 Johannes already fixed a similar (or same) problem in my tree:

 wil6210: include moduleparam.h

 https://git.kernel.org/cgit/linux/kernel/git/kvalo/wireless-drivers-next.git/commit/?id=949c2d0096753d518ef6e0bd8418c8086747196b

 I'm planning to send you a pull request tomorrow which contains that
 one.
>>>
>>> Thanks Kalle!
>>>
>>> David, can you hold on this series until Kalle's pull request gets
>>> submitted? Past this error, allmodconfig builds fine with this patch
>>> series (just tested). Thanks!
>>
>> Just submitted the pull request:
>>
>> https://patchwork.ozlabs.org/patch/726133/
> 
> I've retried this patch series, and will push it out assuming the build
> completes properly.

I see it merged in net-next/master, thanks a lot this is going to save a
lot of cycles in the future, thanks David!
-- 
Florian


Re: [PATCH net-next v2 00/12] net: dsa: remove unnecessary phy.h include

2017-02-10 Thread David Miller
From: Kalle Valo 
Date: Thu, 09 Feb 2017 16:10:06 +0200

> Florian Fainelli  writes:
> 
 If not, for something like this it's a must:

 drivers/net/wireless/ath/wil6210/cfg80211.c:24:30: error: expected ‘)’ 
 before ‘bool’
  module_param(disable_ap_sme, bool, 0444);
   ^
 drivers/net/wireless/ath/wil6210/cfg80211.c:25:34: error: expected ‘)’ 
 before string constant
  MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME");
   ^
 Like like that file needs linux/module.h included.
>>> 
>>> Johannes already fixed a similar (or same) problem in my tree:
>>> 
>>> wil6210: include moduleparam.h
>>> 
>>> https://git.kernel.org/cgit/linux/kernel/git/kvalo/wireless-drivers-next.git/commit/?id=949c2d0096753d518ef6e0bd8418c8086747196b
>>> 
>>> I'm planning to send you a pull request tomorrow which contains that
>>> one.
>>
>> Thanks Kalle!
>>
>> David, can you hold on this series until Kalle's pull request gets
>> submitted? Past this error, allmodconfig builds fine with this patch
>> series (just tested). Thanks!
> 
> Just submitted the pull request:
> 
> https://patchwork.ozlabs.org/patch/726133/

I've retried this patch series, and will push it out assuming the build
completes properly.


Re: [PATCH RFC] target/user: Add double ring buffers support.

2017-02-10 Thread Andy Grover

On 02/09/2017 10:48 PM, lixi...@cmss.chinamobile.com wrote:

For now the tcmu is based on UIO framework and only using the
map0 with fixed ring buffer size. This will work fine mostly,
but when we are using the 10GBASE NIC, the ring buffer is too
small to deal with the incoming iscsi cmds.

We can resolve the above issue by increasingt the ring buffer
size larger, but we don't know the exactly size to all cases.

This patch will add double ring buffers support by adding map1
support through UIO device.


Hi Xiubo,

Yes I think it's now clear we need more buffer space to avoid 
bottlenecks for high iops. The initial design kept it simple with the 
1MB vmalloc'd space but anticipated greater would be needed. It should 
not be necessary to change userspace or the TCMU ABI to handle growing 
the buffer for fast devices:


1. increase the region mmap()ed by userspace, TCMU_RING_SIZE, from 1MB 
to 1GB or larger
2. Don't vmalloc() the whole thing, instead vmalloc for the cmd ring 
portion, and dynamically alloc pages for the data area as needed and map 
them into the data area.
3. Upgrade the current fixed-size bitmap-based tracking of data area to 
handle the new scheme
4. Implement an algorithm to keep allocated pages mapped into the data 
area for reuse, and maybe a heuristic to keep extreme burstiness from 
over-allocating pages


This should allow TCMU to allocate more data area as needed, not waste 
memory for slower devices, and avoid userspace ABI changes. Could we 
prototype this approach and see if it is workable?


Thanks -- Regards -- Andy



Re: [PATCH v3 19/39] megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access

2017-02-10 Thread Tomas Henzl
On 10.2.2017 09:59, Shivasharan S wrote:
> Change MR_TargetIdToLdGet return type from u8 to u16.
>
> ld id range check is added at two places in this patch -
> @megasas_build_ldio_fusion and @megasas_build_ld_nonrw_fusion.
> Previous driver code used different data type for lds TargetId returned from 
> MR_TargetIdToLdGet.
> Prior to this change, above two functions was safeguarded due to function 
> always return u8
> and maximum value of ld id returned was 255.
>
> In below check, fw_supported_vd_count as of today is 64 or 256 and
> valid range  to support is either 0-63 or 0-255. Ideally want to filter 
> accessing
> raid map for ld ids which are not valid. With the u16 change, invalid ld id 
> value
> is 0x and we will see kernel panic due to random memory access in 
> MR_LdRaidGet.
> The changes will ensure we do not call MR_LdRaidGet if ld id is beyond size 
> of ldSpanMap array.
>
>if (ld < instance->fw_supported_vd_count)
>
> From firmware perspective,ld id 0xFF is invalid and even though current driver
> code forward such command, firmware fails with target not available.
>
> ld target id issue occurs mainly whenever driver loops to populate raid map 
> (ea. MR_ValidateMapInfo).
> These are the only two places where we may see out of range target ids and 
> wants to
> protect raid map access based on range provided by Firmware API.
>
> Signed-off-by: Shivasharan S 
> Signed-off-by: Kashyap Desai 

Reviewed-by: Tomas Henzl 

Tomas



[PATCH v3 32/39] megaraid_sas: Change build_mpt_mfi_pass_thru to return void

2017-02-10 Thread Shivasharan S
Code refactoring to build_mpt_mfi_pass_thru to return void.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index c0a58dc..bafaf03 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -3229,7 +3229,7 @@ irqreturn_t megasas_isr_fusion(int irq, void *devp)
  * mfi_cmd:megasas_cmd pointer
  *
  */
-u8
+void
 build_mpt_mfi_pass_thru(struct megasas_instance *instance,
struct megasas_cmd *mfi_cmd)
 {
@@ -3279,8 +3279,6 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR;
 
mpi25_ieee_chain->Length = cpu_to_le32(instance->max_chain_frame_sz);
-
-   return 0;
 }
 
 /**
@@ -3295,11 +3293,7 @@ build_mpt_cmd(struct megasas_instance *instance, struct 
megasas_cmd *cmd)
union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc = NULL;
u16 index;
 
-   if (build_mpt_mfi_pass_thru(instance, cmd)) {
-   dev_err(>pdev->dev, "Couldn't build MFI pass thru 
cmd\n");
-   return NULL;
-   }
-
+   build_mpt_mfi_pass_thru(instance, cmd);
index = cmd->context.smid;
 
req_desc = megasas_get_request_descriptor(instance, index - 1);
-- 
2.8.3



RE: [PATCH v3 19/39] megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access

2017-02-10 Thread Shivasharan Srikanteshwara
> -Original Message-
> From: Hannes Reinecke [mailto:h...@suse.com]
> Sent: Friday, February 10, 2017 5:05 PM
> To: Shivasharan S; linux-scsi@vger.kernel.org
> Cc: martin.peter...@oracle.com; the...@redhat.com;
> j...@linux.vnet.ibm.com; kashyap.de...@broadcom.com;
> sumit.sax...@broadcom.com
> Subject: Re: [PATCH v3 19/39] megaraid_sas: MR_TargetIdToLdGet u8 to u16
> and avoid invalid raid-map access
>
> On 02/10/2017 09:59 AM, Shivasharan S wrote:
> > Change MR_TargetIdToLdGet return type from u8 to u16.
> >
> > ld id range check is added at two places in this patch -
> > @megasas_build_ldio_fusion and @megasas_build_ld_nonrw_fusion.
> > Previous driver code used different data type for lds TargetId
returned from
> MR_TargetIdToLdGet.
> > Prior to this change, above two functions was safeguarded due to
> > function always return u8 and maximum value of ld id returned was 255.
> >
> > In below check, fw_supported_vd_count as of today is 64 or 256 and
> > valid range  to support is either 0-63 or 0-255. Ideally want to
> > filter accessing raid map for ld ids which are not valid. With the u16
> > change, invalid ld id value is 0x and we will see kernel panic due
to random
> memory access in MR_LdRaidGet.
> > The changes will ensure we do not call MR_LdRaidGet if ld id is beyond
size of
> ldSpanMap array.
> >
> >if (ld < instance->fw_supported_vd_count)
> >
> > From firmware perspective,ld id 0xFF is invalid and even though
> > current driver code forward such command, firmware fails with target
not
> available.
> >
> > ld target id issue occurs mainly whenever driver loops to populate
raid map
> (ea. MR_ValidateMapInfo).
> > These are the only two places where we may see out of range target ids
> > and wants to protect raid map access based on range provided by
Firmware
> API.
> >
> > Signed-off-by: Shivasharan S 
> > Signed-off-by: Kashyap Desai 
> > ---
> >
> > fix in v2 - updated description content.
> >
> >  drivers/scsi/megaraid/megaraid_sas.h|  2 +-
> >  drivers/scsi/megaraid/megaraid_sas_fp.c |  5 +++--
> >  drivers/scsi/megaraid/megaraid_sas_fusion.c | 25
> > ++---
> >  3 files changed, 18 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/scsi/megaraid/megaraid_sas.h
> > b/drivers/scsi/megaraid/megaraid_sas.h
> > index 0a20fff..efc01a3 100644
> > --- a/drivers/scsi/megaraid/megaraid_sas.h
> > +++ b/drivers/scsi/megaraid/megaraid_sas.h
> > @@ -2448,7 +2448,7 @@ MR_BuildRaidContext(struct megasas_instance
> *instance,
> > struct IO_REQUEST_INFO *io_info,
> > struct RAID_CONTEXT *pRAID_Context,
> > struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN);
> > -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map);
> > +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL
> *map);
> >  struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL
> > *map);
> >  u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map);
> >  u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL
> > *map); diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c
> > b/drivers/scsi/megaraid/megaraid_sas_fp.c
> > index a0b0e68..9d5d485 100644
> > --- a/drivers/scsi/megaraid/megaraid_sas_fp.c
> > +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
> > @@ -165,7 +165,7 @@ u16 MR_GetLDTgtId(u32 ld, struct
> MR_DRV_RAID_MAP_ALL *map)
> > return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId);
> >  }
> >
> > -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map)
> > +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL
> *map)
> >  {
> > return map->raidMap.ldTgtIdToLd[ldTgtId];
> >  }
> > @@ -1151,7 +1151,7 @@ MR_BuildRaidContext(struct megasas_instance
> > *instance,  {
> > struct fusion_context *fusion;
> > struct MR_LD_RAID  *raid;
> > -   u32 ld, stripSize, stripe_mask;
> > +   u32 stripSize, stripe_mask;
> > u64 endLba, endStrip, endRow, start_row, start_strip;
> > u64 regStart;
> > u32 regSize;
> > @@ -1163,6 +1163,7 @@ MR_BuildRaidContext(struct megasas_instance
> *instance,
> > u8  retval = 0;
> > u8  startlba_span = SPAN_INVALID;
> > u64 *pdBlock = _info->pdBlock;
> > +   u16 ld;
> >
> > ldStartBlock = io_info->ldStartBlock;
> > numBlocks = io_info->numBlocks;
> > diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c
> > b/drivers/scsi/megaraid/megaraid_sas_fusion.c
> > index 9019b82..4aaf307 100644
> > --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
> > +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
> > @@ -1121,7 +1121,8 @@ megasas_sync_map_info(struct megasas_instance
> *instance)
> > int i;
> > struct megasas_cmd *cmd;
> > struct megasas_dcmd_frame *dcmd;
> > -   u32 size_sync_info, num_lds;
> > +   u16 num_lds;
> > +   u32 size_sync_info;

[PATCH v3 25/39] megaraid_sas: Change max_cmd from u32 to u16 in all functions

2017-02-10 Thread Shivasharan S
Since maximum supported FW commands are all defined as u16, change
all local variables referring to max_cmd from u32 to u16.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_base.c   | 10 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.c |  5 +++--
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index cd9d223..06001b4 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1549,7 +1549,7 @@ megasas_dump_pending_frames(struct megasas_instance 
*instance)
struct megasas_io_frame *ldio;
struct megasas_pthru_frame *pthru;
u32 sgcount;
-   u32 max_cmd = instance->max_fw_cmds;
+   u16 max_cmd = instance->max_fw_cmds;
 
dev_err(>pdev->dev, "[%d]: Dumping Frame Phys Address of all 
pending cmds in FW\n",instance->host->host_no);
dev_err(>pdev->dev, "[%d]: Total OS Pending cmds : 
%d\n",instance->host->host_no,atomic_read(>fw_outstanding));
@@ -3467,7 +3467,7 @@ megasas_internal_reset_defer_cmds(struct megasas_instance 
*instance)
 {
struct megasas_cmd *cmd;
int i;
-   u32 max_cmd = instance->max_fw_cmds;
+   u16 max_cmd = instance->max_fw_cmds;
u32 defer_index;
unsigned long flags;
 
@@ -3843,7 +3843,7 @@ megasas_transition_to_ready(struct megasas_instance 
*instance, int ocr)
 static void megasas_teardown_frame_pool(struct megasas_instance *instance)
 {
int i;
-   u32 max_cmd = instance->max_mfi_cmds;
+   u16 max_cmd = instance->max_mfi_cmds;
struct megasas_cmd *cmd;
 
if (!instance->frame_dma_pool)
@@ -3887,7 +3887,7 @@ static void megasas_teardown_frame_pool(struct 
megasas_instance *instance)
 static int megasas_create_frame_pool(struct megasas_instance *instance)
 {
int i;
-   u32 max_cmd;
+   u16 max_cmd;
u32 sge_sz;
u32 total_sz;
u32 frame_count;
@@ -4021,7 +4021,7 @@ int megasas_alloc_cmds(struct megasas_instance *instance)
 {
int i;
int j;
-   u32 max_cmd;
+   u16 max_cmd;
struct megasas_cmd *cmd;
struct fusion_context *fusion;
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index baea4c2..2d6d979 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -367,7 +367,7 @@ megasas_free_cmds_fusion(struct megasas_instance *instance)
 static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 {
int i;
-   u32 max_cmd;
+   u16 max_cmd;
struct fusion_context *fusion;
struct megasas_cmd_fusion *cmd;
 
@@ -1274,7 +1274,8 @@ megasas_init_adapter_fusion(struct megasas_instance 
*instance)
 {
struct megasas_register_set __iomem *reg_set;
struct fusion_context *fusion;
-   u32 max_cmd, scratch_pad_2;
+   u16 max_cmd;
+   u32 scratch_pad_2;
int i = 0, count;
 
fusion = instance->ctrl_context;
-- 
2.8.3



Re: [PATCH v3 19/39] megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access

2017-02-10 Thread Hannes Reinecke
On 02/10/2017 09:59 AM, Shivasharan S wrote:
> Change MR_TargetIdToLdGet return type from u8 to u16.
> 
> ld id range check is added at two places in this patch -
> @megasas_build_ldio_fusion and @megasas_build_ld_nonrw_fusion.
> Previous driver code used different data type for lds TargetId returned from 
> MR_TargetIdToLdGet.
> Prior to this change, above two functions was safeguarded due to function 
> always return u8
> and maximum value of ld id returned was 255.
> 
> In below check, fw_supported_vd_count as of today is 64 or 256 and
> valid range  to support is either 0-63 or 0-255. Ideally want to filter 
> accessing
> raid map for ld ids which are not valid. With the u16 change, invalid ld id 
> value
> is 0x and we will see kernel panic due to random memory access in 
> MR_LdRaidGet.
> The changes will ensure we do not call MR_LdRaidGet if ld id is beyond size 
> of ldSpanMap array.
> 
>if (ld < instance->fw_supported_vd_count)
> 
> From firmware perspective,ld id 0xFF is invalid and even though current driver
> code forward such command, firmware fails with target not available.
> 
> ld target id issue occurs mainly whenever driver loops to populate raid map 
> (ea. MR_ValidateMapInfo).
> These are the only two places where we may see out of range target ids and 
> wants to
> protect raid map access based on range provided by Firmware API.
> 
> Signed-off-by: Shivasharan S 
> Signed-off-by: Kashyap Desai 
> ---
> 
> fix in v2 - updated description content.
> 
>  drivers/scsi/megaraid/megaraid_sas.h|  2 +-
>  drivers/scsi/megaraid/megaraid_sas_fp.c |  5 +++--
>  drivers/scsi/megaraid/megaraid_sas_fusion.c | 25 ++---
>  3 files changed, 18 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
> b/drivers/scsi/megaraid/megaraid_sas.h
> index 0a20fff..efc01a3 100644
> --- a/drivers/scsi/megaraid/megaraid_sas.h
> +++ b/drivers/scsi/megaraid/megaraid_sas.h
> @@ -2448,7 +2448,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
>   struct IO_REQUEST_INFO *io_info,
>   struct RAID_CONTEXT *pRAID_Context,
>   struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN);
> -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map);
> +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map);
>  struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL *map);
>  u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map);
>  u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map);
> diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c 
> b/drivers/scsi/megaraid/megaraid_sas_fp.c
> index a0b0e68..9d5d485 100644
> --- a/drivers/scsi/megaraid/megaraid_sas_fp.c
> +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
> @@ -165,7 +165,7 @@ u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map)
>   return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId);
>  }
>  
> -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map)
> +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map)
>  {
>   return map->raidMap.ldTgtIdToLd[ldTgtId];
>  }
> @@ -1151,7 +1151,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
>  {
>   struct fusion_context *fusion;
>   struct MR_LD_RAID  *raid;
> - u32 ld, stripSize, stripe_mask;
> + u32 stripSize, stripe_mask;
>   u64 endLba, endStrip, endRow, start_row, start_strip;
>   u64 regStart;
>   u32 regSize;
> @@ -1163,6 +1163,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
>   u8  retval = 0;
>   u8  startlba_span = SPAN_INVALID;
>   u64 *pdBlock = _info->pdBlock;
> + u16 ld;
>  
>   ldStartBlock = io_info->ldStartBlock;
>   numBlocks = io_info->numBlocks;
> diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
> b/drivers/scsi/megaraid/megaraid_sas_fusion.c
> index 9019b82..4aaf307 100644
> --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
> +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
> @@ -1121,7 +1121,8 @@ megasas_sync_map_info(struct megasas_instance *instance)
>   int i;
>   struct megasas_cmd *cmd;
>   struct megasas_dcmd_frame *dcmd;
> - u32 size_sync_info, num_lds;
> + u16 num_lds;
> + u32 size_sync_info;
>   struct fusion_context *fusion;
>   struct MR_LD_TARGET_SYNC *ci = NULL;
>   struct MR_DRV_RAID_MAP_ALL *map;
> @@ -1870,7 +1871,7 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST 
> *io_request, u8 cdb_len,
>  struct MR_DRV_RAID_MAP_ALL *local_map_ptr, u32 ref_tag)
>  {
>   struct MR_LD_RAID *raid;
> - u32 ld;
> + u16 ld;
>   u64 start_blk = io_info->pdBlock;
>   u8 *cdb = io_request->CDB.CDB32;
>   u32 num_blocks = io_info->numBlocks;
> @@ -2303,10 +2304,11 @@ 

Re: aacraid: kernel: AAC: Host adapter dead -1 (bisected)

2017-02-10 Thread Andrey Melnikov
Cc: linux-scsi@vger.kernel.org

2017-02-10 13:24 GMT+03:00 Greg Kroah-Hartman :
> On Fri, Feb 10, 2017 at 02:25:26AM +0300, Andrey Jr. Melnikov wrote:
>> In article <201701151205.37563.a.miskiew...@gmail.com> you wrote:
>> > Newsgroups: gmane.linux.kernel
>>
>>
>> > Hi.
>>
>> > There is a bug with handling of adaptec raid cards (in my case it is 
>> > Adaptec
>> > 3405) where kernel logs hundreds of "AAC: Host adapter dead -1" messages.
>>
>> > Bug was reported previously on lkml but there was no progres in solving it.
>>
>> > There is also bugzilla entry:
>> > https://bugzilla.kernel.org/show_bug.cgi?id=151661
>>
>> > I've bisected that to commit bellow and indeed, reverting it from kernel 
>> > 4.9.3
>> > makes messages go away.
>>
>>
>> Don't try to switch Adaptec 3405/3805 RAID cards to MSI-X interrupt mode.
>> Fix https://bugzilla.kernel.org/show_bug.cgi?id=151661
>>
>> Signed-off-by: Andrey Jr. Melnikov 
>>
>> ---
>>
>> diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
>> index 969c312de1be..2ad8403dea40 100644
>> --- a/drivers/scsi/aacraid/aacraid.h
>> +++ b/drivers/scsi/aacraid/aacraid.h
>
> 
>
> Why are you sending this to me and not the scsi developers who can
> actually do something with this patch?

Bug in bugzilla open half year ago, microsemi maintainer slowly read
his fine docs about his hardware, broken driver fills our log with
useless messages every 10 seconds.
So, make decision - apply this patch to stable 4.9.x/4.4.x tree or
revert commit 78cbccd3bd683c295a44af8050797dc4a41376ff from it.


[PATCH v3 38/39] megaraid_sas: Change RAID_1_10_RMW_CMDS to RAID_1_PEER_CMDS and set value to 2

2017-02-10 Thread Shivasharan S
For RAID1 FastPath writes, driver needs to allocate extra commands
internally to accommodate for the extra peer command being sent.
Currently driver is allocating 2 extra commands for each but only
one extra command is necessary.
Set RAID_1_10_RMW_CMDS to 2 and also change macro name to
RAID_1_PEER_CMDS.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 9928766..7500901 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -293,7 +293,7 @@ megasas_fusion_update_can_queue(struct megasas_instance 
*instance, int fw_boot_c
 
if (instance->is_ventura)
instance->max_mpt_cmds =
-   instance->max_fw_cmds * RAID_1_10_RMW_CMDS;
+   instance->max_fw_cmds * RAID_1_PEER_CMDS;
else
instance->max_mpt_cmds = instance->max_fw_cmds;
 }
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h 
b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 8e8c35f..d78d7611 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -101,7 +101,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE {
 #define MEGASAS_FP_CMD_LEN 16
 #define MEGASAS_FUSION_IN_RESET 0
 #define THRESHOLD_REPLY_COUNT 50
-#define RAID_1_10_RMW_CMDS 3
+#define RAID_1_PEER_CMDS 2
 #define JBOD_MAPS_COUNT2
 
 enum MR_FUSION_ADAPTER_TYPE {
-- 
2.8.3



[PATCH v3 08/39] megaraid_sas: megasas_get_request_descriptor always return valid desc

2017-02-10 Thread Shivasharan S
No functional change. Code clean up. Removing error code which is not
valid scenario.
In megasas_get_request_descriptor we can remove the error handling
which is not required.
With fusion controllers, if there is a valid message frame available,
we are guaranteed to get a corresponding request descriptor.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---

Changes in v2 - split patches into two. 
discussed below 
http://marc.info/?l=linux-scsi=148638999110404=2

 drivers/scsi/megaraid/megaraid_sas_fusion.c | 24 ++--
 1 file changed, 2 insertions(+), 22 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 6ec7a18..b6c5dc5 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -2438,18 +2438,12 @@ megasas_build_io_fusion(struct megasas_instance 
*instance,
return 0;
 }
 
-union MEGASAS_REQUEST_DESCRIPTOR_UNION *
+static union MEGASAS_REQUEST_DESCRIPTOR_UNION *
 megasas_get_request_descriptor(struct megasas_instance *instance, u16 index)
 {
u8 *p;
struct fusion_context *fusion;
 
-   if (index >= instance->max_mpt_cmds) {
-   dev_err(>pdev->dev, "Invalid SMID (0x%x)request for "
-  "descriptor for scsi%d\n", index,
-   instance->host->host_no);
-   return NULL;
-   }
fusion = instance->ctrl_context;
p = fusion->req_frames_desc +
sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) * index;
@@ -2960,7 +2954,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
 union MEGASAS_REQUEST_DESCRIPTOR_UNION *
 build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
 {
-   union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+   union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc = NULL;
u16 index;
 
if (build_mpt_mfi_pass_thru(instance, cmd)) {
@@ -2972,9 +2966,6 @@ build_mpt_cmd(struct megasas_instance *instance, struct 
megasas_cmd *cmd)
 
req_desc = megasas_get_request_descriptor(instance, index - 1);
 
-   if (!req_desc)
-   return NULL;
-
req_desc->Words = 0;
req_desc->SCSIIO.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
 MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
@@ -2997,11 +2988,6 @@ megasas_issue_dcmd_fusion(struct megasas_instance 
*instance,
union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
 
req_desc = build_mpt_cmd(instance, cmd);
-   if (!req_desc) {
-   dev_info(>pdev->dev, "Failed from %s %d\n",
-   __func__, __LINE__);
-   return DCMD_NOT_FIRED;
-   }
 
megasas_fire_cmd_fusion(instance, req_desc);
return DCMD_SUCCESS;
@@ -3438,12 +3424,6 @@ megasas_issue_tm(struct megasas_instance *instance, u16 
device_handle,
 
req_desc = megasas_get_request_descriptor(instance,
(cmd_fusion->index - 1));
-   if (!req_desc) {
-   dev_err(>pdev->dev, "Failed from %s %d\n",
-   __func__, __LINE__);
-   megasas_return_cmd(instance, cmd_mfi);
-   return -ENOMEM;
-   }
 
cmd_fusion->request_desc = req_desc;
req_desc->Words = 0;
-- 
2.8.3



Re: aacraid: kernel: AAC: Host adapter dead -1 (bisected)

2017-02-10 Thread Greg Kroah-Hartman
On Fri, Feb 10, 2017 at 01:45:06PM +0300, Andrey Melnikov wrote:
> Cc: linux-scsi@vger.kernel.org
> 
> 2017-02-10 13:24 GMT+03:00 Greg Kroah-Hartman :
> > On Fri, Feb 10, 2017 at 02:25:26AM +0300, Andrey Jr. Melnikov wrote:
> >> In article <201701151205.37563.a.miskiew...@gmail.com> you wrote:
> >> > Newsgroups: gmane.linux.kernel
> >>
> >>
> >> > Hi.
> >>
> >> > There is a bug with handling of adaptec raid cards (in my case it is 
> >> > Adaptec
> >> > 3405) where kernel logs hundreds of "AAC: Host adapter dead -1" messages.
> >>
> >> > Bug was reported previously on lkml but there was no progres in solving 
> >> > it.
> >>
> >> > There is also bugzilla entry:
> >> > https://bugzilla.kernel.org/show_bug.cgi?id=151661
> >>
> >> > I've bisected that to commit bellow and indeed, reverting it from kernel 
> >> > 4.9.3
> >> > makes messages go away.
> >>
> >>
> >> Don't try to switch Adaptec 3405/3805 RAID cards to MSI-X interrupt mode.
> >> Fix https://bugzilla.kernel.org/show_bug.cgi?id=151661
> >>
> >> Signed-off-by: Andrey Jr. Melnikov 
> >>
> >> ---
> >>
> >> diff --git a/drivers/scsi/aacraid/aacraid.h 
> >> b/drivers/scsi/aacraid/aacraid.h
> >> index 969c312de1be..2ad8403dea40 100644
> >> --- a/drivers/scsi/aacraid/aacraid.h
> >> +++ b/drivers/scsi/aacraid/aacraid.h
> >
> > 
> >
> > Why are you sending this to me and not the scsi developers who can
> > actually do something with this patch?
> 
> Bug in bugzilla open half year ago, microsemi maintainer slowly read
> his fine docs about his hardware, broken driver fills our log with
> useless messages every 10 seconds.
> So, make decision - apply this patch to stable 4.9.x/4.4.x tree or
> revert commit 78cbccd3bd683c295a44af8050797dc4a41376ff from it.

I don't understand, that's not how the stable kernels work, please read
Documentation/stable_kernel_rules.txt for how the process works.  Please
get a patch accepted into Linus's tree and then we will be glad to apply
it to the stable kernel trees.

thanks,

greg k-h


[PATCH v3 24/39] megaraid_sas: set pd_after_lb from MR_BuildRaidContext and initialize pDevHandle to MR_DEVHANDLE_INVALID

2017-02-10 Thread Shivasharan S
Issue is limited for Syncro firmware where pd_after_lb is not set but is 
accidentally used.
Not a functional issue, but results in low performance due to improper load 
balancing between two LUNs.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_fp.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c 
b/drivers/scsi/megaraid/megaraid_sas_fp.c
index 68582d9..a5517e7 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -948,6 +948,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance 
*instance, u32 ld,
struct fusion_context *fusion;
 
fusion = instance->ctrl_context;
+   *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID);
 
/*Get row and span from io_info for Uneven Span IO.*/
row = io_info->start_row;
@@ -986,7 +987,6 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance 
*instance, u32 ld,
MR_PdDevHandleGet(r1_alt_pd, map);
}
} else {
-   *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID);
if ((raid->level >= 5) &&
((fusion->adapter_type == THUNDERBOLT_SERIES)  ||
((fusion->adapter_type == INVADER_SERIES) &&
@@ -1013,6 +1013,7 @@ static u8 mr_spanset_get_phy_params(struct 
megasas_instance *instance, u32 ld,
(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
io_info->span_arm = pRAID_Context->span_arm;
}
+   io_info->pd_after_lb = pd;
return retval;
 }
 
@@ -1049,7 +1050,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 
ld, u64 stripRow,
struct fusion_context *fusion;
 
fusion = instance->ctrl_context;
-
+   *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID);
 
row =  mega_div64_32(stripRow, raid->rowDataSize);
 
@@ -1102,8 +1103,6 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 
ld, u64 stripRow,
MR_PdDevHandleGet(r1_alt_pd, map);
}
} else {
-   /* set dev handle as invalid. */
-   *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID);
if ((raid->level >= 5) &&
((fusion->adapter_type == THUNDERBOLT_SERIES)  ||
((fusion->adapter_type == INVADER_SERIES) &&
@@ -1132,6 +1131,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 
ld, u64 stripRow,
(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
io_info->span_arm = pRAID_Context->span_arm;
}
+   io_info->pd_after_lb = pd;
return retval;
 }
 
-- 
2.8.3



[PATCH v3 15/39] megaraid_sas: enhance debug logs in OCR context

2017-02-10 Thread Shivasharan S
Add additional logging from driver in OCR context.
Add debug logs for partial completion of IOs is iodone context.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas.h|  3 +++
 drivers/scsi/megaraid/megaraid_sas_base.c   | 38 ++---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 35 +-
 3 files changed, 72 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index bed8a37..93da6dc 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1405,6 +1405,9 @@ struct megasas_ctrl_info {
 
 #define VD_EXT_DEBUG 0
 
+/* Driver's internal Logging levels*/
+#define OCR_LOGS(1 << 0)
+
 #define SCAN_PD_CHANNEL0x1
 #define SCAN_VD_CHANNEL0x2
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 51b35a6..b41bbea 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -2742,6 +2742,24 @@ blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd 
*scmd)
 }
 
 /**
+ * megasas_dump_frame -This function will dump MPT/MFI frame
+ */
+static inline void
+megasas_dump_frame(void *mpi_request, int sz)
+{
+   int i;
+   __le32 *mfp = (__le32 *)mpi_request;
+
+   printk(KERN_INFO "IO request frame:\n\t");
+   for (i = 0; i < sz; i++) {
+   if (i && ((i % 8) == 0))
+   printk("\n\t");
+   printk("%08x ", le32_to_cpu(mfp[i]));
+   }
+   printk("\n");
+}
+
+/**
  * megasas_reset_bus_host -Bus & host reset handler entry point
  */
 static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
@@ -2751,12 +2769,26 @@ static int megasas_reset_bus_host(struct scsi_cmnd 
*scmd)
 
instance = (struct megasas_instance *)scmd->device->host->hostdata;
 
+   scmd_printk(KERN_INFO, scmd,
+   "Controller reset is requested due to IO timeout\n"
+   "SCSI command pointer: (%p)\t SCSI host state: %d\t"
+   " SCSI host busy: %d\t FW outstanding: %d\n",
+   scmd, scmd->device->host->shost_state,
+   atomic_read((atomic_t *)>device->host->host_busy),
+   atomic_read(>fw_outstanding));
+
/*
 * First wait for all commands to complete
 */
-   if (instance->ctrl_context)
-   ret = megasas_reset_fusion(scmd->device->host, 1);
-   else
+   if (instance->ctrl_context) {
+   struct megasas_cmd_fusion *cmd;
+   cmd = (struct megasas_cmd_fusion *)scmd->SCp.ptr;
+   if (cmd)
+   megasas_dump_frame(cmd->io_request,
+   sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
+   ret = megasas_reset_fusion(scmd->device->host,
+   SCSIIO_TIMEOUT_OCR);
+   } else
ret = megasas_generic_reset(scmd);
 
return ret;
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 4628671..1252a3c 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1445,8 +1445,10 @@ map_cmd_status(struct fusion_context *fusion,
struct scsi_cmnd *scmd, u8 status, u8 ext_status,
u32 data_length, u8 *sense)
 {
+   u8 cmd_type;
int resid;
 
+   cmd_type = megasas_cmd_type(scmd);
switch (status) {
 
case MFI_STAT_OK:
@@ -1477,6 +1479,13 @@ map_cmd_status(struct fusion_context *fusion,
 */
resid = (scsi_bufflen(scmd) - data_length);
scsi_set_resid(scmd, resid);
+
+   if (resid &&
+   ((cmd_type == READ_WRITE_LDIO) ||
+   (cmd_type == READ_WRITE_SYSPDIO)))
+   scmd_printk(KERN_INFO, scmd, "BRCM Debug mfi stat 0x%x, 
data len"
+   " requested/completed 0x%x/0x%x\n",
+   status, scsi_bufflen(scmd), data_length);
break;
 
case MFI_STAT_LD_OFFLINE:
@@ -3477,6 +3486,14 @@ int megasas_wait_for_outstanding_fusion(struct 
megasas_instance *instance,
   " will reset adapter scsi%d.\n",
instance->host->host_no);
megasas_complete_cmd_dpc_fusion((unsigned 
long)instance);
+   if (instance->requestorId && reason) {
+   dev_warn(>pdev->dev, "SR-IOV Found FW 
in FAULT"
+   " state while polling during"
+   " I/O timeout handling for %d\n",

[PATCH v3 34/39] megaraid_sas: Use synchronize_irq to wait for IRQs to complete

2017-02-10 Thread Shivasharan S
FIX - Do not use random delay to synchronize with IRQ. Use kernel API.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index bafaf03..d8bfb87 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -3145,6 +3145,22 @@ complete_cmd_fusion(struct megasas_instance *instance, 
u32 MSIxIndex)
 }
 
 /**
+ * megasas_sync_irqs - Synchronizes all IRQs owned by adapter
+ * @instance:  Adapter soft state
+ */
+void megasas_sync_irqs(unsigned long instance_addr)
+{
+   u32 count, i;
+   struct megasas_instance *instance =
+   (struct megasas_instance *)instance_addr;
+
+   count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
+
+   for (i = 0; i < count; i++)
+   synchronize_irq(pci_irq_vector(instance->pdev, i));
+}
+
+/**
  * megasas_complete_cmd_dpc_fusion -   Completes command
  * @instance:  Adapter soft state
  *
@@ -3820,7 +3836,7 @@ megasas_issue_tm(struct megasas_instance *instance, u16 
device_handle,
break;
else {
instance->instancet->disable_intr(instance);
-   msleep(1000);
+   megasas_sync_irqs((unsigned long)instance);
megasas_complete_cmd_dpc_fusion
((unsigned long)instance);
instance->instancet->enable_intr(instance);
@@ -4174,7 +4190,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int 
reason)
set_bit(MEGASAS_FUSION_IN_RESET, >reset_flags);
atomic_set(>adprecovery, MEGASAS_ADPRESET_SM_POLLING);
instance->instancet->disable_intr(instance);
-   msleep(1000);
+   megasas_sync_irqs((unsigned long)instance);
 
/* First try waiting for commands to complete */
if (megasas_wait_for_outstanding_fusion(instance, reason,
-- 
2.8.3



[PATCH v3 00/39] megaraid_sas: Updates for scsi-next

2017-02-10 Thread Shivasharan S
Changes in v3:
Patch 21: Fix to pass rctx_g35 pointer to set/get_num_sge()
Move all v2 changelog descriptions beyond actual commit message body

Changes in v2:
Patch 3: Fix to update status and ex_status from failed r1_cmd
Patch 8: Split into two separate patches,
 1. megasas_get_request_descriptor will always return valid
request descriptor
 2. With above changes, issue_dcmd always return DCMD_SUCCESS.
Change return type to void and update all callers.
Patch 11: Update commit description, remove reference to dependent patch.
Patch 12: Update with correct commit description
Patch 14: Fix typo in commit description
Patch 19: Correction to commit description
Drop patch 33 of last patch series which added call for flush_scheduled_work

Shivasharan S (39):
  Revert "scsi: megaraid_sas: Enable or Disable Fast path based on the
PCI Threshold Bandwidth"
  megaraid_sas: cpu select rework.
  megaraid_sas: raid 1 fast path code optimize
  megaraid_sas: 32 bit descriptor fire cmd optimization
  megaraid_sas: Refactor MEGASAS_IS_LOGICAL macro using sdev
  megaraid_sas: RAID map is accessed for SYS PDs when use_seqnum_jbod_fp
is not set
  megaraid_sas: Use DID_REQUEUE
  megaraid_sas: megasas_get_request_descriptor always return valid desc
  megaraid_sas: change issue_dcmd to return void from int
  megaraid_sas: NVME Interface detection and prop settings
  megaraid_sas: NVME interface target prop added
  megaraid_sas: NVME fast path io support
  megaraid_sas: raid 1 write performance for large io
  megaraid_sas: set residual bytes count during IO completion
  megaraid_sas: enhance debug logs in OCR context
  megaraid_sas: add print in device removal path
  megaraid_sas: reduce size of fusion_context and use vmalloc if kmalloc
fails
  megaraid_sas: In validate raid map, raid capability is not converted
to cpu format for all lds
  megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map
access
  megaraid_sas: Big endian RDPQ mode fix
  megaraid_sas: big endian support changes
  megaraid_sas: avoid unaligned access in ioctl path
  megaraid_sas: latest controller OCR capability from FW before sending
shutdown DCMD
  megaraid_sas: set pd_after_lb from MR_BuildRaidContext and initialize
pDevHandle to MR_DEVHANDLE_INVALID
  megaraid_sas: Change max_cmd from u32 to u16 in all functions
  megaraid_sas: update can_queue only if the new value is less
  megaraid_sas: max_fw_cmds are decremented twice, remove duplicate
  megaraid_sas: megasas_return_cmd does not memset IO frame to zero
  megaraid_sas: Remove unused pd_index from
megasas_build_ld_nonrw_fusion
  megaraid_sas: Do not set fp_possible if TM capable for non-RW syspdIO,
change fp_possible to bool
  megaraid_sas: During OCR, if get_ctrl_info fails do not continue with
OCR
  megaraid_sas: Change build_mpt_mfi_pass_thru to return void
  megaraid_sas: Bail out the driver load if ld_list_query fails
  megaraid_sas: Use synchronize_irq to wait for IRQs to complete
  megaraid_sas: Increase internal command pool
  megaraid_sas: Cleanup VD_EXT_DEBUG and SPAN_DEBUG related debug prints
  megaraid_sas: Indentation and smatch warning fixes
  megaraid_sas: Change RAID_1_10_RMW_CMDS to RAID_1_PEER_CMDS and set
value to 2
  megaraid_sas: driver version upgrade

 drivers/scsi/megaraid/megaraid_sas.h|   82 +-
 drivers/scsi/megaraid/megaraid_sas_base.c   |  548 +++
 drivers/scsi/megaraid/megaraid_sas_fp.c |  427 ++---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 1352 ---
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  144 ++-
 5 files changed, 1434 insertions(+), 1119 deletions(-)

-- 
2.8.3



[PATCH v3 11/39] megaraid_sas: NVME interface target prop added

2017-02-10 Thread Shivasharan S
This patch fetch true values of NVME property from FW using New DCMD interface 
MR_DCMD_DEV_GET_TARGET_PROP

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas.h|  14 +++
 drivers/scsi/megaraid/megaraid_sas_base.c   | 144 +++-
 drivers/scsi/megaraid/megaraid_sas_fusion.h |   1 +
 3 files changed, 155 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index f9efddf..a45ff10 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -695,6 +695,18 @@ struct  MR_PD_INFO {
u8 reserved1[512-428];
 } __packed;
 
+/*
+ * Definition of structure used to expose attributes of VD or JBOD
+ * (this structure is to be filled by firmware when MR_DCMD_DRV_GET_TARGET_PROP
+ * is fired by driver)
+ */
+struct MR_TARGET_PROPERTIES {
+   u32max_io_size_kb;
+   u32device_qdepth;
+   u32sector_size;
+   u8 reserved[500];
+} __packed;
+
  /*
  * defines the physical drive address structure
  */
@@ -2090,6 +2102,8 @@ struct megasas_instance {
dma_addr_t hb_host_mem_h;
struct MR_PD_INFO *pd_info;
dma_addr_t pd_info_h;
+   struct MR_TARGET_PROPERTIES *tgt_prop;
+   dma_addr_t tgt_prop_h;
 
__le32 *reply_queue;
dma_addr_t reply_queue_h;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index f383bf2..51b35a6 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -118,6 +118,8 @@ static int megasas_register_aen(struct megasas_instance 
*instance,
u32 seq_num, u32 class_locale_word);
 static void megasas_get_pd_info(struct megasas_instance *instance,
struct scsi_device *sdev);
+static int megasas_get_target_prop(struct megasas_instance *instance,
+  struct scsi_device *sdev);
 /*
  * PCI ID table for all supported controllers
  */
@@ -1834,14 +1836,16 @@ megasas_set_nvme_device_properties(struct scsi_device 
*sdev, u32 max_io_size)
  * set nvme device properties. see - megasas_set_nvme_device_properties
  *
  * @sdev:  scsi device
- *
+ * @is_target_prop true, if fw provided target properties.
  */
-static void megasas_set_static_target_properties(struct scsi_device *sdev)
+static void megasas_set_static_target_properties(struct scsi_device *sdev,
+bool is_target_prop)
 {
u16 target_index = 0;
u8 interface_type;
u32 device_qd = MEGASAS_DEFAULT_CMD_PER_LUN;
u32 max_io_size_kb = MR_DEFAULT_NVME_MDTS_KB;
+   u32 tgt_device_qd;
struct megasas_instance *instance;
struct MR_PRIV_DEVICE *mr_device_priv_data;
 
@@ -1868,6 +1872,18 @@ static void megasas_set_static_target_properties(struct 
scsi_device *sdev)
break;
}
 
+   if (is_target_prop) {
+   tgt_device_qd = le32_to_cpu(instance->tgt_prop->device_qdepth);
+   if (tgt_device_qd &&
+   (tgt_device_qd <= instance->host->can_queue))
+   device_qd = tgt_device_qd;
+
+   /* max_io_size_kb will be set to non zero for
+* nvme based vd and syspd.
+*/
+   max_io_size_kb = 
le32_to_cpu(instance->tgt_prop->max_io_size_kb);
+   }
+
if (instance->nvme_page_size && max_io_size_kb)
megasas_set_nvme_device_properties(sdev, (max_io_size_kb << 
10));
 
@@ -1880,6 +1896,8 @@ static int megasas_slave_configure(struct scsi_device 
*sdev)
 {
u16 pd_index = 0;
struct megasas_instance *instance;
+   int ret_target_prop = DCMD_FAILED;
+   bool is_target_prop = false;
 
instance = megasas_lookup_instance(sdev->host->host_no);
if (instance->pd_list_not_supported) {
@@ -1897,7 +1915,14 @@ static int megasas_slave_configure(struct scsi_device 
*sdev)
if ((instance->pd_info) && !MEGASAS_IS_LOGICAL(sdev))
megasas_get_pd_info(instance, sdev);
 
-   megasas_set_static_target_properties(sdev);
+   /* Some ventura firmware may not have instance->nvme_page_size set.
+* Do not send MR_DCMD_DRV_GET_TARGET_PROP
+*/
+   if ((instance->tgt_prop) && (instance->nvme_page_size))
+   ret_target_prop = megasas_get_target_prop(instance, sdev);
+
+   is_target_prop = (ret_target_prop == DCMD_SUCCESS) ? true : false;
+   megasas_set_static_target_properties(sdev, is_target_prop);
 
mutex_unlock(>hba_mutex);
 
@@ -5682,6 +5707,98 @@ megasas_register_aen(struct megasas_instance 

[PATCH v3 21/39] megaraid_sas: big endian support changes

2017-02-10 Thread Shivasharan S
Fix endiannes fixes for Ventura specific.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---

Fix in v3: Pass RAID_CONTEXT_G35 pointer to get/set_num_sge

 drivers/scsi/megaraid/megaraid_sas_fp.c |  15 ++--
 drivers/scsi/megaraid/megaraid_sas_fusion.c |  70 ++---
 drivers/scsi/megaraid/megaraid_sas_fusion.h | 115 +---
 3 files changed, 122 insertions(+), 78 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c 
b/drivers/scsi/megaraid/megaraid_sas_fp.c
index 9d5d485..68582d9 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -210,7 +210,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance 
*instance)
le32_to_cpu(fw_map_dyn->desc_table_size),
le32_to_cpu(fw_map_dyn->desc_table_num_elements));
dev_dbg(>pdev->dev, "drv map %p ldCount %d\n",
-   drv_map, fw_map_dyn->ld_count);
+   drv_map, le16_to_cpu(fw_map_dyn->ld_count));
 #endif
desc_table =
(struct MR_RAID_MAP_DESC_TABLE *)((void *)fw_map_dyn + 
le32_to_cpu(fw_map_dyn->desc_table_offset));
@@ -222,7 +222,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance 
*instance)
pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count);
pDrvRaidMap->fpPdIoTimeoutSec =
fw_map_dyn->fp_pd_io_timeout_sec;
-   pDrvRaidMap->totalSize = sizeof(struct MR_DRV_RAID_MAP_ALL);
+   pDrvRaidMap->totalSize =
+   cpu_to_le32(sizeof(struct MR_DRV_RAID_MAP_ALL));
/* point to actual data starting point*/
raid_map_data = (void *)fw_map_dyn +
le32_to_cpu(fw_map_dyn->desc_table_offset) +
@@ -234,11 +235,11 @@ void MR_PopulateDrvRaidMap(struct megasas_instance 
*instance)
dev_dbg(>pdev->dev, "desc table %p\n",
desc_table);
dev_dbg(>pdev->dev, "raidmap type %d, 
raidmapOffset 0x%x\n",
-   desc_table->raid_map_desc_type,
-   desc_table->raid_map_desc_offset);
+   le32_to_cpu(desc_table->raid_map_desc_type),
+   le32_to_cpu(desc_table->raid_map_desc_offset));
dev_dbg(>pdev->dev, "raid map number of 
elements 0%x, raidmapsize 0x%x\n",
-   desc_table->raid_map_desc_elements,
-   desc_table->raid_map_desc_buffer_size);
+   le32_to_cpu(desc_table->raid_map_desc_elements),
+   
le32_to_cpu(desc_table->raid_map_desc_buffer_size));
 #endif
switch (le32_to_cpu(desc_table->raid_map_desc_type)) {
case RAID_MAP_DESC_TYPE_DEVHDL_INFO:
@@ -263,7 +264,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance 
*instance)
 #endif
for (j = 0; j < 
le32_to_cpu(desc_table->raid_map_desc_elements); j++) {
pDrvRaidMap->ldTgtIdToLd[j] =
-   fw_map_dyn->ld_tgt_id_to_ld[j];
+   
le16_to_cpu(fw_map_dyn->ld_tgt_id_to_ld[j]);
 #if VD_EXT_DEBUG
dev_dbg(>pdev->dev, " %d drv 
ldTgtIdToLd %d\n",
j, pDrvRaidMap->ldTgtIdToLd[j]);
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index b26ee85..baea4c2 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -2080,7 +2080,7 @@ static void megasas_stream_detect(struct megasas_instance 
*instance,
 */
continue;
 
-   cmd->io_request->RaidContext.raid_context_g35.stream_detected = 
true;
+   
SET_STREAM_DETECTED(cmd->io_request->RaidContext.raid_context_g35);
current_sd->next_seq_lba =
io_info->ldStartBlock + io_info->numBlocks;
/*
@@ -2154,7 +2154,8 @@ megasas_set_raidflag_cpu_affinity(union 
RAID_CONTEXT_UNION *praid_context,
/* Fast path cache by pass capable R0/R1 VD */
if ((raid->level <= 1) &&
(raid->capability.fp_cache_bypass_capable)) {
-   rctx_g35->routing_flags.bits.sld = 1;
+   rctx_g35->routing_flags |=
+   (1 << 
MR_RAID_CTX_ROUTINGFLAGS_SLD_SHIFT);
rctx_g35->raid_flags =

[PATCH v3 36/39] megaraid_sas: Cleanup VD_EXT_DEBUG and SPAN_DEBUG related debug prints

2017-02-10 Thread Shivasharan S
Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas.h|   2 -
 drivers/scsi/megaraid/megaraid_sas_base.c   |  15 --
 drivers/scsi/megaraid/megaraid_sas_fp.c | 266 +---
 drivers/scsi/megaraid/megaraid_sas_fusion.c |   5 -
 4 files changed, 2 insertions(+), 286 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 42c0e1f..dc331e8 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1403,8 +1403,6 @@ struct megasas_ctrl_info {
 
 #define MEGASAS_FW_BUSY1
 
-#define VD_EXT_DEBUG 0
-
 /* Driver's internal Logging levels*/
 #define OCR_LOGS(1 << 0)
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 0e7121d..5e0dea1 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -4601,17 +4601,6 @@ static void megasas_update_ext_vd_details(struct 
megasas_instance *instance)
}
/* irrespective of FW raid maps, driver raid map is constant */
fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP_ALL);
-
-#if VD_EXT_DEBUG
-   dev_info(>pdev->dev, "instance->max_raid_mapsize 0x%x\n ",
-   instance->max_raid_mapsize);
-   dev_info(>pdev->dev, "new_map_sz = 0x%x, old_map_sz = 0x%x\n",
-   fusion->new_map_sz, fusion->old_map_sz);
-   dev_info(>pdev->dev, "ventura_map_sz = 0x%x, current_map_sz = 
0x%x\n",
-   ventura_map_sz, fusion->current_map_sz);
-   dev_info(>pdev->dev, "fusion->drv_map_sz =0x%x, size of 
driver raid map 0x%lx\n",
-   fusion->drv_map_sz, sizeof(struct MR_DRV_RAID_MAP_ALL));
-#endif
 }
 
 /**
@@ -5215,10 +5204,6 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
if (instance->is_ventura) {
scratch_pad_3 =
readl(>reg_set->outbound_scratch_pad_3);
-#if VD_EXT_DEBUG
-   dev_info(>pdev->dev, "scratch_pad3 0x%x\n",
-   scratch_pad_3);
-#endif
instance->max_raid_mapsize = ((scratch_pad_3 >>
MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT) &
MR_MAX_RAID_MAP_SIZE_MASK);
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c 
b/drivers/scsi/megaraid/megaraid_sas_fp.c
index a5517e7..7dc7708 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -77,7 +77,6 @@ MODULE_PARM_DESC(lb_pending_cmds, "Change raid-1 load 
balancing outstanding "
 #endif
 #define TRUE 1
 
-#define SPAN_DEBUG 0
 #define SPAN_ROW_SIZE(map, ld, index_) (MR_LdSpanPtrGet(ld, index_, 
map)->spanRowSize)
 #define SPAN_ROW_DATA_SIZE(map_, ld, index_)   (MR_LdSpanPtrGet(ld, index_, 
map)->spanRowDataSize)
 #define SPAN_INVALID  0xff
@@ -202,16 +201,6 @@ void MR_PopulateDrvRaidMap(struct megasas_instance 
*instance)
 
if (instance->max_raid_mapsize) {
fw_map_dyn = fusion->ld_map[(instance->map_id & 1)];
-#if VD_EXT_DEBUG
-   dev_dbg(>pdev->dev, "raidMapSize 0x%x 
fw_map_dyn->descTableOffset 0x%x\n",
-   le32_to_cpu(fw_map_dyn->raid_map_size),
-   le32_to_cpu(fw_map_dyn->desc_table_offset));
-   dev_dbg(>pdev->dev, "descTableSize 0x%x 
descTableNumElements 0x%x\n",
-   le32_to_cpu(fw_map_dyn->desc_table_size),
-   le32_to_cpu(fw_map_dyn->desc_table_num_elements));
-   dev_dbg(>pdev->dev, "drv map %p ldCount %d\n",
-   drv_map, le16_to_cpu(fw_map_dyn->ld_count));
-#endif
desc_table =
(struct MR_RAID_MAP_DESC_TABLE *)((void *)fw_map_dyn + 
le32_to_cpu(fw_map_dyn->desc_table_offset));
if (desc_table != fw_map_dyn->raid_map_desc_table)
@@ -230,25 +219,10 @@ void MR_PopulateDrvRaidMap(struct megasas_instance 
*instance)
le32_to_cpu(fw_map_dyn->desc_table_size);
 
for (i = 0; i < 
le32_to_cpu(fw_map_dyn->desc_table_num_elements); ++i) {
-
-#if VD_EXT_DEBUG
-   dev_dbg(>pdev->dev, "desc table %p\n",
-   desc_table);
-   dev_dbg(>pdev->dev, "raidmap type %d, 
raidmapOffset 0x%x\n",
-   le32_to_cpu(desc_table->raid_map_desc_type),
-   le32_to_cpu(desc_table->raid_map_desc_offset));
-   dev_dbg(>pdev->dev, "raid map number of 
elements 0%x, raidmapsize 0x%x\n",
-   le32_to_cpu(desc_table->raid_map_desc_elements),
-   
le32_to_cpu(desc_table->raid_map_desc_buffer_size));
-#endif
   

[PATCH v3 13/39] megaraid_sas: raid 1 write performance for large io

2017-02-10 Thread Shivasharan S
Avoid Host side PCI bandwidth bottleneck and hint FW to do Write buffering using
RaidFlag MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT.
Once IO is landed in FW with MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT,
it will do single DMA from host and buffer the Write operation. On back end,
FW will DMA same buffer to the Mirror and Data Arm.
This will improve large block IO performance which bottleneck due to Host side 
PCI bandwidth limitation.

Consistent ~4000MB T.P for 256K Block size is expected performance numbers.
IOPS for small Block size should be on par with Disk performance.
(E.g 42 SAS Disk in JBOD mode gives 3700MB T.P.
Same Drive used in R1 WT mode, should give ~1800MB T.P)

Using this patch 24 R1 VDs (HDD) gives below performance for Sequential Write.
Without this patch, we cannot reach above 3200MB (Throughput is in MB. )

Block Size  50% 256K and 50% 4K  100% 256K
4K 31002030
8K 31402740
16K31403140
32K34003240
64K35003700
128K   38703870
256K   39203920

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas.h|  5 +
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 32 +++--
 2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 075e2e9..bed8a37 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1409,6 +1409,8 @@ struct megasas_ctrl_info {
 #define SCAN_VD_CHANNEL0x2
 
 #define MEGASAS_KDUMP_QUEUE_DEPTH   100
+#define MR_LARGE_IO_MIN_SIZE   (32 * 1024)
+#define MR_R1_LDIO_PIGGYBACK_DEFAULT   4
 
 enum MR_SCSI_CMD_TYPE {
READ_WRITE_LDIO = 0,
@@ -1875,6 +1877,7 @@ union megasas_frame {
 struct MR_PRIV_DEVICE {
bool is_tm_capable;
bool tm_busy;
+   atomic_t r1_ldio_hint;
u8   interface_type;
 };
 struct megasas_cmd;
@@ -2235,6 +2238,8 @@ struct megasas_instance {
bool is_ventura;
bool msix_combined;
u16 max_raid_mapsize;
+   /* preffered count to send as LDIO irrspective of FP capable.*/
+   u8  r1_ldio_hint_default;
u32 nvme_page_size;
 };
 struct MR_LD_VF_MAP {
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 379c723..edbecc5 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1383,6 +1383,7 @@ megasas_init_adapter_fusion(struct megasas_instance 
*instance)
}
 
instance->flag_ieee = 1;
+   instance->r1_ldio_hint_default =  MR_R1_LDIO_PIGGYBACK_DEFAULT;
fusion->fast_path_io = 0;
 
fusion->drv_map_pages = get_order(fusion->drv_map_sz);
@@ -2110,7 +2111,7 @@ static void megasas_stream_detect(struct megasas_instance 
*instance,
 static void
 megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context,
  struct MR_LD_RAID *raid, bool fp_possible,
- u8 is_read)
+ u8 is_read, u32 scsi_buff_len)
 {
u8 cpu_sel = MR_RAID_CTX_CPUSEL_0;
struct RAID_CONTEXT_G35 *rctx_g35;
@@ -2161,6 +2162,17 @@ megasas_set_raidflag_cpu_affinity(union 
RAID_CONTEXT_UNION *praid_context,
}
 
rctx_g35->routing_flags.bits.cpu_sel = cpu_sel;
+
+   /* Always give priority to MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT
+* vs MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS.
+* IO Subtype is not bitmap.
+*/
+   if ((raid->level == 1) && (!is_read)) {
+   if (scsi_buff_len > MR_LARGE_IO_MIN_SIZE)
+   praid_context->raid_context_g35.raid_flags =
+   (MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT
+   << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT);
+   }
 }
 
 /**
@@ -2303,6 +2315,14 @@ megasas_build_ldio_fusion(struct megasas_instance 
*instance,
io_info.isRead && io_info.ra_capable)
fp_possible = false;
 
+   /* FP for Optimal raid level 1.
+* All large RAID-1 writes (> 32 KiB, both WT and WB modes)
+* are built by the driver as LD I/Os.
+* All small RAID-1 WT writes (<= 32 KiB) are built as FP I/Os
+* (there is never a reason to process these as buffered writes)
+* All small RAID-1 WB writes (<= 32 KiB) are built as FP I/Os
+* with the 

[PATCH v3 18/39] megaraid_sas: In validate raid map, raid capability is not converted to cpu format for all lds

2017-02-10 Thread Shivasharan S
On a host, if an ld is deleted there is a hole in the ld array returned
by the FW. But in MR_ValidateMapInfo we are not accounting for holes in
the ld array and traverse only upto index num_lds.
This patch takes care of converting the capability field of all the
valid lds in the ld raid map.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_fp.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c 
b/drivers/scsi/megaraid/megaraid_sas_fp.c
index d9b0f28..a0b0e68 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -452,7 +452,7 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance)
struct LD_LOAD_BALANCE_INFO *lbInfo;
PLD_SPAN_INFO ldSpanInfo;
struct MR_LD_RAID *raid;
-   u16 ldCount, num_lds;
+   u16 num_lds, i;
u16 ld;
u32 expected_size;
 
@@ -495,10 +495,17 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance)
num_lds = le16_to_cpu(drv_map->raidMap.ldCount);
 
/*Convert Raid capability values to CPU arch */
-   for (ldCount = 0; ldCount < num_lds; ldCount++) {
-   ld = MR_TargetIdToLdGet(ldCount, drv_map);
+   for (i = 0; (num_lds > 0) && (i < MAX_LOGICAL_DRIVES_EXT); i++) {
+   ld = MR_TargetIdToLdGet(i, drv_map);
+
+   /* For non existing VDs, iterate to next VD*/
+   if (ld >= (MAX_LOGICAL_DRIVES_EXT - 1))
+   continue;
+
raid = MR_LdRaidGet(ld, drv_map);
le32_to_cpus((u32 *)>capability);
+
+   num_lds--;
}
 
return 1;
-- 
2.8.3



[PATCH v3 20/39] megaraid_sas: Big endian RDPQ mode fix

2017-02-10 Thread Shivasharan S
Fix if RDPQ mode enabled MR FW is deployed on big endian host machine,
driver does not setup reply address correctly.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 4aaf307..b26ee85 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -580,7 +580,7 @@ megasas_alloc_rdpq_fusion(struct megasas_instance *instance)
}
 
fusion->rdpq_virt[i].RDPQBaseAddress =
-   fusion->reply_frames_desc_phys[i];
+   cpu_to_le64(fusion->reply_frames_desc_phys[i]);
 
reply_desc = fusion->reply_frames_desc[i];
for (j = 0; j < fusion->reply_q_depth; j++, reply_desc++)
-- 
2.8.3



[PATCH v3 37/39] megaraid_sas: Indentation and smatch warning fixes

2017-02-10 Thread Shivasharan S
Fix indentation issues and smatch warning reported by Dan Carpenter
for previous series as discussed below.
http://www.spinics.net/lists/linux-scsi/msg103635.html
http://www.spinics.net/lists/linux-scsi/msg103603.html

Reported-by: Dan Carpenter 
Signed-off-by: Kashyap Desai 
Signed-off-by: Sasikumar Chandrasekaran 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas.h|  2 +-
 drivers/scsi/megaraid/megaraid_sas_base.c   | 10 ++--
 drivers/scsi/megaraid/megaraid_sas_fp.c | 57 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 92 ++---
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  2 +-
 5 files changed, 80 insertions(+), 83 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index dc331e8..8c06cbf 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1376,7 +1376,7 @@ struct megasas_ctrl_info {
u16 reserved:8;
#endif
} adapter_operations4;
-   u8 pad[0x800-0x7FE]; /* 0x7FE pad to 2K for expansion */
+   u8 pad[0x800 - 0x7FE]; /* 0x7FE pad to 2K for expansion */
 } __packed;
 
 /*
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 5e0dea1..dc9f42e 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -5343,14 +5343,14 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
 
/* stream detection initialization */
-   if (instance->is_ventura) {
+   if (instance->is_ventura && fusion) {
fusion->stream_detect_by_ld =
-   kzalloc(sizeof(struct LD_STREAM_DETECT *)
-   * MAX_LOGICAL_DRIVES_EXT,
-   GFP_KERNEL);
+   kzalloc(sizeof(struct LD_STREAM_DETECT *)
+   * MAX_LOGICAL_DRIVES_EXT,
+   GFP_KERNEL);
if (!fusion->stream_detect_by_ld) {
dev_err(>pdev->dev,
-   "unable to allocate stream detection 
for pool of LDs\n");
+   "unable to allocate stream detection for pool 
of LDs\n");
goto fail_get_ld_pd_list;
}
for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) {
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c 
b/drivers/scsi/megaraid/megaraid_sas_fp.c
index 7dc7708..62affa7 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -197,7 +197,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance 
*instance)
 
memset(drv_map, 0, fusion->drv_map_sz);
memset(pDrvRaidMap->ldTgtIdToLd,
-   0xff, (sizeof(u16) * MAX_LOGICAL_DRIVES_DYN));
+  0xff, (sizeof(u16) * MAX_LOGICAL_DRIVES_DYN));
 
if (instance->max_raid_mapsize) {
fw_map_dyn = fusion->ld_map[(instance->map_id & 1)];
@@ -224,34 +224,37 @@ void MR_PopulateDrvRaidMap(struct megasas_instance 
*instance)
fw_map_dyn->dev_hndl_info =
(struct MR_DEV_HANDLE_INFO *)(raid_map_data + 
le32_to_cpu(desc_table->raid_map_desc_offset));
memcpy(pDrvRaidMap->devHndlInfo,
-   fw_map_dyn->dev_hndl_info,
-   sizeof(struct MR_DEV_HANDLE_INFO) *
-   
le32_to_cpu(desc_table->raid_map_desc_elements));
+   fw_map_dyn->dev_hndl_info,
+   sizeof(struct MR_DEV_HANDLE_INFO) *
+   
le32_to_cpu(desc_table->raid_map_desc_elements));
break;
case RAID_MAP_DESC_TYPE_TGTID_INFO:
fw_map_dyn->ld_tgt_id_to_ld =
-   (u16 *) (raid_map_data +
-   le32_to_cpu(desc_table->raid_map_desc_offset));
-   for (j = 0; j < 
le32_to_cpu(desc_table->raid_map_desc_elements); j++) {
-   pDrvRaidMap->ldTgtIdToLd[j] =
-   
le16_to_cpu(fw_map_dyn->ld_tgt_id_to_ld[j]);
-   }
+   (u16 *)(raid_map_data +
+   
le32_to_cpu(desc_table->raid_map_desc_offset));
+   for (j = 0; j < 
le32_to_cpu(desc_table->raid_map_desc_elements); j++) {
+   pDrvRaidMap->ldTgtIdToLd[j] =
+   
le16_to_cpu(fw_map_dyn->ld_tgt_id_to_ld[j]);
+

[PATCH v3 03/39] megaraid_sas: raid 1 fast path code optimize

2017-02-10 Thread Shivasharan S
No functional change. Code refactor.
Remove function megasas_fpio_to_ldio as we never require to convert fpio to 
ldio because of frame unavailability.
Grab extra frame of raid 1 write fast path before it creates first frame as 
Fast Path.
Removed is_raid_1_fp_write flag as raid 1 write fast path command is decided 
using r1_alt_dev_handle only.
Move resetting megasas_cmd_fusion fields at common function 
megasas_return_cmd_fusion.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---

Fix in v2:
ex_status and status was wrongly re-used in megasas_complete_r1_command.
discussed below -
http://marc.info/?l=linux-scsi=148638763409385=2

 drivers/scsi/megaraid/megaraid_sas_fp.c |  14 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 349 +---
 drivers/scsi/megaraid/megaraid_sas_fusion.h |   3 +-
 3 files changed, 118 insertions(+), 248 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c 
b/drivers/scsi/megaraid/megaraid_sas_fp.c
index f1384b0..24258af 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -1338,20 +1338,8 @@ MR_BuildRaidContext(struct megasas_instance *instance,
ref_in_start_stripe, io_info,
pRAID_Context, map);
/* If IO on an invalid Pd, then FP is not possible.*/
-   if (io_info->devHandle == cpu_to_le16(MR_PD_INVALID))
+   if (io_info->devHandle == MR_DEVHANDLE_INVALID)
io_info->fpOkForIo = FALSE;
-   /* if FP possible, set the SLUD bit in
-*  regLockFlags for ventura
-*/
-   else if ((instance->is_ventura) && (!isRead) &&
-   (raid->writeMode == MR_RL_WRITE_BACK_MODE) &&
-   (raid->capability.fp_cache_bypass_capable))
-   ((struct RAID_CONTEXT_G35 *) 
pRAID_Context)->routing_flags.bits.sld = 1;
-   /* set raid 1/10 fast path write capable bit in io_info */
-   if (io_info->fpOkForIo &&
-   (io_info->r1_alt_dev_handle != MR_PD_INVALID) &&
-   (raid->level == 1) && !isRead)
-   io_info->is_raid_1_fp_write = 1;
return retval;
} else if (isRead) {
uint stripIdx;
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 514c306..7516589 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -181,7 +181,9 @@ inline void megasas_return_cmd_fusion(struct 
megasas_instance *instance,
struct megasas_cmd_fusion *cmd)
 {
cmd->scmd = NULL;
-   memset(cmd->io_request, 0, sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
+   memset(cmd->io_request, 0, MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE);
+   cmd->r1_alt_dev_handle = MR_DEVHANDLE_INVALID;
+   cmd->cmd_completed = false;
 }
 
 /**
@@ -701,7 +703,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
memset(cmd->io_request, 0,
   sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
cmd->io_request_phys_addr = io_req_base_phys + offset;
-   cmd->is_raid_1_fp_write = 0;
+   cmd->r1_alt_dev_handle = MR_DEVHANDLE_INVALID;
}
 
if (megasas_create_sg_sense_fusion(instance))
@@ -1984,7 +1986,7 @@ megasas_build_ldio_fusion(struct megasas_instance 
*instance,
io_info.ldStartBlock = ((u64)start_lba_hi << 32) | start_lba_lo;
io_info.numBlocks = datalength;
io_info.ldTgtId = device_id;
-   io_info.r1_alt_dev_handle = MR_PD_INVALID;
+   io_info.r1_alt_dev_handle = MR_DEVHANDLE_INVALID;
scsi_buff_len = scsi_bufflen(scp);
io_request->DataLength = cpu_to_le32(scsi_buff_len);
 
@@ -2025,7 +2027,7 @@ megasas_build_ldio_fusion(struct megasas_instance 
*instance,
io_info.isRead && io_info.ra_capable)
fp_possible = false;
 
-   if (io_info.r1_alt_dev_handle != MR_PD_INVALID) {
+   if (io_info.r1_alt_dev_handle != MR_DEVHANDLE_INVALID) {
mrdev_priv = scp->device->hostdata;
 
if (atomic_inc_return(>fw_outstanding) >
@@ -2090,9 +2092,10 @@ megasas_build_ldio_fusion(struct megasas_instance 
*instance,
} else
scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG;
 
-   cmd->is_raid_1_fp_write = io_info.is_raid_1_fp_write;
-   if (io_info.is_raid_1_fp_write)
+   if (instance->is_ventura)
cmd->r1_alt_dev_handle = io_info.r1_alt_dev_handle;
+   else
+   

[PATCH v3 27/39] megaraid_sas: max_fw_cmds are decremented twice, remove duplicate

2017-02-10 Thread Shivasharan S
Fix to account for the reply_q_sz not exceeding
the maximum commands that the firmware can support,
instance->max_fw_cmds is already decremented in
megasas_fusion_update_can_queue().
Remove the extra decrement logic in code.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 94b7a68..74cefae 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1285,13 +1285,6 @@ megasas_init_adapter_fusion(struct megasas_instance 
*instance)
megasas_fusion_update_can_queue(instance, PROBE_CONTEXT);
 
/*
-* Reduce the max supported cmds by 1. This is to ensure that the
-* reply_q_sz (1 more than the max cmd that driver may send)
-* does not exceed max cmds that the FW can support
-*/
-   instance->max_fw_cmds = instance->max_fw_cmds-1;
-
-   /*
 * Only Driver's internal DCMDs and IOCTL DCMDs needs to have MFI frames
 */
instance->max_mfi_cmds =
-- 
2.8.3



[PATCH v3 30/39] megaraid_sas: Do not set fp_possible if TM capable for non-RW syspdIO, change fp_possible to bool

2017-02-10 Thread Shivasharan S
FIX - firmware wants non-RW SYS PD IOs to avoid FastPath for
better tracking and other functionalities if the device
is task management capable.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index a9b66ce..ba102e4 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -2566,7 +2566,8 @@ static void megasas_build_ld_nonrw_fusion(struct 
megasas_instance *instance,
  */
 static void
 megasas_build_syspd_fusion(struct megasas_instance *instance,
-   struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd, u8 fp_possible)
+   struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd,
+   bool fp_possible)
 {
u32 device_id;
struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
@@ -2687,6 +2688,8 @@ megasas_build_io_fusion(struct megasas_instance *instance,
int sge_count;
u8  cmd_type;
struct MPI2_RAID_SCSI_IO_REQUEST *io_request = cmd->io_request;
+   struct MR_PRIV_DEVICE *mr_device_priv_data;
+   mr_device_priv_data = scp->device->hostdata;
 
/* Zero out some fields so they don't get reused */
memset(io_request->LUN, 0x0, 8);
@@ -2715,12 +2718,14 @@ megasas_build_io_fusion(struct megasas_instance 
*instance,
megasas_build_ld_nonrw_fusion(instance, scp, cmd);
break;
case READ_WRITE_SYSPDIO:
+   megasas_build_syspd_fusion(instance, scp, cmd, true);
+   break;
case NON_READ_WRITE_SYSPDIO:
-   if (instance->secure_jbod_support &&
-   (cmd_type == NON_READ_WRITE_SYSPDIO))
-   megasas_build_syspd_fusion(instance, scp, cmd, 0);
+   if (instance->secure_jbod_support ||
+   mr_device_priv_data->is_tm_capable)
+   megasas_build_syspd_fusion(instance, scp, cmd, false);
else
-   megasas_build_syspd_fusion(instance, scp, cmd, 1);
+   megasas_build_syspd_fusion(instance, scp, cmd, true);
break;
default:
break;
-- 
2.8.3



[PATCH v3 35/39] megaraid_sas: Increase internal command pool

2017-02-10 Thread Shivasharan S
Fix - increase internal command pool to 8.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas.h| 2 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 508516d..42c0e1f 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1460,7 +1460,7 @@ enum FW_BOOT_CONTEXT {
  */
 #define MEGASAS_INT_CMDS   32
 #define MEGASAS_SKINNY_INT_CMDS5
-#define MEGASAS_FUSION_INTERNAL_CMDS   5
+#define MEGASAS_FUSION_INTERNAL_CMDS   8
 #define MEGASAS_FUSION_IOCTL_CMDS  3
 #define MEGASAS_MFI_IOCTL_CMDS 27
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index d8bfb87..773ce34 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1350,7 +1350,7 @@ megasas_init_adapter_fusion(struct megasas_instance 
*instance)
fusion->last_reply_idx[i] = 0;
 
/*
-* For fusion adapters, 3 commands for IOCTL and 5 commands
+* For fusion adapters, 3 commands for IOCTL and 8 commands
 * for driver's internal DCMDs.
 */
instance->max_scsi_cmds = instance->max_fw_cmds -
-- 
2.8.3



[PATCH v3 31/39] megaraid_sas: During OCR, if get_ctrl_info fails do not continue with OCR

2017-02-10 Thread Shivasharan S
Error handling: If controller reset is not able to
recover, kill HBA and quit immediately.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index ba102e4..c0a58dc 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -4285,6 +4285,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int 
reason)
__func__, __LINE__);
megaraid_sas_kill_hba(instance);
retval = FAILED;
+   goto out;
}
/* Reset load balance info */
if (fusion->load_balance_info)
-- 
2.8.3



[Bug 151661] Adaptec 3405 3805 prints "AAC: Host adapter dead -1" every 10 seconds but works fine anyway

2017-02-10 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=151661

--- Comment #19 from Arkadiusz Miskiewicz (ar...@maven.pl) ---
Fix:

http://git.kernel.org/cgit/linux/kernel/git/jejb/scsi.git/patch/?id=8af8e1c22f9994bb1849c01d66c24fe23f9bc9a0

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[PATCH v3 39/39] megaraid_sas: driver version upgrade

2017-02-10 Thread Shivasharan S
Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 8c06cbf..e7e5974 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -35,8 +35,8 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION"07.700.00.00-rc1"
-#define MEGASAS_RELDATE"November 29, 2016"
+#define MEGASAS_VERSION"07.701.16.00-rc1"
+#define MEGASAS_RELDATE"February 2, 2017"
 
 /*
  * Device IDs
-- 
2.8.3



[PATCH v3 10/39] megaraid_sas: NVME Interface detection and prop settings

2017-02-10 Thread Shivasharan S
New functionality
Adding detection logic for NVME device attached behind Ventura controller.
Driver set HostPageSize in IOC_INIT frame to inform about page size for NVME 
devices.
Firmware reports NVME page size to the driver.
PD INFO DCMD provide new interface type NVME_PD. Driver set property of NVME 
device.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas.h|  23 ++--
 drivers/scsi/megaraid/megaraid_sas_base.c   | 170 
 drivers/scsi/megaraid/megaraid_sas_fusion.c |   6 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.h |   2 +-
 4 files changed, 142 insertions(+), 59 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index d9049d5..f9efddf 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -733,7 +733,6 @@ struct megasas_pd_list {
u16 tid;
u8 driveType;
u8 driveState;
-   u8 interface;
 } __packed;
 
  /*
@@ -1530,8 +1529,8 @@ struct megasas_register_set {
u32 outbound_scratch_pad ;  /*00B0h*/
u32 outbound_scratch_pad_2; /*00B4h*/
u32 outbound_scratch_pad_3; /*00B8h*/
+   u32 outbound_scratch_pad_4; /*00BCh*/
 
-   u32 reserved_4; /*00BCh*/
 
u32 inbound_low_queue_port ;/*00C0h*/
 
@@ -1864,6 +1863,7 @@ union megasas_frame {
 struct MR_PRIV_DEVICE {
bool is_tm_capable;
bool tm_busy;
+   u8   interface_type;
 };
 struct megasas_cmd;
 
@@ -2055,17 +2055,24 @@ struct MR_DRV_SYSTEM_INFO {
 };
 
 enum MR_PD_TYPE {
-UNKNOWN_DRIVE = 0,
-PARALLEL_SCSI = 1,
-SAS_PD = 2,
-SATA_PD = 3,
-FC_PD = 4,
+   UNKNOWN_DRIVE = 0,
+   PARALLEL_SCSI = 1,
+   SAS_PD = 2,
+   SATA_PD = 3,
+   FC_PD = 4,
+   NVME_PD = 5,
 };
 
 /* JBOD Queue depth definitions */
 #define MEGASAS_SATA_QD32
 #define MEGASAS_SAS_QD 64
 #define MEGASAS_DEFAULT_PD_QD  64
+#define MEGASAS_NVME_QD32
+
+#define MR_DEFAULT_NVME_PAGE_SIZE  4096
+#define MR_DEFAULT_NVME_PAGE_SHIFT 12
+#define MR_DEFAULT_NVME_MDTS_KB128
+#define MR_NVME_PAGE_SIZE_MASK 0x00FF
 
 struct megasas_instance {
 
@@ -2209,6 +2216,7 @@ struct megasas_instance {
bool is_ventura;
bool msix_combined;
u16 max_raid_mapsize;
+   u32 nvme_page_size;
 };
 struct MR_LD_VF_MAP {
u32 size;
@@ -2428,6 +2436,7 @@ int megasas_get_ctrl_info(struct megasas_instance 
*instance);
 /* PD sequence */
 int
 megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend);
+void megasas_set_dynamic_target_properties(struct scsi_device *sdev);
 int megasas_set_crash_dump_params(struct megasas_instance *instance,
u8 crash_buf_state);
 void megasas_free_host_crash_buffer(struct megasas_instance *instance);
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 23fb78a..f383bf2 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -116,8 +116,8 @@ static int megasas_ld_list_query(struct megasas_instance 
*instance,
 static int megasas_issue_init_mfi(struct megasas_instance *instance);
 static int megasas_register_aen(struct megasas_instance *instance,
u32 seq_num, u32 class_locale_word);
-static int
-megasas_get_pd_info(struct megasas_instance *instance, u16 device_id);
+static void megasas_get_pd_info(struct megasas_instance *instance,
+   struct scsi_device *sdev);
 /*
  * PCI ID table for all supported controllers
  */
@@ -1738,16 +1738,21 @@ static struct megasas_instance 
*megasas_lookup_instance(u16 host_no)
 }
 
 /*
-* megasas_update_sdev_properties - Update sdev structure based on controller's 
FW capabilities
+* megasas_set_dynamic_target_properties -
+* Device property set by driver may not be static and it is required to be
+* updated after OCR
+*
+* set tm_capable.
+* set dma alignment (only for eedp protection enable vd).
 *
 * @sdev: OS provided scsi device
 *
 * Returns void
 */
-void megasas_update_sdev_properties(struct scsi_device *sdev)
+void megasas_set_dynamic_target_properties(struct scsi_device *sdev)
 {
-   u16 pd_index = 0;
-   u32 device_id, ld;
+   u16 pd_index = 0, ld;
+   u32 device_id;
struct megasas_instance *instance;
struct fusion_context *fusion;
struct MR_PRIV_DEVICE *mr_device_priv_data;
@@ -1772,57 +1777,102 @@ void megasas_update_sdev_properties(struct scsi_device 
*sdev)
raid = MR_LdRaidGet(ld, 

[PATCH v3 23/39] megaraid_sas: latest controller OCR capability from FW before sending shutdown DCMD

2017-02-10 Thread Shivasharan S
Fetch the latest controller OCR capability from FW before
sending MR_DCMD_CTRL_SHUTDOWN
When application sends a shutdown DCMD (MR_DCMD_CTRL_SHUTDOWN),
driver will fetch latest controller information from firmware.
This is to ensure that driver always has latest OCR capability
of controller before sending the DCMD.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_base.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 5d7aa05..cd9d223 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -6900,6 +6900,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
   MFI_FRAME_SGL64 |
   MFI_FRAME_SENSE64));
 
+   if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_SHUTDOWN) {
+   if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) {
+   megasas_return_cmd(instance, cmd);
+   return -1;
+   }
+   }
+
if (cmd->frame->dcmd.opcode == MR_DRIVER_SET_APP_CRASHDUMP_MODE) {
error = megasas_set_crash_dump_params_ioctl(cmd);
megasas_return_cmd(instance, cmd);
-- 
2.8.3



[PATCH v3 19/39] megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access

2017-02-10 Thread Shivasharan S
Change MR_TargetIdToLdGet return type from u8 to u16.

ld id range check is added at two places in this patch -
@megasas_build_ldio_fusion and @megasas_build_ld_nonrw_fusion.
Previous driver code used different data type for lds TargetId returned from 
MR_TargetIdToLdGet.
Prior to this change, above two functions was safeguarded due to function 
always return u8
and maximum value of ld id returned was 255.

In below check, fw_supported_vd_count as of today is 64 or 256 and
valid range  to support is either 0-63 or 0-255. Ideally want to filter 
accessing
raid map for ld ids which are not valid. With the u16 change, invalid ld id 
value
is 0x and we will see kernel panic due to random memory access in 
MR_LdRaidGet.
The changes will ensure we do not call MR_LdRaidGet if ld id is beyond size of 
ldSpanMap array.

   if (ld < instance->fw_supported_vd_count)

>From firmware perspective,ld id 0xFF is invalid and even though current driver
code forward such command, firmware fails with target not available.

ld target id issue occurs mainly whenever driver loops to populate raid map 
(ea. MR_ValidateMapInfo).
These are the only two places where we may see out of range target ids and 
wants to
protect raid map access based on range provided by Firmware API.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
---

fix in v2 - updated description content.

 drivers/scsi/megaraid/megaraid_sas.h|  2 +-
 drivers/scsi/megaraid/megaraid_sas_fp.c |  5 +++--
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 25 ++---
 3 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 0a20fff..efc01a3 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2448,7 +2448,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
struct IO_REQUEST_INFO *io_info,
struct RAID_CONTEXT *pRAID_Context,
struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN);
-u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map);
+u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map);
 struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL *map);
 u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map);
 u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map);
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c 
b/drivers/scsi/megaraid/megaraid_sas_fp.c
index a0b0e68..9d5d485 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -165,7 +165,7 @@ u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map)
return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId);
 }
 
-u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map)
+u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map)
 {
return map->raidMap.ldTgtIdToLd[ldTgtId];
 }
@@ -1151,7 +1151,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
 {
struct fusion_context *fusion;
struct MR_LD_RAID  *raid;
-   u32 ld, stripSize, stripe_mask;
+   u32 stripSize, stripe_mask;
u64 endLba, endStrip, endRow, start_row, start_strip;
u64 regStart;
u32 regSize;
@@ -1163,6 +1163,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
u8  retval = 0;
u8  startlba_span = SPAN_INVALID;
u64 *pdBlock = _info->pdBlock;
+   u16 ld;
 
ldStartBlock = io_info->ldStartBlock;
numBlocks = io_info->numBlocks;
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 9019b82..4aaf307 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1121,7 +1121,8 @@ megasas_sync_map_info(struct megasas_instance *instance)
int i;
struct megasas_cmd *cmd;
struct megasas_dcmd_frame *dcmd;
-   u32 size_sync_info, num_lds;
+   u16 num_lds;
+   u32 size_sync_info;
struct fusion_context *fusion;
struct MR_LD_TARGET_SYNC *ci = NULL;
struct MR_DRV_RAID_MAP_ALL *map;
@@ -1870,7 +1871,7 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST 
*io_request, u8 cdb_len,
   struct MR_DRV_RAID_MAP_ALL *local_map_ptr, u32 ref_tag)
 {
struct MR_LD_RAID *raid;
-   u32 ld;
+   u16 ld;
u64 start_blk = io_info->pdBlock;
u8 *cdb = io_request->CDB.CDB32;
u32 num_blocks = io_info->numBlocks;
@@ -2303,10 +2304,11 @@ megasas_build_ldio_fusion(struct megasas_instance 
*instance,
 
local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
-   raid = 

[PATCH v3 17/39] megaraid_sas: reduce size of fusion_context and use vmalloc if kmalloc fails

2017-02-10 Thread Shivasharan S
Currently fusion context has fixed array load_balance_info. Use dynamic 
allocation.
In few places, driver do not want physically contigious memory.
Attempt to use vmalloc if physical contiguous memory is not available.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas.h|  2 +
 drivers/scsi/megaraid/megaraid_sas_base.c   | 15 ++
 drivers/scsi/megaraid/megaraid_sas_fp.c |  3 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 71 +++--
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  3 +-
 5 files changed, 76 insertions(+), 18 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 93da6dc..0a20fff 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2488,4 +2488,6 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int 
reason);
 int megasas_task_abort_fusion(struct scsi_cmnd *scmd);
 int megasas_reset_target_fusion(struct scsi_cmnd *scmd);
 u32 mega_mod64(u64 dividend, u32 divisor);
+int megasas_alloc_fusion_context(struct megasas_instance *instance);
+void megasas_free_fusion_context(struct megasas_instance *instance);
 #endif /*LSI_MEGARAID_SAS_H */
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index c8fa480..b2da257 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -6029,18 +6029,12 @@ static int megasas_probe_one(struct pci_dev *pdev,
case PCI_DEVICE_ID_LSI_CUTLASS_52:
case PCI_DEVICE_ID_LSI_CUTLASS_53:
{
-   instance->ctrl_context_pages =
-   get_order(sizeof(struct fusion_context));
-   instance->ctrl_context = (void *)__get_free_pages(GFP_KERNEL,
-   instance->ctrl_context_pages);
-   if (!instance->ctrl_context) {
-   dev_printk(KERN_DEBUG, >dev, "Failed to allocate "
-  "memory for Fusion context info\n");
+   if (megasas_alloc_fusion_context(instance)) {
+   megasas_free_fusion_context(instance);
goto fail_alloc_dma_buf;
}
fusion = instance->ctrl_context;
-   memset(fusion, 0,
-   ((1 << PAGE_SHIFT) << instance->ctrl_context_pages));
+
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
(instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA))
fusion->adapter_type = THUNDERBOLT_SERIES;
@@ -6683,8 +6677,7 @@ static void megasas_detach_one(struct pci_dev *pdev)
fusion->pd_seq_sync[i],
fusion->pd_seq_phys[i]);
}
-   free_pages((ulong)instance->ctrl_context,
-   instance->ctrl_context_pages);
+   megasas_free_fusion_context(instance);
} else {
megasas_release_mfi(instance);
pci_free_consistent(pdev, sizeof(u32),
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c 
b/drivers/scsi/megaraid/megaraid_sas_fp.c
index c3ef82d..d9b0f28 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -489,7 +489,8 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance)
if (instance->UnevenSpanSupport)
mr_update_span_set(drv_map, ldSpanInfo);
 
-   mr_update_load_balance_params(drv_map, lbInfo);
+   if (lbInfo)
+   mr_update_load_balance_params(drv_map, lbInfo);
 
num_lds = le16_to_cpu(drv_map->raidMap.ldCount);
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 1252a3c..9019b82 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -47,6 +47,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -2397,8 +2398,9 @@ megasas_build_ldio_fusion(struct megasas_instance 
*instance,
io_request->IoFlags |=
cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
}
-   if ((fusion->load_balance_info[device_id].loadBalanceFlag) &&
-   (io_info.isRead)) {
+   if (fusion->load_balance_info &&
+   (fusion->load_balance_info[device_id].loadBalanceFlag) 
&&
+   (io_info.isRead)) {
io_info.devHandle =
get_updated_dev_handle(instance,
>load_balance_info[device_id],
@@ -4270,9 

[PATCH v3 16/39] megaraid_sas: add print in device removal path

2017-02-10 Thread Shivasharan S
Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_base.c | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index b41bbea..c8fa480 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -7383,6 +7383,13 @@ megasas_sysfs_set_dbg_lvl(struct device_driver *dd, 
const char *buf, size_t coun
 static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl,
megasas_sysfs_set_dbg_lvl);
 
+static inline void megasas_remove_scsi_device(struct scsi_device *sdev)
+{
+   sdev_printk(KERN_INFO, sdev, "SCSI device is removed\n");
+   scsi_remove_device(sdev);
+   scsi_device_put(sdev);
+}
+
 static void
 megasas_aen_polling(struct work_struct *work)
 {
@@ -7487,10 +7494,8 @@ megasas_aen_polling(struct work_struct *work)
else
scsi_device_put(sdev1);
} else {
-   if (sdev1) {
-   scsi_remove_device(sdev1);
-   scsi_device_put(sdev1);
-   }
+   if (sdev1)
+   
megasas_remove_scsi_device(sdev1);
}
}
}
@@ -7507,10 +7512,8 @@ megasas_aen_polling(struct work_struct *work)
else
scsi_device_put(sdev1);
} else {
-   if (sdev1) {
-   scsi_remove_device(sdev1);
-   scsi_device_put(sdev1);
-   }
+   if (sdev1)
+   
megasas_remove_scsi_device(sdev1);
}
}
}
-- 
2.8.3



[PATCH v3 01/39] Revert "scsi: megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth"

2017-02-10 Thread Shivasharan S
This reverts
commit "3e5eadb1a881" ("scsi: megaraid_sas: Enable or Disable Fast path based 
on the PCI Threshold Bandwidth")

This patch was aimed to increase performance of R1 Write operation for large IO 
size.
Since this method used timer approach, it turn on/off fast path did not work as 
expected.
Patch 0013 describes new algorithm and performance number.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas.h|  8 -
 drivers/scsi/megaraid/megaraid_sas_base.c   | 48 -
 drivers/scsi/megaraid/megaraid_sas_fp.c |  7 -
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 16 --
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  2 +-
 5 files changed, 7 insertions(+), 74 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index ba9fbb7..f5c4742 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1477,8 +1477,6 @@ enum FW_BOOT_CONTEXT {
 #define MFI_1068_FW_HANDSHAKE_OFFSET   0x64
 #define MFI_1068_FW_READY  0x
 
-#define MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL HZ
-
 #define MR_MAX_REPLY_QUEUES_OFFSET  0X001F
 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET  0X003FC000
 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT14
@@ -2154,10 +2152,6 @@ struct megasas_instance {
atomic_t ldio_outstanding;
atomic_t fw_reset_no_pci_access;
 
-   atomic64_t bytes_wrote; /* used for raid1 fast path enable or disable */
-   atomic_t r1_write_fp_capable;
-
-
struct megasas_instance_template *instancet;
struct tasklet_struct isr_tasklet;
struct work_struct work_init;
@@ -2199,7 +2193,6 @@ struct megasas_instance {
long reset_flags;
struct mutex reset_mutex;
struct timer_list sriov_heartbeat_timer;
-   struct timer_list r1_fp_hold_timer;
char skip_heartbeat_timer_del;
u8 requestorId;
char PlasmaFW111;
@@ -2216,7 +2209,6 @@ struct megasas_instance {
bool is_ventura;
bool msix_combined;
u16 max_raid_mapsize;
-   u64 pci_threshold_bandwidth; /* used to control the fp writes */
 };
 struct MR_LD_VF_MAP {
u32 size;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 70891a7..3ed876a 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1940,9 +1940,6 @@ void megaraid_sas_kill_hba(struct megasas_instance 
*instance)
}
/* Complete outstanding ioctls when adapter is killed */
megasas_complete_outstanding_ioctls(instance);
-   if (instance->is_ventura)
-   del_timer_sync(>r1_fp_hold_timer);
-
 }
 
  /**
@@ -2441,24 +2438,6 @@ void megasas_sriov_heartbeat_handler(unsigned long 
instance_addr)
}
 }
 
-/*Handler for disabling/enabling raid 1 fast paths*/
-void megasas_change_r1_fp_status(unsigned long instance_addr)
-{
-   struct megasas_instance *instance =
-   (struct megasas_instance *)instance_addr;
-   if (atomic64_read(>bytes_wrote) >=
-   instance->pci_threshold_bandwidth) {
-
-   atomic64_set(>bytes_wrote, 0);
-   atomic_set(>r1_write_fp_capable, 0);
-   } else {
-   atomic64_set(>bytes_wrote, 0);
-   atomic_set(>r1_write_fp_capable, 1);
-   }
-   mod_timer(>r1_fp_hold_timer,
-jiffies + MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
-}
-
 /**
  * megasas_wait_for_outstanding -  Wait for all outstanding cmds
  * @instance:  Adapter soft state
@@ -5386,17 +5365,6 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
instance->skip_heartbeat_timer_del = 1;
}
 
-   if (instance->is_ventura) {
-   atomic64_set(>bytes_wrote, 0);
-   atomic_set(>r1_write_fp_capable, 1);
-   megasas_start_timer(instance,
-   >r1_fp_hold_timer,
-   megasas_change_r1_fp_status,
-   MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
-   dev_info(>pdev->dev, "starting the 
raid 1 fp timer with interval %d\n",
-   MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
-   }
-
return 0;
 
 fail_get_ld_pd_list:
@@ -6187,9 +6155,6 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
if (instance->requestorId && !instance->skip_heartbeat_timer_del)
del_timer_sync(>sriov_heartbeat_timer);
 
-   if (instance->is_ventura)
-   del_timer_sync(>r1_fp_hold_timer);
-
  

[PATCH v3 05/39] megaraid_sas: Refactor MEGASAS_IS_LOGICAL macro using sdev

2017-02-10 Thread Shivasharan S
Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas.h|  4 ++--
 drivers/scsi/megaraid/megaraid_sas_base.c   | 20 ++--
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 12 ++--
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index f5c4742..dff877f 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2301,8 +2301,8 @@ struct megasas_instance_template {
struct megasas_cmd *cmd);
 };
 
-#define MEGASAS_IS_LOGICAL(scp)
\
-   ((scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1)
+#define MEGASAS_IS_LOGICAL(sdev)   \
+   ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1)
 
 #define MEGASAS_DEV_INDEX(scp) \
(((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) +   \
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 3ed876a..6ca49ef 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1279,7 +1279,7 @@ megasas_build_dcdb(struct megasas_instance *instance, 
struct scsi_cmnd *scp,
u16 flags = 0;
struct megasas_pthru_frame *pthru;
 
-   is_logical = MEGASAS_IS_LOGICAL(scp);
+   is_logical = MEGASAS_IS_LOGICAL(scp->device);
device_id = MEGASAS_DEV_INDEX(scp);
pthru = (struct megasas_pthru_frame *)cmd->frame;
 
@@ -1519,11 +1519,11 @@ inline int megasas_cmd_type(struct scsi_cmnd *cmd)
case WRITE_6:
case READ_16:
case WRITE_16:
-   ret = (MEGASAS_IS_LOGICAL(cmd)) ?
+   ret = (MEGASAS_IS_LOGICAL(cmd->device)) ?
READ_WRITE_LDIO : READ_WRITE_SYSPDIO;
break;
default:
-   ret = (MEGASAS_IS_LOGICAL(cmd)) ?
+   ret = (MEGASAS_IS_LOGICAL(cmd->device)) ?
NON_READ_WRITE_LDIO : NON_READ_WRITE_SYSPDIO;
}
return ret;
@@ -1699,15 +1699,16 @@ megasas_queue_command(struct Scsi_Host *shost, struct 
scsi_cmnd *scmd)
 
scmd->result = 0;
 
-   if (MEGASAS_IS_LOGICAL(scmd) &&
+   if (MEGASAS_IS_LOGICAL(scmd->device) &&
(scmd->device->id >= instance->fw_supported_vd_count ||
scmd->device->lun)) {
scmd->result = DID_BAD_TARGET << 16;
goto out_done;
}
 
-   if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) && MEGASAS_IS_LOGICAL(scmd) &&
-   (!instance->fw_sync_cache_support)) {
+   if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) &&
+   MEGASAS_IS_LOGICAL(scmd->device) &&
+   (!instance->fw_sync_cache_support)) {
scmd->result = DID_OK << 16;
goto out_done;
}
@@ -1758,7 +1759,7 @@ void megasas_update_sdev_properties(struct scsi_device 
*sdev)
if (!fusion)
return;
 
-   if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
+   if (!MEGASAS_IS_LOGICAL(sdev) &&
instance->use_seqnum_jbod_fp) {
pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
sdev->id;
@@ -1826,8 +1827,7 @@ static int megasas_slave_configure(struct scsi_device 
*sdev)
 
instance = megasas_lookup_instance(sdev->host->host_no);
if (instance->pd_list_not_supported) {
-   if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
-   sdev->type == TYPE_DISK) {
+   if (!MEGASAS_IS_LOGICAL(sdev) && sdev->type == TYPE_DISK) {
pd_index = (sdev->channel * 
MEGASAS_MAX_DEV_PER_CHANNEL) +
sdev->id;
if (instance->pd_list[pd_index].driveState !=
@@ -1854,7 +1854,7 @@ static int megasas_slave_alloc(struct scsi_device *sdev)
struct MR_PRIV_DEVICE *mr_device_priv_data;
 
instance = megasas_lookup_instance(sdev->host->host_no);
-   if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) {
+   if (!MEGASAS_IS_LOGICAL(sdev)) {
/*
 * Open the OS scan to the SYSTEM PD
 */
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 24b72c5..675afc9 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -3581,13 +3581,13 @@ static u16 megasas_get_tm_devhandle(struct scsi_device 
*sdev)
instance = (struct megasas_instance *)sdev->host->hostdata;
fusion = instance->ctrl_context;
 
-   if (sdev->channel < 

[PATCH v3 02/39] megaraid_sas: cpu select rework.

2017-02-10 Thread Shivasharan S
No functional change. Code refactor.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 175 
 1 file changed, 100 insertions(+), 75 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 54728b3..514c306 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1819,6 +1819,73 @@ static void megasas_stream_detect(struct 
megasas_instance *instance,
 }
 
 /**
+ * megasas_set_raidflag_cpu_affinity - This function sets the cpu
+ * affinity (cpu of the controller) and raid_flags in the raid context
+ * based on IO type.
+ *
+ * @praid_context: IO RAID context
+ * @raid:  LD raid map
+ * @fp_possible:   Is fast path possible?
+ * @is_read:   Is read IO?
+ *
+ */
+static void
+megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context,
+ struct MR_LD_RAID *raid, bool fp_possible,
+ u8 is_read)
+{
+   u8 cpu_sel = MR_RAID_CTX_CPUSEL_0;
+   struct RAID_CONTEXT_G35 *rctx_g35;
+
+   rctx_g35 = _context->raid_context_g35;
+   if (fp_possible) {
+   if (is_read) {
+   if ((raid->cpuAffinity.pdRead.cpu0) &&
+   (raid->cpuAffinity.pdRead.cpu1))
+   cpu_sel = MR_RAID_CTX_CPUSEL_FCFS;
+   else if (raid->cpuAffinity.pdRead.cpu1)
+   cpu_sel = MR_RAID_CTX_CPUSEL_1;
+   } else {
+   if ((raid->cpuAffinity.pdWrite.cpu0) &&
+   (raid->cpuAffinity.pdWrite.cpu1))
+   cpu_sel = MR_RAID_CTX_CPUSEL_FCFS;
+   else if (raid->cpuAffinity.pdWrite.cpu1)
+   cpu_sel = MR_RAID_CTX_CPUSEL_1;
+   /* Fast path cache by pass capable R0/R1 VD */
+   if ((raid->level <= 1) &&
+   (raid->capability.fp_cache_bypass_capable)) {
+   rctx_g35->routing_flags.bits.sld = 1;
+   rctx_g35->raid_flags =
+   (MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS
+   << 
MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT);
+   }
+   }
+   } else {
+   if (is_read) {
+   if ((raid->cpuAffinity.ldRead.cpu0) &&
+   (raid->cpuAffinity.ldRead.cpu1))
+   cpu_sel = MR_RAID_CTX_CPUSEL_FCFS;
+   else if (raid->cpuAffinity.ldRead.cpu1)
+   cpu_sel = MR_RAID_CTX_CPUSEL_1;
+   } else {
+   if ((raid->cpuAffinity.ldWrite.cpu0) &&
+   (raid->cpuAffinity.ldWrite.cpu1))
+   cpu_sel = MR_RAID_CTX_CPUSEL_FCFS;
+   else if (raid->cpuAffinity.ldWrite.cpu1)
+   cpu_sel = MR_RAID_CTX_CPUSEL_1;
+
+   if (rctx_g35->stream_detected &&
+   (raid->level == 5) &&
+   (raid->writeMode == MR_RL_WRITE_THROUGH_MODE) &&
+   (cpu_sel == MR_RAID_CTX_CPUSEL_FCFS))
+   cpu_sel = MR_RAID_CTX_CPUSEL_0;
+   }
+   }
+
+   rctx_g35->routing_flags.bits.cpu_sel = cpu_sel;
+}
+
+/**
  * megasas_build_ldio_fusion - Prepares IOs to devices
  * @instance:  Adapter soft state
  * @scp:   SCSI command
@@ -1832,8 +1899,10 @@ megasas_build_ldio_fusion(struct megasas_instance 
*instance,
  struct scsi_cmnd *scp,
  struct megasas_cmd_fusion *cmd)
 {
-   u8 fp_possible;
-   u32 start_lba_lo, start_lba_hi, device_id, datalength = 0, ld;
+   bool fp_possible;
+   u16 ld;
+   u32 start_lba_lo, start_lba_hi, device_id, datalength = 0;
+   u32 scsi_buff_len;
struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
struct IO_REQUEST_INFO io_info;
@@ -1842,7 +1911,8 @@ megasas_build_ldio_fusion(struct megasas_instance 
*instance,
u8 *raidLUN;
unsigned long spinlock_flags;
union RAID_CONTEXT_UNION *praid_context;
-   struct MR_LD_RAID *raid;
+   struct MR_LD_RAID *raid = NULL;
+   struct MR_PRIV_DEVICE *mrdev_priv;
 
device_id = MEGASAS_DEV_INDEX(scp);
 
@@ -1858,7 +1928,7 @@ megasas_build_ldio_fusion(struct megasas_instance 
*instance,
 
start_lba_lo = 0;
start_lba_hi 

[PATCH v3 33/39] megaraid_sas: Bail out the driver load if ld_list_query fails

2017-02-10 Thread Shivasharan S
Error handling: Bail out the driver load if
key FW cmds (LD_LIST) are not return successful.
Clean up error handling in megasas_init_fw.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_base.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 30e390c..0e7121d 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -5352,7 +5352,7 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
(MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
if (megasas_get_pd_list(instance) < 0) {
dev_err(>pdev->dev, "failed to get PD list\n");
-   goto fail_get_pd_list;
+   goto fail_get_ld_pd_list;
}
 
memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
@@ -5388,7 +5388,7 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
 
if (megasas_ld_list_query(instance,
  MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
-   megasas_get_ld_list(instance);
+   goto fail_get_ld_pd_list;
 
/*
 * Compute the max allowed sectors per IO: The controller info has two
@@ -5507,8 +5507,6 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
 
 fail_get_ld_pd_list:
instance->instancet->disable_intr(instance);
-fail_get_pd_list:
-   instance->instancet->disable_intr(instance);
 fail_init_adapter:
megasas_destroy_irqs(instance);
 fail_setup_irqs:
@@ -5520,9 +5518,11 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
instance->ctrl_info = NULL;
iounmap(instance->reg_set);
 
-  fail_ioremap:
+fail_ioremap:
pci_release_selected_regions(instance->pdev, 1pdev->dev, "Failed from %s %d\n",
+   __func__, __LINE__);
return -EINVAL;
 }
 
-- 
2.8.3



[PATCH v3 22/39] megaraid_sas: avoid unaligned access in ioctl path

2017-02-10 Thread Shivasharan S
Fix kernel warning for accessing unaligned memory access in driver.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_base.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index b2da257..5d7aa05 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -43,6 +43,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -7007,7 +7008,8 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
ioc->sense_off);
 
-   if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
+   if (copy_to_user((void __user *)((unsigned long)
+get_unaligned((unsigned long *)sense_ptr)),
 sense, ioc->sense_len)) {
dev_err(>pdev->dev, "Failed to copy out to 
user "
"sense data\n");
-- 
2.8.3



[PATCH v3 09/39] megaraid_sas: change issue_dcmd to return void from int

2017-02-10 Thread Shivasharan S
With the changes to remove checks for a valid request descriptor,
issue_dcmd will now always return DCMD_SUCCESS. This patch changes
return type of issue_dcmd to void and change all callers
appropriately.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---

Fix in v2 : 
1. split patches into two as discussed below 
http://marc.info/?l=linux-scsi=148638999110404=2
2. issue_dcmd return type changed from int to void.

 drivers/scsi/megaraid/megaraid_sas.h|  2 +-
 drivers/scsi/megaraid/megaraid_sas_base.c   | 19 +++
 drivers/scsi/megaraid/megaraid_sas_fusion.c |  8 
 3 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index dff877f..d9049d5 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2297,7 +2297,7 @@ struct megasas_instance_template {
u32 (*init_adapter)(struct megasas_instance *);
u32 (*build_and_issue_cmd) (struct megasas_instance *,
struct scsi_cmnd *);
-   int (*issue_dcmd)(struct megasas_instance *instance,
+   void (*issue_dcmd)(struct megasas_instance *instance,
struct megasas_cmd *cmd);
 };
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 80fcdf5..23fb78a 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -202,12 +202,12 @@ void megasas_fusion_ocr_wq(struct work_struct *work);
 static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
 int initial);
 
-int
+void
 megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
 {
instance->instancet->fire_cmd(instance,
cmd->frame_phys_addr, 0, instance->reg_set);
-   return 0;
+   return;
 }
 
 /**
@@ -995,13 +995,14 @@ megasas_issue_polled(struct megasas_instance *instance, 
struct megasas_cmd *cmd)
frame_hdr->cmd_status = MFI_STAT_INVALID_STATUS;
frame_hdr->flags |= cpu_to_le16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE);
 
-   if ((atomic_read(>adprecovery) == MEGASAS_HW_CRITICAL_ERROR) 
||
-   (instance->instancet->issue_dcmd(instance, cmd))) {
+   if (atomic_read(>adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
dev_err(>pdev->dev, "Failed from %s %d\n",
__func__, __LINE__);
return DCMD_NOT_FIRED;
}
 
+   instance->instancet->issue_dcmd(instance, cmd);
+
return wait_and_poll(instance, cmd, instance->requestorId ?
MEGASAS_ROUTINE_WAIT_TIME_VF : MFI_IO_TIMEOUT_SECS);
 }
@@ -1023,13 +1024,14 @@ megasas_issue_blocked_cmd(struct megasas_instance 
*instance,
int ret = 0;
cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
 
-   if ((atomic_read(>adprecovery) == MEGASAS_HW_CRITICAL_ERROR) 
||
-   (instance->instancet->issue_dcmd(instance, cmd))) {
+   if (atomic_read(>adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
dev_err(>pdev->dev, "Failed from %s %d\n",
__func__, __LINE__);
return DCMD_NOT_FIRED;
}
 
+   instance->instancet->issue_dcmd(instance, cmd);
+
if (timeout) {
ret = wait_event_timeout(instance->int_cmd_wait_q,
cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, 
timeout * HZ);
@@ -1087,13 +1089,14 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance 
*instance,
cmd->sync_cmd = 1;
cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
 
-   if ((atomic_read(>adprecovery) == MEGASAS_HW_CRITICAL_ERROR) 
||
-   (instance->instancet->issue_dcmd(instance, cmd))) {
+   if (atomic_read(>adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
dev_err(>pdev->dev, "Failed from %s %d\n",
__func__, __LINE__);
return DCMD_NOT_FIRED;
}
 
+   instance->instancet->issue_dcmd(instance, cmd);
+
if (timeout) {
ret = wait_event_timeout(instance->abort_cmd_wait_q,
cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, 
timeout * HZ);
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index b6c5dc5..c38fde0 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1115,7 +1115,7 @@ megasas_get_map_info(struct megasas_instance *instance)
 int
 megasas_sync_map_info(struct megasas_instance *instance)
 {
-   int ret = 0, i;
+   int i;
struct megasas_cmd *cmd;
struct megasas_dcmd_frame *dcmd;
   

[PATCH v3 04/39] megaraid_sas: 32 bit descriptor fire cmd optimization

2017-02-10 Thread Shivasharan S
No functional change. Code refactor.
megasas_fire_cmd_fusion can always use 32 bit descriptor write for ventura. No 
need to pass extra flag.
Only IOC INIT required 64 bit Descriptor write.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Tomas Henzl 
Reviewed-by: Hannes Reinecke 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 65 +++--
 1 file changed, 33 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 7516589..24b72c5 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -188,40 +188,35 @@ inline void megasas_return_cmd_fusion(struct 
megasas_instance *instance,
 
 /**
  * megasas_fire_cmd_fusion -   Sends command to the FW
+ * @instance:  Adapter soft state
+ * @req_desc:  32bit or 64bit Request descriptor
+ *
+ * Perform PCI Write. Ventura supports 32 bit Descriptor.
+ * Prior to Ventura (12G) MR controller supports 64 bit Descriptor.
  */
+
 static void
 megasas_fire_cmd_fusion(struct megasas_instance *instance,
-   union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc, bool is_32bit)
+   union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc)
 {
-   struct megasas_register_set __iomem *regs = instance->reg_set;
-   unsigned long flags;
-
-   if (is_32bit)
+   if (instance->is_ventura)
writel(le32_to_cpu(req_desc->u.low),
-   &(regs)->inbound_single_queue_port);
-   else if (instance->is_ventura) {
+   >reg_set->inbound_single_queue_port);
+   else {
+#if defined(writeq) && defined(CONFIG_64BIT)
+   u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) |
+   le32_to_cpu(req_desc->u.low));
+
+   writeq(req_data, >reg_set->inbound_low_queue_port);
+#else
+   unsigned long flags;
spin_lock_irqsave(>hba_lock, flags);
writel(le32_to_cpu(req_desc->u.low),
-   &(regs)->inbound_low_queue_port);
+   >reg_set->inbound_low_queue_port);
writel(le32_to_cpu(req_desc->u.high),
-   &(regs)->inbound_high_queue_port);
+   >reg_set->inbound_high_queue_port);
mmiowb();
spin_unlock_irqrestore(>hba_lock, flags);
-   } else {
-#if defined(writeq) && defined(CONFIG_64BIT)
-   u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) |
-   le32_to_cpu(req_desc->u.low));
-
-   writeq(req_data, >reg_set->inbound_low_queue_port);
-#else
-
-   spin_lock_irqsave(>hba_lock, flags);
-   writel(le32_to_cpu(req_desc->u.low),
-   >reg_set->inbound_low_queue_port);
-   writel(le32_to_cpu(req_desc->u.high),
-   >reg_set->inbound_high_queue_port);
-   mmiowb();
-   spin_unlock_irqrestore(>hba_lock, flags);
 #endif
}
 }
@@ -771,6 +766,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
const char *sys_info;
MFI_CAPABILITIES *drv_ops;
u32 scratch_pad_2;
+   unsigned long flags;
 
fusion = instance->ctrl_context;
 
@@ -897,7 +893,14 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
break;
}
 
-   megasas_fire_cmd_fusion(instance, _desc, false);
+   /* For Ventura also IOC INIT required 64 bit Descriptor write. */
+   spin_lock_irqsave(>hba_lock, flags);
+   writel(le32_to_cpu(req_desc.u.low),
+  >reg_set->inbound_low_queue_port);
+   writel(le32_to_cpu(req_desc.u.high),
+  >reg_set->inbound_high_queue_port);
+   mmiowb();
+   spin_unlock_irqrestore(>hba_lock, flags);
 
wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS);
 
@@ -2577,11 +2580,10 @@ megasas_build_and_issue_cmd_fusion(struct 
megasas_instance *instance,
 * Issue the command to the FW
 */
 
-   megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura);
+   megasas_fire_cmd_fusion(instance, req_desc);
 
if (r1_cmd)
-   megasas_fire_cmd_fusion(instance, r1_cmd->request_desc,
-   instance->is_ventura);
+   megasas_fire_cmd_fusion(instance, r1_cmd->request_desc);
 
 
return 0;
@@ -3001,7 +3003,7 @@ megasas_issue_dcmd_fusion(struct megasas_instance 
*instance,
return DCMD_NOT_FIRED;
}
 
-   megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura);
+   megasas_fire_cmd_fusion(instance, req_desc);
return DCMD_SUCCESS;
 }
 
@@ -3294,8 +3296,7 @@ void megasas_refire_mgmt_cmd(struct megasas_instance 
*instance)

[PATCH v3 14/39] megaraid_sas: set residual bytes count during IO completion

2017-02-10 Thread Shivasharan S
Fixing issue of not setting residual bytes correctly.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index edbecc5..4628671 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1445,6 +1445,7 @@ map_cmd_status(struct fusion_context *fusion,
struct scsi_cmnd *scmd, u8 status, u8 ext_status,
u32 data_length, u8 *sense)
 {
+   int resid;
 
switch (status) {
 
@@ -1467,6 +1468,15 @@ map_cmd_status(struct fusion_context *fusion,
   SCSI_SENSE_BUFFERSIZE);
scmd->result |= DRIVER_SENSE << 24;
}
+
+   /*
+* If the  IO request is partially completed, then MR FW will
+* update "io_request->DataLength" field with actual number of
+* bytes transferred.Driver will set residual bytes count in
+* SCSI command structure.
+*/
+   resid = (scsi_bufflen(scmd) - data_length);
+   scsi_set_resid(scmd, resid);
break;
 
case MFI_STAT_LD_OFFLINE:
-- 
2.8.3



[PATCH v3 07/39] megaraid_sas: Use DID_REQUEUE

2017-02-10 Thread Shivasharan S
Moving to use DID_REQUEUE return type for reliable unconditional retries.
Driver wants unconditional re-queue, so replace DID_RESET with DID_REQUEUE
Discussed below -
https://www.spinics.net/lists/linux-scsi/msg102848.html

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_base.c   | 4 ++--
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 67a205a..80fcdf5 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1668,7 +1668,7 @@ megasas_queue_command(struct Scsi_Host *shost, struct 
scsi_cmnd *scmd)
/* Check for an mpio path and adjust behavior */
if (atomic_read(>adprecovery) == MEGASAS_ADPRESET_SM_INFAULT) 
{
if (megasas_check_mpio_paths(instance, scmd) ==
-   (DID_RESET << 16)) {
+   (DID_REQUEUE << 16)) {
return SCSI_MLQUEUE_HOST_BUSY;
} else {
scmd->result = DID_NO_CONNECT << 16;
@@ -2492,7 +2492,7 @@ static int megasas_wait_for_outstanding(struct 
megasas_instance *instance)
struct megasas_cmd, list);
list_del_init(_cmd->list);
if (reset_cmd->scmd) {
-   reset_cmd->scmd->result = DID_RESET << 16;
+   reset_cmd->scmd->result = DID_REQUEUE << 16;
dev_notice(>pdev->dev, "%d:%p reset 
[%02x]\n",
reset_index, reset_cmd,
reset_cmd->scmd->cmnd[0]);
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 675afc9..6ec7a18 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -3770,7 +3770,7 @@ int megasas_check_mpio_paths(struct megasas_instance 
*instance,
struct scsi_cmnd *scmd)
 {
struct megasas_instance *peer_instance = NULL;
-   int retval = (DID_RESET << 16);
+   int retval = (DID_REQUEUE << 16);
 
if (instance->peerIsPresent) {
peer_instance = megasas_get_peer_instance(instance);
-- 
2.8.3



[PATCH v3 26/39] megaraid_sas: update can_queue only if the new value is less

2017-02-10 Thread Shivasharan S
Minor Optimization: No need to update HBA can_queue value
if the current max FW commands is equal to earlier value.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 2d6d979..94b7a68 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -259,7 +259,7 @@ megasas_fusion_update_can_queue(struct megasas_instance 
*instance, int fw_boot_c
 
if (fw_boot_context == OCR_CONTEXT) {
cur_max_fw_cmds = cur_max_fw_cmds - 1;
-   if (cur_max_fw_cmds <= instance->max_fw_cmds) {
+   if (cur_max_fw_cmds < instance->max_fw_cmds) {
instance->cur_can_queue =
cur_max_fw_cmds - (MEGASAS_FUSION_INTERNAL_CMDS 
+
MEGASAS_FUSION_IOCTL_CMDS);
-- 
2.8.3



[PATCH v3 29/39] megaraid_sas: Remove unused pd_index from megasas_build_ld_nonrw_fusion

2017-02-10 Thread Shivasharan S
Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 74cefae..a9b66ce 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -2480,7 +2480,7 @@ static void megasas_build_ld_nonrw_fusion(struct 
megasas_instance *instance,
 {
u32 device_id;
struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
-   u16 pd_index = 0, ld;
+   u16 ld;
struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
struct fusion_context *fusion = instance->ctrl_context;
u8  span, physArm;
@@ -2492,7 +2492,6 @@ static void megasas_build_ld_nonrw_fusion(struct 
megasas_instance *instance,
 
io_request = cmd->io_request;
device_id = MEGASAS_DEV_INDEX(scmd);
-   pd_index = MEGASAS_PD_INDEX(scmd);
local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
/* get RAID_Context pointer */
-- 
2.8.3



[PATCH v3 06/39] megaraid_sas: RAID map is accessed for SYS PDs when use_seqnum_jbod_fp is not set

2017-02-10 Thread Shivasharan S
Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas_base.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 6ca49ef..67a205a 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1756,28 +1756,31 @@ void megasas_update_sdev_properties(struct scsi_device 
*sdev)
fusion = instance->ctrl_context;
mr_device_priv_data = sdev->hostdata;
 
-   if (!fusion)
+   if (!fusion || !mr_device_priv_data)
return;
 
-   if (!MEGASAS_IS_LOGICAL(sdev) &&
-   instance->use_seqnum_jbod_fp) {
-   pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
-   sdev->id;
-   pd_sync = (void *)fusion->pd_seq_sync
-   [(instance->pd_seq_map_id - 1) & 1];
-   mr_device_priv_data->is_tm_capable =
-   pd_sync->seq[pd_index].capability.tmCapable;
-   } else {
+   if (MEGASAS_IS_LOGICAL(sdev)) {
device_id = ((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL)
+ sdev->id;
local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
+   if (ld >= instance->fw_supported_vd_count)
+   return;
raid = MR_LdRaidGet(ld, local_map_ptr);
 
if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER)
-   blk_queue_update_dma_alignment(sdev->request_queue, 0x7);
+   blk_queue_update_dma_alignment(sdev->request_queue,
+  0x7);
+
mr_device_priv_data->is_tm_capable =
raid->capability.tmCapable;
+   } else if (instance->use_seqnum_jbod_fp) {
+   pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
+   sdev->id;
+   pd_sync = (void *)fusion->pd_seq_sync
+   [(instance->pd_seq_map_id - 1) & 1];
+   mr_device_priv_data->is_tm_capable =
+   pd_sync->seq[pd_index].capability.tmCapable;
}
 }
 
-- 
2.8.3



[PATCH v3 28/39] megaraid_sas: megasas_return_cmd does not memset IO frame to zero

2017-02-10 Thread Shivasharan S
Memset the IO frame to zero after release.

Signed-off-by: Kashyap Desai 
Signed-off-by: Shivasharan S 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas.h  |  1 +
 drivers/scsi/megaraid/megaraid_sas_base.c | 10 ++
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index efc01a3..508516d 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2238,6 +2238,7 @@ struct megasas_instance {
u8 is_rdpq;
bool dev_handle;
bool fw_sync_cache_support;
+   u32 mfi_frame_size;
bool is_ventura;
bool msix_combined;
u16 max_raid_mapsize;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 06001b4..30e390c 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -268,6 +268,8 @@ megasas_return_cmd(struct megasas_instance *instance, 
struct megasas_cmd *cmd)
cmd->scmd = NULL;
cmd->frame_count = 0;
cmd->flags = 0;
+   memset(cmd->frame, 0, instance->mfi_frame_size);
+   cmd->frame->io.context = cpu_to_le32(cmd->index);
if (!fusion && reset_devices)
cmd->frame->hdr.cmd = MFI_CMD_INVALID;
list_add(>list, (>cmd_pool)->next);
@@ -3889,7 +3891,6 @@ static int megasas_create_frame_pool(struct 
megasas_instance *instance)
int i;
u16 max_cmd;
u32 sge_sz;
-   u32 total_sz;
u32 frame_count;
struct megasas_cmd *cmd;
 
@@ -3917,12 +3918,13 @@ static int megasas_create_frame_pool(struct 
megasas_instance *instance)
 * Total 192 byte (3 MFI frame of 64 byte)
 */
frame_count = instance->ctrl_context ? (3 + 1) : (15 + 1);
-   total_sz = MEGAMFI_FRAME_SIZE * frame_count;
+   instance->mfi_frame_size = MEGAMFI_FRAME_SIZE * frame_count;
/*
 * Use DMA pool facility provided by PCI layer
 */
instance->frame_dma_pool = pci_pool_create("megasas frame pool",
-   instance->pdev, total_sz, 256, 0);
+   instance->pdev, 
instance->mfi_frame_size,
+   256, 0);
 
if (!instance->frame_dma_pool) {
dev_printk(KERN_DEBUG, >pdev->dev, "failed to setup 
frame pool\n");
@@ -3966,7 +3968,7 @@ static int megasas_create_frame_pool(struct 
megasas_instance *instance)
return -ENOMEM;
}
 
-   memset(cmd->frame, 0, total_sz);
+   memset(cmd->frame, 0, instance->mfi_frame_size);
cmd->frame->io.context = cpu_to_le32(cmd->index);
cmd->frame->io.pad_0 = 0;
if (!instance->ctrl_context && reset_devices)
-- 
2.8.3



[PATCH v3 12/39] megaraid_sas: NVME fast path io support

2017-02-10 Thread Shivasharan S
This patch provide true fast path IO support.
Driver creates PRP for NVME drives and send Fast Path for performance.
Certain h/w requirement needs to be taken care in driver.

Signed-off-by: Shivasharan S 
Signed-off-by: Kashyap Desai 
Reviewed-by: Hannes Reinecke 
Reviewed-by: Tomas Henzl 
---
 drivers/scsi/megaraid/megaraid_sas.h|  10 +-
 drivers/scsi/megaraid/megaraid_sas_fp.c |  55 +++--
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 316 ++--
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  14 +-
 4 files changed, 350 insertions(+), 45 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index a45ff10..075e2e9 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2172,6 +2172,11 @@ struct megasas_instance {
atomic_t fw_outstanding;
atomic_t ldio_outstanding;
atomic_t fw_reset_no_pci_access;
+   atomic_t ieee_sgl;
+   atomic_t prp_sgl;
+   atomic_t sge_holes_type1;
+   atomic_t sge_holes_type2;
+   atomic_t sge_holes_type3;
 
struct megasas_instance_template *instancet;
struct tasklet_struct isr_tasklet;
@@ -2443,7 +2448,9 @@ __le16 MR_PdDevHandleGet(u32 pd, struct 
MR_DRV_RAID_MAP_ALL *map);
 u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map);
 
 __le16 get_updated_dev_handle(struct megasas_instance *instance,
-   struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *in_info);
+ struct LD_LOAD_BALANCE_INFO *lbInfo,
+ struct IO_REQUEST_INFO *in_info,
+ struct MR_DRV_RAID_MAP_ALL *drv_map);
 void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map,
struct LD_LOAD_BALANCE_INFO *lbInfo);
 int megasas_get_ctrl_info(struct megasas_instance *instance);
@@ -2472,4 +2479,5 @@ void megasas_update_sdev_properties(struct scsi_device 
*sdev);
 int megasas_reset_fusion(struct Scsi_Host *shost, int reason);
 int megasas_task_abort_fusion(struct scsi_cmnd *scmd);
 int megasas_reset_target_fusion(struct scsi_cmnd *scmd);
+u32 mega_mod64(u64 dividend, u32 divisor);
 #endif /*LSI_MEGARAID_SAS_H */
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c 
b/drivers/scsi/megaraid/megaraid_sas_fp.c
index 24258af..c3ef82d 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -155,6 +155,11 @@ __le16 MR_PdDevHandleGet(u32 pd, struct 
MR_DRV_RAID_MAP_ALL *map)
return map->raidMap.devHndlInfo[pd].curDevHdl;
 }
 
+static u8 MR_PdInterfaceTypeGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map)
+{
+   return map->raidMap.devHndlInfo[pd].interfaceType;
+}
+
 u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map)
 {
return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId);
@@ -929,6 +934,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance 
*instance, u32 ld,
u8  retval = TRUE;
u64 *pdBlock = _info->pdBlock;
__le16  *pDevHandle = _info->devHandle;
+   u8  *pPdInterface = _info->pd_interface;
u32 logArm, rowMod, armQ, arm;
struct fusion_context *fusion;
 
@@ -960,15 +966,18 @@ static u8 mr_spanset_get_phy_params(struct 
megasas_instance *instance, u32 ld,
 
if (pd != MR_PD_INVALID) {
*pDevHandle = MR_PdDevHandleGet(pd, map);
+   *pPdInterface = MR_PdInterfaceTypeGet(pd, map);
/* get second pd also for raid 1/10 fast path writes*/
-   if (raid->level == 1) {
+   if (instance->is_ventura &&
+   (raid->level == 1) &&
+   !io_info->isRead) {
r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map);
if (r1_alt_pd != MR_PD_INVALID)
io_info->r1_alt_dev_handle =
MR_PdDevHandleGet(r1_alt_pd, map);
}
} else {
-   *pDevHandle = cpu_to_le16(MR_PD_INVALID);
+   *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID);
if ((raid->level >= 5) &&
((fusion->adapter_type == THUNDERBOLT_SERIES)  ||
((fusion->adapter_type == INVADER_SERIES) &&
@@ -977,8 +986,10 @@ static u8 mr_spanset_get_phy_params(struct 
megasas_instance *instance, u32 ld,
else if (raid->level == 1) {
physArm = physArm + 1;
pd = MR_ArPdGet(arRef, physArm, map);
-   if (pd != MR_PD_INVALID)
+   if (pd != MR_PD_INVALID) {
*pDevHandle = MR_PdDevHandleGet(pd, map);
+   *pPdInterface = MR_PdInterfaceTypeGet(pd, map);
+   }