Re: [PATCH 25/27] block: remove the discard_zeroes_data flag

2017-05-10 Thread Nicholas A. Bellinger
On Wed, 2017-05-10 at 16:06 +0200, h...@lst.de wrote:
> On Mon, May 08, 2017 at 11:46:14PM -0700, Nicholas A. Bellinger wrote:
> > That said, simply propagating up q->limits.max_write_zeroes_sectors as
> > dev_attrib->unmap_zeroes_data following existing code still looks like
> > the right thing to do.
> 
> It is not.  Martin has decoupled write same/zeroes support from discard
> support.  Any device will claim to support it initially, and we'll
> only clear the flag if a Write Same command fails.
> 
> So even if LBPRZ is not set you can trivially get into a situation
> where discard is supported through UNMAP, and you'll incorrectly
> set LBPRZ and will cause data corruption.

In that case, there are two choices.

1) Expose a block_device or request_queue bit to signal 'real LBPRZ'
support up to IBLOCK, in order to maintain SCSI target feature
compatibility.

2) Or drop the LBPRZ bit usage for IBLOCK all-together.

Since I happen happen to support a block driver that has 'real LBPRZ'
support for all discards, I'd prefer the latter so this doesn't have to
be carried out-of-tree.

So what are the options for this in post v4.12..?



[PATCH] scsi: zero per-cmd driver data for each MQ I/O

2017-05-10 Thread Long Li
From: Long Li 

Lower layer driver may not initialize private data before use. Zero them
out to prevent use of stale data.

Signed-off-by: Long Li 
---
 drivers/scsi/scsi_lib.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 19125d7..a821593 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1850,7 +1850,7 @@ static int scsi_mq_prep_fn(struct request *req)
 
/* zero out the cmd, except for the embedded scsi_request */
memset((char *)cmd + sizeof(cmd->req), 0,
-   sizeof(*cmd) - sizeof(cmd->req));
+   sizeof(*cmd) - sizeof(cmd->req) + shost->hostt->cmd_size);
 
req->special = cmd;
 
-- 
2.7.4



Re: [PATCH v2] scsi: sg: don't return bogus Sg_requests

2017-05-10 Thread Douglas Gilbert

On 2017-05-10 03:53 AM, Johannes Thumshirn wrote:

If the list search in sg_get_rq_mark() fails to find a valid request, we
return a bogus element. This then can later lead to a GPF in sg_remove_scat().

So don't return bogus Sg_requests in sg_get_rq_mark() but NULL in case the
list search doesn't find a valid request.

Signed-off-by: Johannes Thumshirn 
Reported-by: Andrey Konovalov 
Cc: Hannes Reinecke 
Cc: Christoph Hellwig 
Cc: Doug Gilbert 
---
Changes to v1:
* Directly return found element within the loop (Hannes)

 drivers/scsi/sg.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 0a38ba01b7b4..82c33a6edbea 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -2074,11 +2074,12 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
if ((1 == resp->done) && (!resp->sg_io_owned) &&
((-1 == pack_id) || (resp->header.pack_id == pack_id))) {
resp->done = 2;  /* guard against other readers */
-   break;
+   write_unlock_irqrestore(>rq_list_lock, iflags);
+   return resp;
}
}
write_unlock_irqrestore(>rq_list_lock, iflags);
-   return resp;
+   return NULL;
 }

 /* always adds to end of list */



Acked-by: Douglas Gilbert 


[PATCH v2] ibmvscsis: Fix the incorrect req_lim_delta

2017-05-10 Thread Bryant G. Ly
The current code is not correctly calculating the req_lim_delta.

We want to make sure vscsi->credit is always incremented when
we do not send a response for the scsi op. Thus for the case where
there is a successfully aborted task we need to make sure the
vscsi->credit is incremented.

v2 - Moves the original location of the vscsi->credit increment
to a better spot. Since if we increment credit, the next command
we send back will have increased req_lim_delta. But we probably
shouldn't be doing that until the aborted cmd is actually released.
Otherwise the client will think that it can send a new command, and
we could find ourselves short of command elements. Not likely, but could
happen.

This patch depends on both:
commit 25e78531268e ("ibmvscsis: Do not send aborted task response")
commit 38b2788edbd6 ("ibmvscsis: Clear left-over abort_cmd pointers")

Signed-off-by: Bryant G. Ly 
Reviewed-by: Michael Cyr 
Cc:  # v4.8+
---
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 24 
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c 
b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index ee64241..abf6026 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -1791,6 +1791,25 @@ static void ibmvscsis_send_messages(struct scsi_info 
*vscsi)
list_del(>list);
ibmvscsis_free_cmd_resources(vscsi,
 cmd);
+   /*
+* With a successfully aborted op
+* through LIO we want to increment the
+* the vscsi credit so that when we dont
+* send a rsp to the original scsi abort
+* op (h_send_crq), but the tm rsp to
+* the abort is sent, the credit is
+* correctly sent with the abort tm rsp.
+* We would need 1 for the abort tm rsp
+* and 1 credit for the aborted scsi op.
+* Thus we need to increment here.
+* Also we want to increment the credit
+* here because we want to make sure
+* cmd is actually released first
+* otherwise the client will think it
+* it can send a new cmd, and we could
+* find ourselves short of cmd elements.
+*/
+   vscsi->credit += 1;
} else {
iue = cmd->iue;
 
@@ -2965,10 +2984,7 @@ static long srp_build_response(struct scsi_info *vscsi,
 
rsp->opcode = SRP_RSP;
 
-   if (vscsi->credit > 0 && vscsi->state == SRP_PROCESSING)
-   rsp->req_lim_delta = cpu_to_be32(vscsi->credit);
-   else
-   rsp->req_lim_delta = cpu_to_be32(1 + vscsi->credit);
+   rsp->req_lim_delta = cpu_to_be32(1 + vscsi->credit);
rsp->tag = cmd->rsp.tag;
rsp->flags = 0;
 
-- 
2.5.4 (Apple Git-61)



[PATCH 15/15] lpfc: update version to 11.2.0.14

2017-05-10 Thread James Smart
Change driver version to 11.2.0.14

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 1c26dc67151b..c2653244221c 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -20,7 +20,7 @@
  * included with this package. *
  ***/
 
-#define LPFC_DRIVER_VERSION "11.2.0.12"
+#define LPFC_DRIVER_VERSION "11.2.0.14"
 #define LPFC_DRIVER_NAME   "lpfc"
 
 /* Used for SLI 2/3 */
-- 
2.11.0



[PATCH 13/15] lpfc: Fix NVMEI's handling of NVMET's PRLI response attributes

2017-05-10 Thread James Smart
Code review of NVMEI's FC_PORT_ROLE_NVME_DISCOVERY
looked wrong.

Discussions with storage architecture team clarified
NVMEI's audit of the PRLI response port roles.  Following up
discussion with code review showed a few minor corrections
were required - especially in anticipation of NVME auto
discovery.

During PRLI, NVMEI should sent prli_init - which it it
does.  NVMET should send prli_tgt and prli_disc - which it does.
When NVMEI receives a PRLI Response now, it audits the
incoming target bits and stores the attributes in the
corresponding NDLP.  Later, when NVMEI registers the NVME
rport, it uses the stored ndlp attributes to set the rport
port_roles correctly.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_disc.h  | 1 +
 drivers/scsi/lpfc/lpfc_nportdisc.c | 6 ++
 2 files changed, 7 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 9d5a379f4b15..094c97b9e5f7 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -90,6 +90,7 @@ struct lpfc_nodelist {
 #define NLP_FCP_INITIATOR  0x10/* entry is an FCP 
Initiator */
 #define NLP_NVME_TARGET0x20/* entry is a NVME 
Target */
 #define NLP_NVME_INITIATOR 0x40/* entry is a NVME 
Initiator */
+#define NLP_NVME_DISCOVERY 0x80 /* entry has NVME disc srvc */
 
uint16_tnlp_fc4_type;   /* FC types node supports. */
/* Assigned from GID_FF, only
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c 
b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 8777c2d5f50d..bff3de053df4 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -1944,7 +1944,13 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, 
struct lpfc_nodelist *ndlp,
 
/* Target driver cannot solicit NVME FB. */
if (bf_get_be32(prli_tgt, nvpr)) {
+   /* Complete the nvme target roles.  The transport
+* needs to know if the rport is capable of
+* discovery in addition to its role.
+*/
ndlp->nlp_type |= NLP_NVME_TARGET;
+   if (bf_get_be32(prli_disc, nvpr))
+   ndlp->nlp_type |= NLP_NVME_DISCOVERY;
if ((bf_get_be32(prli_fba, nvpr) == 1) &&
(bf_get_be32(prli_fb_sz, nvpr) > 0) &&
(phba->cfg_nvme_enable_fb) &&
-- 
2.11.0



[PATCH 07/15] lpfc: Separate NVMET data buffer pool fir ELS/CT.

2017-05-10 Thread James Smart
Using 2048 byte buffer and onle 128 bytes is needed.

Create nee LFPC_NVMET_DATA_BUF_SIZE define to use
for NVMET RQ/MRQs.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h  |  1 +
 drivers/scsi/lpfc/lpfc_crtn.h |  1 +
 drivers/scsi/lpfc/lpfc_hw4.h  |  1 +
 drivers/scsi/lpfc/lpfc_init.c |  7 ++-
 drivers/scsi/lpfc/lpfc_mem.c  | 33 ++---
 drivers/scsi/lpfc/lpfc_sli.c  | 19 +++
 6 files changed, 50 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 62571fa9c6ad..c4b38491da8e 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -943,6 +943,7 @@ struct lpfc_hba {
struct pci_pool *lpfc_mbuf_pool;
struct pci_pool *lpfc_hrb_pool; /* header receive buffer pool */
struct pci_pool *lpfc_drb_pool; /* data receive buffer pool */
+   struct pci_pool *lpfc_nvmet_drb_pool; /* data receive buffer pool */
struct pci_pool *lpfc_hbq_pool; /* SLI3 hbq buffer pool */
struct pci_pool *txrdy_payload_pool;
struct lpfc_dma_pool lpfc_mbuf_safety_pool;
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 1c55408ac718..fb7fc48a1324 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -271,6 +271,7 @@ int lpfc_sli4_fcf_rr_next_proc(struct lpfc_vport *, 
uint16_t);
 void lpfc_sli4_clear_fcf_rr_bmask(struct lpfc_hba *);
 
 int lpfc_mem_alloc(struct lpfc_hba *, int align);
+int lpfc_nvmet_mem_alloc(struct lpfc_hba *phba);
 int lpfc_mem_alloc_active_rrq_pool_s4(struct lpfc_hba *);
 void lpfc_mem_free(struct lpfc_hba *);
 void lpfc_mem_free_all(struct lpfc_hba *);
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 1d12f2be36bc..df97c6b7433b 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1356,6 +1356,7 @@ struct lpfc_mbx_wq_destroy {
 
 #define LPFC_HDR_BUF_SIZE 128
 #define LPFC_DATA_BUF_SIZE 2048
+#define LPFC_NVMET_DATA_BUF_SIZE 128
 struct rq_context {
uint32_t word0;
 #define lpfc_rq_context_rqe_count_SHIFT16  /* Version 0 Only */
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 66e3cc40d64e..ced1fa3a3983 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -5956,16 +5956,21 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
for (i = 0; i < lpfc_enable_nvmet_cnt; i++) {
if (wwn == lpfc_enable_nvmet[i]) {
 #if (IS_ENABLED(CONFIG_NVME_TARGET_FC))
+   if (lpfc_nvmet_mem_alloc(phba))
+   break;
+
+   phba->nvmet_support = 1; /* a match */
+
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"6017 NVME Target %016llx\n",
wwn);
-   phba->nvmet_support = 1; /* a match */
 #else
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"6021 Can't enable NVME Target."
" NVME_TARGET_FC infrastructure"
" is not in kernel\n");
 #endif
+   break;
}
}
}
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index 5986c7957199..91060afc9721 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -214,6 +214,21 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align)
return -ENOMEM;
 }
 
+int
+lpfc_nvmet_mem_alloc(struct lpfc_hba *phba)
+{
+   phba->lpfc_nvmet_drb_pool =
+   pci_pool_create("lpfc_nvmet_drb_pool",
+   phba->pcidev, LPFC_NVMET_DATA_BUF_SIZE,
+   SGL_ALIGN_SZ, 0);
+   if (!phba->lpfc_nvmet_drb_pool) {
+   lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+   "6024 Can't enable NVME Target - no memory\n");
+   return -ENOMEM;
+   }
+   return 0;
+}
+
 /**
  * lpfc_mem_free - Frees memory allocated by lpfc_mem_alloc
  * @phba: HBA to free memory for
@@ -232,6 +247,9 @@ lpfc_mem_free(struct lpfc_hba *phba)
 
/* Free HBQ pools */
lpfc_sli_hbqbuf_free_all(phba);
+   if (phba->lpfc_nvmet_drb_pool)
+   pci_pool_destroy(phba->lpfc_nvmet_drb_pool);
+   phba->lpfc_nvmet_drb_pool = NULL;
if (phba->lpfc_drb_pool)
pci_pool_destroy(phba->lpfc_drb_pool);
phba->lpfc_drb_pool = NULL;
@@ -624,20 +642,20 @@ lpfc_sli4_nvmet_alloc(struct lpfc_hba *phba)
kfree(dma_buf);
return NULL;
}
-   dma_buf->dbuf.virt = 

[PATCH 09/15] lpfc: Added recovery logic for running out of NVMET IO context resources

2017-05-10 Thread James Smart
Previous logic would just drop the IO

Added logic to queue the IO to wait for an IO context resource from an IO
thats already in progress.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h |   1 +
 drivers/scsi/lpfc/lpfc_attr.c|   6 ++
 drivers/scsi/lpfc/lpfc_crtn.h|   2 +
 drivers/scsi/lpfc/lpfc_debugfs.c |   6 ++
 drivers/scsi/lpfc/lpfc_init.c|   2 +
 drivers/scsi/lpfc/lpfc_nvmet.c   | 138 +--
 drivers/scsi/lpfc/lpfc_sli.c |   7 +-
 drivers/scsi/lpfc/lpfc_sli4.h|   6 +-
 8 files changed, 144 insertions(+), 24 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 72641b1d3ab8..c47bde6205c9 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -170,6 +170,7 @@ struct rqb_dmabuf {
struct lpfc_dmabuf dbuf;
uint16_t total_size;
uint16_t bytes_recv;
+   uint16_t idx;
struct lpfc_queue *hrq;   /* ptr to associated Header RQ */
struct lpfc_queue *drq;   /* ptr to associated Data RQ */
 };
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index ebde2e06fb4b..f60ab7322d6c 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -245,6 +245,12 @@ lpfc_nvme_info_show(struct device *dev, struct 
device_attribute *attr,
atomic_read(>xmt_abort_rsp),
atomic_read(>xmt_abort_rsp_error));
 
+   len += snprintf(buf + len, PAGE_SIZE - len,
+   "IO_CTX: %08x outstanding %08x total %x",
+   phba->sli4_hba.nvmet_ctx_cnt,
+   phba->sli4_hba.nvmet_io_wait_cnt,
+   phba->sli4_hba.nvmet_io_wait_total);
+
len +=  snprintf(buf+len, PAGE_SIZE-len, "\n");
return len;
}
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index cc95abd130b4..8912767e7bc8 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -77,6 +77,8 @@ void lpfc_retry_pport_discovery(struct lpfc_hba *);
 void lpfc_release_rpi(struct lpfc_hba *, struct lpfc_vport *, uint16_t);
 int lpfc_init_iocb_list(struct lpfc_hba *phba, int cnt);
 void lpfc_free_iocb_list(struct lpfc_hba *phba);
+int lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq,
+   struct lpfc_queue *drq, int count, int idx);
 
 void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 7284533f4df2..c7d1c9d37a64 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -842,6 +842,12 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char 
*buf, int size)
}
spin_unlock(>sli4_hba.abts_nvme_buf_list_lock);
}
+
+   len += snprintf(buf + len, size - len,
+   "IO_CTX: %08x  outstanding %08x total %08x\n",
+   phba->sli4_hba.nvmet_ctx_cnt,
+   phba->sli4_hba.nvmet_io_wait_cnt,
+   phba->sli4_hba.nvmet_io_wait_total);
} else {
if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME))
return len;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 53d5ab37a46e..472117eb9257 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -5825,6 +5825,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
INIT_LIST_HEAD(>sli4_hba.lpfc_abts_nvme_buf_list);
INIT_LIST_HEAD(>sli4_hba.lpfc_abts_nvmet_ctx_list);
INIT_LIST_HEAD(>sli4_hba.lpfc_nvmet_ctx_list);
+   INIT_LIST_HEAD(>sli4_hba.lpfc_nvmet_io_wait_list);
 
/* Fast-path XRI aborted CQ Event work queue list */
INIT_LIST_HEAD(>sli4_hba.sp_nvme_xri_aborted_work_queue);
@@ -5833,6 +5834,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
/* This abort list used by worker thread */
spin_lock_init(>sli4_hba.sgl_list_lock);
spin_lock_init(>sli4_hba.nvmet_io_lock);
+   spin_lock_init(>sli4_hba.nvmet_io_wait_lock);
 
/*
 * Initialize driver internal slow-path work queues
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index fcc77ae0c71c..312f54278bd4 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -158,6 +158,12 @@ void
 lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba, struct lpfc_nvmet_ctxbuf 
*ctx_buf)
 {
struct lpfc_nvmet_rcv_ctx *ctxp = ctx_buf->context;
+   struct 

[PATCH 10/15] lpfc: Fix NVME I+T not registering NVME as a supported FC4 type

2017-05-10 Thread James Smart
When the driver send the RPA command, it does not
send supported FC4 Type NVME to the management server.

Encode NVME (type x28) in the AttribEntry in the
RPA command.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_ct.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index c7962dae4dab..f2cd19c6c2df 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -2092,6 +2092,7 @@ lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport,
 
ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */
ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */
+   ae->un.AttrTypes[6] = 0x01; /* Type 40 - NVME */
ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */
size = FOURBYTES + 32;
ad->AttrLen = cpu_to_be16(size);
-- 
2.11.0



[PATCH 08/15] lpfc: Separate NVMET RQ buffer posting from IO resources SGL/iocbq/context

2017-05-10 Thread James Smart
Currently IO resources are mapped 1 to 1 with RQ buffers posted

Added logic to separate RQE buffers from IO op resources
(sgl/iocbq/context). During initialization, the driver will determine
how many SGLs it will allocate for NVMET (based on what the
firmware reports) and associate a NVMET IOCBq and NVMET context
structure with each one.

Now that hdr/data buffers are immediately reposted back to the RQ,
512 RQEs for each MRQ is sufficient. Also, since NVMET data buffers
are now 128 bytes, lpfc_nvmet_mrq_post is not necessary anymore
as we will always post the max (512) buffers per NVMET MRQ.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h   |  11 +-
 drivers/scsi/lpfc/lpfc_attr.c  |  11 --
 drivers/scsi/lpfc/lpfc_crtn.h  |   8 +-
 drivers/scsi/lpfc/lpfc_init.c  |  92 ++-
 drivers/scsi/lpfc/lpfc_mem.c   |  73 +---
 drivers/scsi/lpfc/lpfc_nvmet.c | 246 +++--
 drivers/scsi/lpfc/lpfc_nvmet.h |   1 +
 drivers/scsi/lpfc/lpfc_sli.c   |  88 +--
 drivers/scsi/lpfc/lpfc_sli4.h  |   4 +-
 9 files changed, 295 insertions(+), 239 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index c4b38491da8e..72641b1d3ab8 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -141,6 +141,13 @@ struct lpfc_dmabuf {
uint32_t   buffer_tag;  /* used for tagged queue ring */
 };
 
+struct lpfc_nvmet_ctxbuf {
+   struct list_head list;
+   struct lpfc_nvmet_rcv_ctx *context;
+   struct lpfc_iocbq *iocbq;
+   struct lpfc_sglq *sglq;
+};
+
 struct lpfc_dma_pool {
struct lpfc_dmabuf   *elements;
uint32_tmax_count;
@@ -163,9 +170,6 @@ struct rqb_dmabuf {
struct lpfc_dmabuf dbuf;
uint16_t total_size;
uint16_t bytes_recv;
-   void *context;
-   struct lpfc_iocbq *iocbq;
-   struct lpfc_sglq *sglq;
struct lpfc_queue *hrq;   /* ptr to associated Header RQ */
struct lpfc_queue *drq;   /* ptr to associated Data RQ */
 };
@@ -777,7 +781,6 @@ struct lpfc_hba {
uint32_t cfg_nvme_oas;
uint32_t cfg_nvme_io_channel;
uint32_t cfg_nvmet_mrq;
-   uint32_t cfg_nvmet_mrq_post;
uint32_t cfg_enable_nvmet;
uint32_t cfg_nvme_enable_fb;
uint32_t cfg_nvmet_fb_size;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index ee4d9be95960..ebde2e06fb4b 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -3316,14 +3316,6 @@ LPFC_ATTR_R(nvmet_mrq,
"Specify number of RQ pairs for processing NVMET cmds");
 
 /*
- * lpfc_nvmet_mrq_post: Specify number buffers to post on every MRQ
- *
- */
-LPFC_ATTR_R(nvmet_mrq_post, LPFC_DEF_MRQ_POST,
-   LPFC_MIN_MRQ_POST, LPFC_MAX_MRQ_POST,
-   "Specify number of buffers to post on every MRQ");
-
-/*
  * lpfc_enable_fc4_type: Defines what FC4 types are supported.
  * Supported Values:  1 - register just FCP
  *3 - register both FCP and NVME
@@ -5158,7 +5150,6 @@ struct device_attribute *lpfc_hba_attrs[] = {
_attr_lpfc_suppress_rsp,
_attr_lpfc_nvme_io_channel,
_attr_lpfc_nvmet_mrq,
-   _attr_lpfc_nvmet_mrq_post,
_attr_lpfc_nvme_enable_fb,
_attr_lpfc_nvmet_fb_size,
_attr_lpfc_enable_bg,
@@ -6198,7 +6189,6 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
 
lpfc_enable_fc4_type_init(phba, lpfc_enable_fc4_type);
lpfc_nvmet_mrq_init(phba, lpfc_nvmet_mrq);
-   lpfc_nvmet_mrq_post_init(phba, lpfc_nvmet_mrq_post);
 
/* Initialize first burst. Target vs Initiator are different. */
lpfc_nvme_enable_fb_init(phba, lpfc_nvme_enable_fb);
@@ -6295,7 +6285,6 @@ lpfc_nvme_mod_param_dep(struct lpfc_hba *phba)
/* Not NVME Target mode.  Turn off Target parameters. */
phba->nvmet_support = 0;
phba->cfg_nvmet_mrq = 0;
-   phba->cfg_nvmet_mrq_post = 0;
phba->cfg_nvmet_fb_size = 0;
}
 
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index fb7fc48a1324..cc95abd130b4 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -75,6 +75,8 @@ void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *);
 void lpfc_retry_pport_discovery(struct lpfc_hba *);
 void lpfc_release_rpi(struct lpfc_hba *, struct lpfc_vport *, uint16_t);
+int lpfc_init_iocb_list(struct lpfc_hba *phba, int cnt);
+void lpfc_free_iocb_list(struct lpfc_hba *phba);
 
 void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -246,16 +248,14 @@ struct hbq_dmabuf *lpfc_sli4_rb_alloc(struct lpfc_hba *);
 void lpfc_sli4_rb_free(struct lpfc_hba *, struct hbq_dmabuf *);
 struct rqb_dmabuf 

[PATCH 14/15] lpfc: Add MDS Diagnostic support.

2017-05-10 Thread James Smart
Added code to support Cisco MDS loopback diagnostic. The diagnostics
run various loopbacks including one which loops-back frame through
the driver.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h |   2 +
 drivers/scsi/lpfc/lpfc_els.c |   7 +++
 drivers/scsi/lpfc/lpfc_hbadisc.c |   3 +-
 drivers/scsi/lpfc/lpfc_hw4.h |  15 -
 drivers/scsi/lpfc/lpfc_init.c|  13 
 drivers/scsi/lpfc/lpfc_sli.c | 131 ---
 6 files changed, 161 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index c47bde6205c9..f2c0ba6ced78 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -675,6 +675,8 @@ struct lpfc_hba {
/* INIT_LINK mailbox command */
 #define LS_NPIV_FAB_SUPPORTED 0x2  /* Fabric supports NPIV */
 #define LS_IGNORE_ERATT   0x4  /* intr handler should ignore ERATT */
+#define LS_MDS_LINK_DOWN  0x8  /* MDS Diagnostics Link Down */
+#define LS_MDS_LOOPBACK  0x16  /* MDS Diagnostics Link Up (Loopback) */
 
uint32_t hba_flag;  /* hba generic flags */
 #define HBA_ERATT_HANDLED  0x1 /* This flag is set when eratt handled */
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 3085895464d9..1d36f82fa369 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -1047,6 +1047,13 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct 
lpfc_iocbq *cmdiocb,
 irsp->ulpStatus, irsp->un.ulpWord[4],
 irsp->ulpTimeout);
 
+
+   /* If this is not a loop open failure, bail out */
+   if (!(irsp->ulpStatus == IOSTAT_LOCAL_REJECT &&
+ ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
+   IOERR_LOOP_OPEN_FAILURE)))
+   goto flogifail;
+
/* FLOGI failed, so there is no fabric */
spin_lock_irq(shost->host_lock);
vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index dcc9b3858778..3ffcd9215ca8 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -701,7 +701,8 @@ lpfc_work_done(struct lpfc_hba *phba)
/* Set the lpfc data pending flag */
set_bit(LPFC_DATA_READY, >data_flags);
} else {
-   if (phba->link_state >= LPFC_LINK_UP) {
+   if (phba->link_state >= LPFC_LINK_UP ||
+   phba->link_flag & LS_MDS_LOOPBACK) {
pring->flag &= ~LPFC_DEFERRED_RING_EVENT;
lpfc_sli_handle_slow_ring_event(phba, pring,
(status &
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index df97c6b7433b..e0a5fce416ae 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -4421,6 +4421,19 @@ struct fcp_treceive64_wqe {
 };
 #define TXRDY_PAYLOAD_LEN  12
 
+#define CMD_SEND_FRAME 0xE1
+
+struct send_frame_wqe {
+   struct ulp_bde64 bde;  /* words 0-2 */
+   uint32_t frame_len;/* word 3 */
+   uint32_t fc_hdr_wd0;   /* word 4 */
+   uint32_t fc_hdr_wd1;   /* word 5 */
+   struct wqe_common wqe_com; /* words 6-11 */
+   uint32_t fc_hdr_wd2;   /* word 12 */
+   uint32_t fc_hdr_wd3;   /* word 13 */
+   uint32_t fc_hdr_wd4;   /* word 14 */
+   uint32_t fc_hdr_wd5;   /* word 15 */
+};
 
 union lpfc_wqe {
uint32_t words[16];
@@ -4439,7 +4452,7 @@ union lpfc_wqe {
struct fcp_trsp64_wqe fcp_trsp;
struct fcp_tsend64_wqe fcp_tsend;
struct fcp_treceive64_wqe fcp_treceive;
-
+   struct send_frame_wqe send_frame;
 };
 
 union lpfc_wqe128 {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 9f6c7e71814b..9add9473cae5 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -4540,6 +4540,19 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct 
lpfc_acqe_fc_la *acqe_fc)
pmb->vport = phba->pport;
 
if (phba->sli4_hba.link_state.status != LPFC_FC_LA_TYPE_LINK_UP) {
+   phba->link_flag &= ~(LS_MDS_LINK_DOWN | LS_MDS_LOOPBACK);
+
+   switch (phba->sli4_hba.link_state.status) {
+   case LPFC_FC_LA_TYPE_MDS_LINK_DOWN:
+   phba->link_flag |= LS_MDS_LINK_DOWN;
+   break;
+   case LPFC_FC_LA_TYPE_MDS_LOOPBACK:
+   phba->link_flag |= LS_MDS_LOOPBACK;
+   break;
+   default:
+   

[PATCH 11/15] lpfc: Fix debugfs root inode "lpfc" not getting deleted on driver unload.

2017-05-10 Thread James Smart
When unloading and reloading the driver, the driver
fails to recreate the lpfc root inode in the debugfs tree.

The driver is incorrectly removing the lpfc root inode
in lpfc_debugfs_terminate in the first driver instance that
unloads and then sets the lpfc_debugfs_root global parameter
to NULL.  When the final driver instance unloads, the debugfs
calls quietly ignore the remove on a NULL pointer.  The bug
is that the debugfs_remove call returns void so the driver
doesn't know to correctly set the global parameter to NULL.

Base the debugfs_remove of the lpfc_debugfs_root parameter
on lpfc_debugfs_hba_count because this parameter tracks the
fnX instance tracked per driver instance.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_debugfs.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index c7d1c9d37a64..4bcb92c844ca 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -5866,8 +5866,10 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
atomic_dec(_debugfs_hba_count);
}
 
-   debugfs_remove(lpfc_debugfs_root); /* lpfc */
-   lpfc_debugfs_root = NULL;
+   if (atomic_read(_debugfs_hba_count) == 0) {
+   debugfs_remove(lpfc_debugfs_root); /* lpfc */
+   lpfc_debugfs_root = NULL;
+   }
}
 #endif
return;
-- 
2.11.0



[PATCH 12/15] lpfc: Cleanup entry_repost settings on SLI4 queues

2017-05-10 Thread James Smart
Too many work items being processed in IRQ context take a lot
of CPU time and cause problems.

With a recent change, we get out of the ISR after hitting entry_repost
work items on a queue. However, the actual values for entry repost are
still high. EQ is 128 and CQ is 128, this could translate into
processing 128 * 128 (16384) work items under IRQ context.

Set entry_repost in the actual queue creation routine now.
Limit EQ repost to 8 and CQ repost to 64 to further limit the amount
of time spent in the IRQ.

Fix fof IRQ routines as well.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_init.c |  3 --
 drivers/scsi/lpfc/lpfc_sli.c  | 64 +++
 drivers/scsi/lpfc/lpfc_sli4.h |  8 --
 3 files changed, 21 insertions(+), 54 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 472117eb9257..9f6c7e71814b 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -8733,9 +8733,6 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
goto out_destroy;
}
 
-   lpfc_rq_adjust_repost(phba, phba->sli4_hba.hdr_rq, LPFC_ELS_HBQ);
-   lpfc_rq_adjust_repost(phba, phba->sli4_hba.dat_rq, LPFC_ELS_HBQ);
-
rc = lpfc_rq_create(phba, phba->sli4_hba.hdr_rq, phba->sli4_hba.dat_rq,
phba->sli4_hba.els_cq, LPFC_USOL);
if (rc) {
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index c8f597f4d49a..903c06ff828a 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -6978,11 +6978,6 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
rqbp->entry_count = LPFC_NVMET_RQE_DEF_COUNT;
rqbp->buffer_count = 0;
 
-   phba->sli4_hba.nvmet_mrq_hdr[i]->entry_repost =
-   LPFC_QUEUE_MAX_REPOST;
-   phba->sli4_hba.nvmet_mrq_data[i]->entry_repost =
-   LPFC_QUEUE_MAX_REPOST;
-
lpfc_post_rq_buffer(
phba, phba->sli4_hba.nvmet_mrq_hdr[i],
phba->sli4_hba.nvmet_mrq_data[i],
@@ -13037,7 +13032,7 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct 
lpfc_eqe *eqe,
while ((cqe = lpfc_sli4_cq_get(cq))) {
workposted |= lpfc_sli4_sp_handle_mcqe(phba, cqe);
if (!(++ecount % cq->entry_repost))
-   lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
+   break;
cq->CQ_mbox++;
}
break;
@@ -13051,7 +13046,7 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct 
lpfc_eqe *eqe,
workposted |= lpfc_sli4_sp_handle_cqe(phba, cq,
  cqe);
if (!(++ecount % cq->entry_repost))
-   lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
+   break;
}
 
/* Track the max number of CQEs processed in 1 EQ */
@@ -13547,7 +13542,7 @@ lpfc_sli4_fof_handle_eqe(struct lpfc_hba *phba, struct 
lpfc_eqe *eqe)
while ((cqe = lpfc_sli4_cq_get(cq))) {
workposted |= lpfc_sli4_fp_handle_cqe(phba, cq, cqe);
if (!(++ecount % cq->entry_repost))
-   lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
+   break;
}
 
/* Track the max number of CQEs processed in 1 EQ */
@@ -13629,7 +13624,7 @@ lpfc_sli4_fof_intr_handler(int irq, void *dev_id)
while ((eqe = lpfc_sli4_eq_get(eq))) {
lpfc_sli4_fof_handle_eqe(phba, eqe);
if (!(++ecount % eq->entry_repost))
-   lpfc_sli4_eq_release(eq, LPFC_QUEUE_NOARM);
+   break;
eq->EQ_processed++;
}
 
@@ -13927,17 +13922,10 @@ lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t 
entry_size,
}
queue->entry_size = entry_size;
queue->entry_count = entry_count;
-
-   /*
-* entry_repost is calculated based on the number of entries in the
-* queue. This works out except for RQs. If buffers are NOT initially
-* posted for every RQE, entry_repost should be adjusted accordingly.
-*/
-   queue->entry_repost = (entry_count >> 3);
-   if (queue->entry_repost < LPFC_QUEUE_MIN_REPOST)
-   queue->entry_repost = LPFC_QUEUE_MIN_REPOST;
queue->phba = phba;
 
+   /* entry_repost will be set during q creation */
+
return queue;
 out_fail:
lpfc_sli4_queue_free(queue);
@@ -14168,6 +14156,7 @@ lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue 
*eq, uint32_t imax)
status = -ENXIO;

[PATCH 05/15] lpfc: Fix NVMEI driver not decrementing counter causing bad rport state.

2017-05-10 Thread James Smart
During driver boot, a latency in the NVMET driver
side causes the incoming NVMEI PRLI to get rejected by the
NVMET driver.  When this happens, the NVMEI driver runs
out of PRLI retries.  Bouncing the link does not fix the
situation.

If the NVMEI driver decides, on PRLI completion
failures, to retry the PRLI, always decrement the
fc4_prli_sent counter.  This allows the PRLI completion
to resolve to UNMAPPED when NVMET rejects the PRLI.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_els.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 3f9f6d5f8c69..3085895464d9 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -2077,16 +2077,19 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct 
lpfc_iocbq *cmdiocb,
 
if (irsp->ulpStatus) {
/* Check for retry */
+   ndlp->fc4_prli_sent--;
if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
/* ELS command is being retried */
-   ndlp->fc4_prli_sent--;
goto out;
}
+
/* PRLI failed */
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
-"2754 PRLI failure DID:%06X Status:x%x/x%x\n",
+"2754 PRLI failure DID:%06X Status:x%x/x%x, "
+"data: x%x\n",
 ndlp->nlp_DID, irsp->ulpStatus,
-irsp->un.ulpWord[4]);
+irsp->un.ulpWord[4], ndlp->fc4_prli_sent);
+
/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
if (lpfc_error_lost_link(irsp))
goto out;
-- 
2.11.0



[PATCH 06/15] lpfc: Fix NMI watchdog assertions when running nvmet IOPS tests

2017-05-10 Thread James Smart
After running IOPS test for 30 second we get
kernel:NMI watchdog: Watchdog detected hard LOCKUP on cpu 0

The driver is speend too much time in it's ISR.

In ISR EQ and CQ processing routines, if we hit the entry_repost
numbers of EQE/CQEs just break out of the routine as opposed to
hitting the doorbell with NOARM and continue processing.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_debugfs.c | 30 +++---
 drivers/scsi/lpfc/lpfc_sli.c |  8 ++--
 2 files changed, 17 insertions(+), 21 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index a41daedeb967..7284533f4df2 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -3075,11 +3075,11 @@ __lpfc_idiag_print_wq(struct lpfc_queue *qp, char 
*wqtype,
qp->assoc_qid, qp->q_cnt_1,
(unsigned long long)qp->q_cnt_4);
len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
-   "\t\tWQID[%02d], QE-CNT[%04d], QE-SIZE[%04d], "
-   "HOST-IDX[%04d], PORT-IDX[%04d]",
+   "\t\tWQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
+   "HST-IDX[%04d], PRT-IDX[%04d], PST[%03d]",
qp->queue_id, qp->entry_count,
qp->entry_size, qp->host_index,
-   qp->hba_index);
+   qp->hba_index, qp->entry_repost);
len +=  snprintf(pbuffer + len,
LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n");
return len;
@@ -3126,11 +3126,11 @@ __lpfc_idiag_print_cq(struct lpfc_queue *qp, char 
*cqtype,
qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2,
qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
-   "\tCQID[%02d], QE-CNT[%04d], QE-SIZE[%04d], "
-   "HOST-IDX[%04d], PORT-IDX[%04d]",
+   "\tCQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
+   "HST-IDX[%04d], PRT-IDX[%04d], PST[%03d]",
qp->queue_id, qp->entry_count,
qp->entry_size, qp->host_index,
-   qp->hba_index);
+   qp->hba_index, qp->entry_repost);
 
len +=  snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n");
 
@@ -3152,16 +3152,16 @@ __lpfc_idiag_print_rqpair(struct lpfc_queue *qp, struct 
lpfc_queue *datqp,
qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2,
qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
-   "\t\tHQID[%02d], QE-CNT[%04d], QE-SIZE[%04d], "
-   "HOST-IDX[%04d], PORT-IDX[%04d]\n",
+   "\t\tHQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
+   "HST-IDX[%04d], PRT-IDX[%04d], PST[%03d]\n",
qp->queue_id, qp->entry_count, qp->entry_size,
-   qp->host_index, qp->hba_index);
+   qp->host_index, qp->hba_index, qp->entry_repost);
len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
-   "\t\tDQID[%02d], QE-CNT[%04d], QE-SIZE[%04d], "
-   "HOST-IDX[%04d], PORT-IDX[%04d]\n",
+   "\t\tDQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
+   "HST-IDX[%04d], PRT-IDX[%04d], PST[%03d]\n",
datqp->queue_id, datqp->entry_count,
datqp->entry_size, datqp->host_index,
-   datqp->hba_index);
+   datqp->hba_index, datqp->entry_repost);
return len;
 }
 
@@ -3247,10 +3247,10 @@ __lpfc_idiag_print_eq(struct lpfc_queue *qp, char 
*eqtype,
eqtype, qp->q_cnt_1, qp->q_cnt_2, qp->q_cnt_3,
(unsigned long long)qp->q_cnt_4);
len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
-   "EQID[%02d], QE-CNT[%04d], QE-SIZE[%04d], "
-   "HOST-IDX[%04d], PORT-IDX[%04d]",
+   "EQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
+   "HST-IDX[%04d], PRT-IDX[%04d], PST[%03d]",
qp->queue_id, qp->entry_count, qp->entry_size,
-   qp->host_index, qp->hba_index);
+   qp->host_index, qp->hba_index, qp->entry_repost);
len +=  snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n");
 
return len;
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index cdf02a957690..66bb86656bba 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -13234,10 +13234,6 @@ 

[PATCH 03/15] lpfc: Adding additional stats counters for nvme.

2017-05-10 Thread James Smart
More debug messages added for nvme statistics.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_attr.c| 24 -
 drivers/scsi/lpfc/lpfc_debugfs.c | 27 +--
 drivers/scsi/lpfc/lpfc_nvmet.c   | 46 ++--
 drivers/scsi/lpfc/lpfc_nvmet.h   | 12 ++-
 drivers/scsi/lpfc/lpfc_sli.c | 38 -
 drivers/scsi/lpfc/lpfc_sli4.h|  2 +-
 6 files changed, 106 insertions(+), 43 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 4830370bfab1..41ec7451689b 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -205,8 +205,9 @@ lpfc_nvme_info_show(struct device *dev, struct 
device_attribute *attr,
atomic_read(>xmt_ls_rsp_error));
 
len += snprintf(buf+len, PAGE_SIZE-len,
-   "FCP: Rcv %08x Drop %08x\n",
+   "FCP: Rcv %08x Release %08x Drop %08x\n",
atomic_read(>rcv_fcp_cmd_in),
+   atomic_read(>xmt_fcp_release),
atomic_read(>rcv_fcp_cmd_drop));
 
if (atomic_read(>rcv_fcp_cmd_in) !=
@@ -218,15 +219,12 @@ lpfc_nvme_info_show(struct device *dev, struct 
device_attribute *attr,
}
 
len += snprintf(buf+len, PAGE_SIZE-len,
-   "FCP Rsp: RD %08x rsp %08x WR %08x rsp %08x\n",
+   "FCP Rsp: RD %08x rsp %08x WR %08x rsp %08x "
+   "drop %08x\n",
atomic_read(>xmt_fcp_read),
atomic_read(>xmt_fcp_read_rsp),
atomic_read(>xmt_fcp_write),
-   atomic_read(>xmt_fcp_rsp));
-
-   len += snprintf(buf+len, PAGE_SIZE-len,
-   "FCP Rsp: abort %08x drop %08x\n",
-   atomic_read(>xmt_fcp_abort),
+   atomic_read(>xmt_fcp_rsp),
atomic_read(>xmt_fcp_drop));
 
len += snprintf(buf+len, PAGE_SIZE-len,
@@ -236,10 +234,16 @@ lpfc_nvme_info_show(struct device *dev, struct 
device_attribute *attr,
atomic_read(>xmt_fcp_rsp_drop));
 
len += snprintf(buf+len, PAGE_SIZE-len,
-   "ABORT: Xmt %08x Err %08x Cmpl %08x",
+   "ABORT: Xmt %08x Cmpl %08x\n",
+   atomic_read(>xmt_fcp_abort),
+   atomic_read(>xmt_fcp_abort_cmpl));
+
+   len += snprintf(buf + len, PAGE_SIZE - len,
+   "ABORT: Sol %08x  Usol %08x Err %08x Cmpl %08x",
+   atomic_read(>xmt_abort_sol),
+   atomic_read(>xmt_abort_unsol),
atomic_read(>xmt_abort_rsp),
-   atomic_read(>xmt_abort_rsp_error),
-   atomic_read(>xmt_abort_cmpl));
+   atomic_read(>xmt_abort_rsp_error));
 
len +=  snprintf(buf+len, PAGE_SIZE-len, "\n");
return len;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index fce549a91911..a41daedeb967 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -798,21 +798,22 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char 
*buf, int size)
atomic_read(>xmt_fcp_rsp));
 
len += snprintf(buf + len, size - len,
-   "FCP Rsp: abort %08x drop %08x\n",
-   atomic_read(>xmt_fcp_abort),
-   atomic_read(>xmt_fcp_drop));
-
-   len += snprintf(buf + len, size - len,
"FCP Rsp Cmpl: %08x err %08x drop %08x\n",
atomic_read(>xmt_fcp_rsp_cmpl),
atomic_read(>xmt_fcp_rsp_error),
atomic_read(>xmt_fcp_rsp_drop));
 
len += snprintf(buf + len, size - len,
-   "ABORT: Xmt %08x Err %08x Cmpl %08x",
+   "ABORT: Xmt %08x Cmpl %08x\n",
+   atomic_read(>xmt_fcp_abort),
+   atomic_read(>xmt_fcp_abort_cmpl));
+
+   len += snprintf(buf + len, size - len,
+   "ABORT: Sol %08x  Usol %08x Err %08x Cmpl %08x",
+   atomic_read(>xmt_abort_sol),
+   atomic_read(>xmt_abort_unsol),

[PATCH 04/15] lpfc: Fix nvmet RQ resource needs for large block writes.

2017-05-10 Thread James Smart
Large block writes to the nvme target were failing because
the default number of RQs posted was insufficient.

Expand the NVMET RQs to 2048 RQEs and ensure a minimun of 2048
RQEs are posted, no matter how many MRQs are configured.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_attr.c  |  4 ++--
 drivers/scsi/lpfc/lpfc_init.c  | 20 +++-
 drivers/scsi/lpfc/lpfc_nvmet.c |  2 +-
 drivers/scsi/lpfc/lpfc_nvmet.h |  1 +
 drivers/scsi/lpfc/lpfc_sli.c   | 18 ++
 drivers/scsi/lpfc/lpfc_sli4.h  |  1 +
 6 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 41ec7451689b..ee4d9be95960 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -60,9 +60,9 @@
 #define LPFC_MIN_DEVLOSS_TMO   1
 #define LPFC_MAX_DEVLOSS_TMO   255
 
-#define LPFC_DEF_MRQ_POST  256
+#define LPFC_DEF_MRQ_POST  512
 #define LPFC_MIN_MRQ_POST  32
-#define LPFC_MAX_MRQ_POST  512
+#define LPFC_MAX_MRQ_POST  2048
 
 /*
  * Write key size should be multiple of 4. If write key is changed
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index b1b181a756dc..66e3cc40d64e 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -3390,6 +3390,11 @@ lpfc_sli4_nvmet_sgl_update(struct lpfc_hba *phba)
 */
els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba);
nvmet_xri_cnt = phba->cfg_nvmet_mrq * phba->cfg_nvmet_mrq_post;
+
+   /* Ensure we at least meet the minimun for the system */
+   if (nvmet_xri_cnt < LPFC_NVMET_RQE_DEF_COUNT)
+   nvmet_xri_cnt = LPFC_NVMET_RQE_DEF_COUNT;
+
tot_cnt = phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt;
if (nvmet_xri_cnt > tot_cnt) {
phba->cfg_nvmet_mrq_post = tot_cnt / phba->cfg_nvmet_mrq;
@@ -8158,7 +8163,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
/* Create NVMET Receive Queue for header */
qdesc = lpfc_sli4_queue_alloc(phba,
  phba->sli4_hba.rq_esize,
- phba->sli4_hba.rq_ecount);
+ LPFC_NVMET_RQE_DEF_COUNT);
if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3146 Failed allocate "
@@ -8180,7 +8185,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
/* Create NVMET Receive Queue for data */
qdesc = lpfc_sli4_queue_alloc(phba,
  phba->sli4_hba.rq_esize,
- phba->sli4_hba.rq_ecount);
+ LPFC_NVMET_RQE_DEF_COUNT);
if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3156 Failed allocate "
@@ -11096,7 +11101,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const 
struct pci_device_id *pid)
struct lpfc_hba   *phba;
struct lpfc_vport *vport = NULL;
struct Scsi_Host  *shost = NULL;
-   int error, cnt;
+   int error, cnt, num;
uint32_t cfg_mode, intr_mode;
 
/* Allocate memory for HBA structure */
@@ -11131,8 +11136,13 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const 
struct pci_device_id *pid)
}
 
cnt = phba->cfg_iocb_cnt * 1024;
-   if (phba->nvmet_support)
-   cnt += phba->cfg_nvmet_mrq_post * phba->cfg_nvmet_mrq;
+   if (phba->nvmet_support) {
+   /* Ensure we at least meet the minimun for the system */
+   num = (phba->cfg_nvmet_mrq_post * phba->cfg_nvmet_mrq);
+   if (num < LPFC_NVMET_RQE_DEF_COUNT)
+   num = LPFC_NVMET_RQE_DEF_COUNT;
+   cnt += num;
+   }
 
/* Initialize and populate the iocb list per host */
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index bb12e2c9fbf4..dfa7296499cf 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -614,9 +614,9 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
lpfc_nvmeio_data(phba, "NVMET FCP CMND: xri x%x op x%x len x%x\n",
 ctxp->oxid, rsp->op, rsp->rsplen);
 
+   ctxp->flag |= LPFC_NVMET_IO_INP;
rc = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, nvmewqeq);
if (rc == WQE_SUCCESS) {
-   ctxp->flag |= LPFC_NVMET_IO_INP;
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
if (!phba->ktime_on)
return 0;
diff --git 

[PATCH 00/15] lpfc updates for 11.2.0.14

2017-05-10 Thread James Smart
This patch set provides a number of bug fixes, code cleanups, and error
handling, mostly in the nvme area of lpfc.

There is one new feature in the series to add MDS diagnostics support

The patches were cut against the Martin's 4.12/scsi-fixes tree.
There are no outside dependencies. The patches should merge via
Martin's tree. 


James Smart (15):
  lpfc: Fix used-RPI accounting problem.
  lpfc: Fix system crash when port is reset.
  lpfc: Adding additional stats counters for nvme.
  lpfc: Fix nvmet RQ resource needs for large block writes.
  lpfc: Fix NVMEI driver not decrementing counter causing bad rport
state.
  lpfc: Fix NMI watchdog assertions when running nvmet IOPS tests
  lpfc: Separate NVMET data buffer pool fir ELS/CT.
  lpfc: Separate NVMET RQ buffer posting from IO resources
SGL/iocbq/context
  lpfc: Added recovery logic for running out of NVMET IO context
resources
  lpfc: Fix NVME I+T not registering NVME as a supported FC4 type
  lpfc: Fix debugfs root inode "lpfc" not getting deleted on driver
unload.
  lpfc: Cleanup entry_repost settings on SLI4 queues
  lpfc: Fix NVMEI's handling of NVMET's PRLI response attributes
  lpfc: Add MDS Diagnostic support.
  lpfc: update version to 11.2.0.14

 drivers/scsi/lpfc/lpfc.h   |  23 ++-
 drivers/scsi/lpfc/lpfc_attr.c  |  45 ++--
 drivers/scsi/lpfc/lpfc_crtn.h  |  11 +-
 drivers/scsi/lpfc/lpfc_ct.c|   1 +
 drivers/scsi/lpfc/lpfc_debugfs.c   |  69 ---
 drivers/scsi/lpfc/lpfc_disc.h  |   1 +
 drivers/scsi/lpfc/lpfc_els.c   |  19 +-
 drivers/scsi/lpfc/lpfc_hbadisc.c   |   9 +-
 drivers/scsi/lpfc/lpfc_hw4.h   |  16 +-
 drivers/scsi/lpfc/lpfc_init.c  | 137 
 drivers/scsi/lpfc/lpfc_mem.c   | 100 +++--
 drivers/scsi/lpfc/lpfc_nportdisc.c |   6 +
 drivers/scsi/lpfc/lpfc_nvmet.c | 412 ++---
 drivers/scsi/lpfc/lpfc_nvmet.h |  14 +-
 drivers/scsi/lpfc/lpfc_sli.c   | 357 +---
 drivers/scsi/lpfc/lpfc_sli4.h  |  18 +-
 drivers/scsi/lpfc/lpfc_version.h   |   2 +-
 17 files changed, 829 insertions(+), 411 deletions(-)

-- 
2.11.0



[PATCH 01/15] lpfc: Fix used-RPI accounting problem.

2017-05-10 Thread James Smart
With 255 vports created a link trasition can casue a crash.

When going through discovery after a link bounce the driver is using
rpis before the cmd FCOE_POST_HDR_TEMPLATES completes. By doing that
the next rpi bumps the rpi range out of the boundary.

The fix it to increment the next_rpi only when the FCOE_POST_HDR_TEMPLATE
succeeds.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_els.c  |  3 ++-
 drivers/scsi/lpfc/lpfc_init.c | 24 +---
 drivers/scsi/lpfc/lpfc_sli.c  |  8 
 drivers/scsi/lpfc/lpfc_sli4.h |  1 +
 4 files changed, 16 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 67827e397431..3f9f6d5f8c69 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -8667,7 +8667,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct 
lpfc_iocbq *cmdiocb,
lpfc_do_scr_ns_plogi(phba, vport);
goto out;
 fdisc_failed:
-   if (vport->fc_vport->vport_state != FC_VPORT_NO_FABRIC_RSCS)
+   if (vport->fc_vport &&
+   (vport->fc_vport->vport_state != FC_VPORT_NO_FABRIC_RSCS))
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
/* Cancel discovery timer */
lpfc_can_disctmo(vport);
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 4b1eb98c228d..b1b181a756dc 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -6525,7 +6525,6 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
uint16_t rpi_limit, curr_rpi_range;
struct lpfc_dmabuf *dmabuf;
struct lpfc_rpi_hdr *rpi_hdr;
-   uint32_t rpi_count;
 
/*
 * If the SLI4 port supports extents, posting the rpi header isn't
@@ -6538,8 +6537,7 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
return NULL;
 
/* The limit on the logical index is just the max_rpi count. */
-   rpi_limit = phba->sli4_hba.max_cfg_param.rpi_base +
-   phba->sli4_hba.max_cfg_param.max_rpi - 1;
+   rpi_limit = phba->sli4_hba.max_cfg_param.max_rpi;
 
spin_lock_irq(>hbalock);
/*
@@ -6550,18 +6548,10 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
curr_rpi_range = phba->sli4_hba.next_rpi;
spin_unlock_irq(>hbalock);
 
-   /*
-* The port has a limited number of rpis. The increment here
-* is LPFC_RPI_HDR_COUNT - 1 to account for the starting value
-* and to allow the full max_rpi range per port.
-*/
-   if ((curr_rpi_range + (LPFC_RPI_HDR_COUNT - 1)) > rpi_limit)
-   rpi_count = rpi_limit - curr_rpi_range;
-   else
-   rpi_count = LPFC_RPI_HDR_COUNT;
-
-   if (!rpi_count)
+   /* Reached full RPI range */
+   if (curr_rpi_range == rpi_limit)
return NULL;
+
/*
 * First allocate the protocol header region for the port.  The
 * port expects a 4KB DMA-mapped memory region that is 4K aligned.
@@ -6595,13 +6585,9 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
 
/* The rpi_hdr stores the logical index only. */
rpi_hdr->start_rpi = curr_rpi_range;
+   rpi_hdr->next_rpi = phba->sli4_hba.next_rpi + LPFC_RPI_HDR_COUNT;
list_add_tail(_hdr->list, >sli4_hba.lpfc_rpi_hdr_list);
 
-   /*
-* The next_rpi stores the next logical module-64 rpi value used
-* to post physical rpis in subsequent rpi postings.
-*/
-   phba->sli4_hba.next_rpi += rpi_count;
spin_unlock_irq(>hbalock);
return rpi_hdr;
 
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 2a4fc00dfa9b..e2d25ae5ba45 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -17137,6 +17137,14 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct 
lpfc_rpi_hdr *rpi_page)
"status x%x add_status x%x, mbx status x%x\n",
shdr_status, shdr_add_status, rc);
rc = -ENXIO;
+   } else {
+   /*
+* The next_rpi stores the next logical module-64 rpi value used
+* to post physical rpis in subsequent rpi postings.
+*/
+   spin_lock_irq(>hbalock);
+   phba->sli4_hba.next_rpi = rpi_page->next_rpi;
+   spin_unlock_irq(>hbalock);
}
return rc;
 }
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index da46471337c8..915e8d5581bd 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -698,6 +698,7 @@ struct lpfc_rpi_hdr {
struct lpfc_dmabuf *dmabuf;
uint32_t page_count;
uint32_t start_rpi;
+   uint16_t next_rpi;
 };
 
 struct lpfc_rsrc_blks {
-- 
2.11.0



[PATCH 02/15] lpfc: Fix system crash when port is reset.

2017-05-10 Thread James Smart
The driver panic when using the els_wq during port reset.

Check for NULL els_wq before dereferencing.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc.h | 8 ++--
 drivers/scsi/lpfc/lpfc_hbadisc.c | 6 +++---
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 6d7840b096e6..62571fa9c6ad 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -1228,7 +1228,11 @@ lpfc_sli_read_hs(struct lpfc_hba *phba)
 static inline struct lpfc_sli_ring *
 lpfc_phba_elsring(struct lpfc_hba *phba)
 {
-   if (phba->sli_rev == LPFC_SLI_REV4)
-   return phba->sli4_hba.els_wq->pring;
+   if (phba->sli_rev == LPFC_SLI_REV4) {
+   if (phba->sli4_hba.els_wq)
+   return phba->sli4_hba.els_wq->pring;
+   else
+   return NULL;
+   }
return >sli.sli3_ring[LPFC_ELS_RING];
 }
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 0482c5580331..dcc9b3858778 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -693,9 +693,9 @@ lpfc_work_done(struct lpfc_hba *phba)
pring = lpfc_phba_elsring(phba);
status = (ha_copy & (HA_RXMASK  << (4*LPFC_ELS_RING)));
status >>= (4*LPFC_ELS_RING);
-   if ((status & HA_RXMASK) ||
-   (pring->flag & LPFC_DEFERRED_RING_EVENT) ||
-   (phba->hba_flag & HBA_SP_QUEUE_EVT)) {
+   if (pring && (status & HA_RXMASK ||
+ pring->flag & LPFC_DEFERRED_RING_EVENT ||
+ phba->hba_flag & HBA_SP_QUEUE_EVT)) {
if (pring->flag & LPFC_STOP_IOCB_EVENT) {
pring->flag |= LPFC_DEFERRED_RING_EVENT;
/* Set the lpfc data pending flag */
-- 
2.11.0



[PATCH v1] ibmvscsis: Fix the incorrect req_lim_delta

2017-05-10 Thread Bryant G. Ly
The current code is not correctly calculating the req_lim_delta.

We want to make sure vscsi->credit is always incremented when
we do not send a response for the scsi op. Thus for the case where
there is a successfully aborted task we need to make sure the
vscsi->credit is incremented.

Signed-off-by: Bryant G. Ly 
Reviewed-by: Michael Cyr 
Cc:  # v4.8+
---
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 21 +
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c 
b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index ee64241..2d97f02 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -2965,10 +2965,7 @@ static long srp_build_response(struct scsi_info *vscsi,
 
rsp->opcode = SRP_RSP;
 
-   if (vscsi->credit > 0 && vscsi->state == SRP_PROCESSING)
-   rsp->req_lim_delta = cpu_to_be32(vscsi->credit);
-   else
-   rsp->req_lim_delta = cpu_to_be32(1 + vscsi->credit);
+   rsp->req_lim_delta = cpu_to_be32(1 + vscsi->credit);
rsp->tag = cmd->rsp.tag;
rsp->flags = 0;
 
@@ -3739,6 +3736,22 @@ static void ibmvscsis_queue_tm_rsp(struct se_cmd *se_cmd)
 
 static void ibmvscsis_aborted_task(struct se_cmd *se_cmd)
 {
+   struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
+se_cmd);
+   struct scsi_info *vscsi = cmd->adapter;
+
+   /*
+* With a successfully aborted op through LIO we want to increment the
+* the vscsi credit so that when we dont send a rsp to the original
+* scsi abort op but the tm rsp to the abort is sent, the credit is
+* correctly sent with the abort tm rsp. We would need 1 for the abort
+* tm rsp and 1 credit for the aborted scsi op. Thus we need to
+* increment here.
+*/
+   spin_lock_bh(>intr_lock);
+   vscsi->credit += 1;
+   spin_unlock_bh(>intr_lock);
+
pr_debug("ibmvscsis_aborted_task %p task_tag: %llu\n",
 se_cmd, se_cmd->tag);
 }
-- 
2.5.4 (Apple Git-61)



RE: [PATCH V2 15/19] aacraid: Make sure ioctl returns on controller reset

2017-05-10 Thread Dave Carroll
> -Original Message-
> From: Raghava Aditya Renukunta
> [mailto:raghavaaditya.renuku...@microsemi.com]
> Sent: Wednesday, May 10, 2017 10:40 AM
> To: j...@linux.vnet.ibm.com; martin.peter...@oracle.com; linux-
> s...@vger.kernel.org
> Cc: Dave Carroll ; Gana Sridaran
> ; Scott Benesh
> ; Prasad Munirathnam
> 
> Subject: [PATCH V2 15/19] aacraid: Make sure ioctl returns on controller reset
> 
> Made sure that ioctl commands return in case of a controller reset.
> 
> Signed-off-by: Raghava Aditya Renukunta
> 
> 
> ---
> Changes in V2:
> Removed incorrect up
> Cleared wait flag once event is received not before

Reviewed-by: Dave Carroll 


RE: [PATCH V2 02/19] aacraid: Fix DMAR issues with iommu=pt

2017-05-10 Thread Dave Carroll
> -Original Message-
> From: Raghava Aditya Renukunta
> [mailto:raghavaaditya.renuku...@microsemi.com]
> Sent: Wednesday, May 10, 2017 10:40 AM
> To: j...@linux.vnet.ibm.com; martin.peter...@oracle.com; linux-
> s...@vger.kernel.org
> Cc: Dave Carroll ; Gana Sridaran
> ; Scott Benesh
> ; Prasad Munirathnam
> 
> Subject: [PATCH V2 02/19] aacraid: Fix DMAR issues with iommu=pt
> 
> The driver changed the DMA consistent map after consistent memory was
> allocated, this invalidated the IOMMU identity mapping. The fix was to make
> sure that we set the DMA consistent mask setting once depending on the
> controller card.
> 
> Signed-off-by: Raghava Aditya Renukunta
> 
> 
> ---
> Changes in V2:
> None
> 
>  drivers/scsi/aacraid/aachba.c  | 17 ++---
> drivers/scsi/aacraid/commsup.c | 29 ++---
>  drivers/scsi/aacraid/linit.c   | 32 +++-
>  3 files changed, 43 insertions(+), 35 deletions(-)
> 
Reviewed-by: Dave Carroll 


RE: [PATCH V2 01/19] aacraid: Remove __GFP_DMA for raw srb memory

2017-05-10 Thread Dave Carroll
> -Original Message-
> From: Raghava Aditya Renukunta
> [mailto:raghavaaditya.renuku...@microsemi.com]
> Sent: Wednesday, May 10, 2017 10:40 AM
> To: j...@linux.vnet.ibm.com; martin.peter...@oracle.com; linux-
> s...@vger.kernel.org
> Cc: Dave Carroll ; Gana Sridaran
> ; Scott Benesh
> ; Prasad Munirathnam
> 
> Subject: [PATCH V2 01/19] aacraid: Remove __GFP_DMA for raw srb memory
> 
> The raw srb commands do not requires memory that in the ZONE_DMA memory
> space. For 32bit srb commands use GFP_DMA32 to limit the memory to 32bit
> memory range (4GB).
> 
> Signed-off-by: Raghava Aditya Renukunta
> 
> 
> ---
> Changes in V2:
> Corrected flag name to GFP_DMA32 in patch description and corrected
> GFP_DMA to __GFP_DMA in patch heading Removed comment
> 
>  drivers/scsi/aacraid/commctrl.c | 15 +++
>  1 file changed, 7 insertions(+), 8 deletions(-)

Reviewed-by: Dave Carroll 


Re: [PATCH 25/27] block: remove the discard_zeroes_data flag

2017-05-10 Thread h...@lst.de
On Mon, May 08, 2017 at 11:46:14PM -0700, Nicholas A. Bellinger wrote:
> That said, simply propagating up q->limits.max_write_zeroes_sectors as
> dev_attrib->unmap_zeroes_data following existing code still looks like
> the right thing to do.

It is not.  Martin has decoupled write same/zeroes support from discard
support.  Any device will claim to support it initially, and we'll
only clear the flag if a Write Same command fails.

So even if LBPRZ is not set you can trivially get into a situation
where discard is supported through UNMAP, and you'll incorrectly
set LBPRZ and will cause data corruption.


Re: [PATCH] scsi: sanity check for timeout in sg_io()

2017-05-10 Thread James Bottomley
On Wed, 2017-05-10 at 15:24 +0200, Hannes Reinecke wrote:
> sg_io() is using msecs_to_jiffies() to convert a passed in timeout
> value (in milliseconds) to a jiffies value. However, if the value
> is too large msecs_to_jiffies() will return MAX_JIFFY_OFFSET, which
> will be truncated to -2 and cause the timeout to be set to 1.3
> _years_. Which is probably too long for most applications.

What makes you think that?  If a user specified timeout in ms is over
MAX_JIFFY_OFFSET on, say a 250HZ machine, then they're already asking
for something around this length of time in ms, which is probably their
attempt at machine infinity, meaning they want effectively no timeout. 
 Your patch would now give them the default timeout, which looks way
too short.

James

> Signed-off-by: Hannes Reinecke 
> ---
>  block/scsi_ioctl.c | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
> index 4a294a5..53b95ea 100644
> --- a/block/scsi_ioctl.c
> +++ b/block/scsi_ioctl.c
> @@ -231,6 +231,7 @@ static int blk_fill_sghdr_rq(struct request_queue
> *q, struct request *rq,
>struct sg_io_hdr *hdr, fmode_t mode)
>  {
>   struct scsi_request *req = scsi_req(rq);
> + unsigned long timeout;
>  
>   if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len))
>   return -EFAULT;
> @@ -242,7 +243,11 @@ static int blk_fill_sghdr_rq(struct
> request_queue *q, struct request *rq,
>*/
>   req->cmd_len = hdr->cmd_len;
>  
> - rq->timeout = msecs_to_jiffies(hdr->timeout);
> + timeout = msecs_to_jiffies(hdr->timeout);
> + if (timeout == MAX_JIFFY_OFFSET)
> + rq->timeout = 0;
> + else
> + rq->timeout = timeout;
>   if (!rq->timeout)
>   rq->timeout = q->sg_timeout;
>   if (!rq->timeout)



[PATCH] scsi: sanity check for timeout in sg_io()

2017-05-10 Thread Hannes Reinecke
sg_io() is using msecs_to_jiffies() to convert a passed in timeout
value (in milliseconds) to a jiffies value. However, if the value
is too large msecs_to_jiffies() will return MAX_JIFFY_OFFSET, which
will be truncated to -2 and cause the timeout to be set to 1.3
_years_. Which is probably too long for most applications.

Signed-off-by: Hannes Reinecke 
---
 block/scsi_ioctl.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 4a294a5..53b95ea 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -231,6 +231,7 @@ static int blk_fill_sghdr_rq(struct request_queue *q, 
struct request *rq,
 struct sg_io_hdr *hdr, fmode_t mode)
 {
struct scsi_request *req = scsi_req(rq);
+   unsigned long timeout;
 
if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len))
return -EFAULT;
@@ -242,7 +243,11 @@ static int blk_fill_sghdr_rq(struct request_queue *q, 
struct request *rq,
 */
req->cmd_len = hdr->cmd_len;
 
-   rq->timeout = msecs_to_jiffies(hdr->timeout);
+   timeout = msecs_to_jiffies(hdr->timeout);
+   if (timeout == MAX_JIFFY_OFFSET)
+   rq->timeout = 0;
+   else
+   rq->timeout = timeout;
if (!rq->timeout)
rq->timeout = q->sg_timeout;
if (!rq->timeout)
-- 
1.8.5.6



Re: [PATCH v2] scsi: sg: don't return bogus Sg_requests

2017-05-10 Thread Hannes Reinecke
On 05/10/2017 09:53 AM, Johannes Thumshirn wrote:
> If the list search in sg_get_rq_mark() fails to find a valid request, we
> return a bogus element. This then can later lead to a GPF in sg_remove_scat().
> 
> So don't return bogus Sg_requests in sg_get_rq_mark() but NULL in case the
> list search doesn't find a valid request.
> 
> Signed-off-by: Johannes Thumshirn 
> Reported-by: Andrey Konovalov 
> Cc: Hannes Reinecke 
> Cc: Christoph Hellwig 
> Cc: Doug Gilbert 
> ---
> Changes to v1:
> * Directly return found element within the loop (Hannes)
> 
>  drivers/scsi/sg.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
> index 0a38ba01b7b4..82c33a6edbea 100644
> --- a/drivers/scsi/sg.c
> +++ b/drivers/scsi/sg.c
> @@ -2074,11 +2074,12 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
>   if ((1 == resp->done) && (!resp->sg_io_owned) &&
>   ((-1 == pack_id) || (resp->header.pack_id == pack_id))) {
>   resp->done = 2; /* guard against other readers */
> - break;
> + write_unlock_irqrestore(>rq_list_lock, iflags);
> + return resp;
>   }
>   }
>   write_unlock_irqrestore(>rq_list_lock, iflags);
> - return resp;
> + return NULL;
>  }
>  
>  /* always adds to end of list */
> 
Better.

Reviewed-by: Hannes Reinecke 

Cheers,

Hannes
-- 
Dr. Hannes ReineckeTeamlead Storage & Networking
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)


[PATCH v2] scsi: sg: don't return bogus Sg_requests

2017-05-10 Thread Johannes Thumshirn
If the list search in sg_get_rq_mark() fails to find a valid request, we
return a bogus element. This then can later lead to a GPF in sg_remove_scat().

So don't return bogus Sg_requests in sg_get_rq_mark() but NULL in case the
list search doesn't find a valid request.

Signed-off-by: Johannes Thumshirn 
Reported-by: Andrey Konovalov 
Cc: Hannes Reinecke 
Cc: Christoph Hellwig 
Cc: Doug Gilbert 
---
Changes to v1:
* Directly return found element within the loop (Hannes)

 drivers/scsi/sg.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 0a38ba01b7b4..82c33a6edbea 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -2074,11 +2074,12 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
if ((1 == resp->done) && (!resp->sg_io_owned) &&
((-1 == pack_id) || (resp->header.pack_id == pack_id))) {
resp->done = 2; /* guard against other readers */
-   break;
+   write_unlock_irqrestore(>rq_list_lock, iflags);
+   return resp;
}
}
write_unlock_irqrestore(>rq_list_lock, iflags);
-   return resp;
+   return NULL;
 }
 
 /* always adds to end of list */
-- 
2.12.0



Re: [PATCH] scsi: sg: don't return bogus Sg_requests

2017-05-10 Thread Hannes Reinecke
On 05/10/2017 09:41 AM, Johannes Thumshirn wrote:
> If the list search in sg_get_rq_mark() fails to find a valid request, we
> return a bogus element. This then can later lead to a GPF in sg_remove_scat().
> 
> So don't return bogus Sg_requests in sg_get_rq_mark() but NULL in case the
> list search doesn't find a valid request.
> 
> Signed-off-by: Johannes Thumshirn 
> Reported-by: Andrey Konovalov 
> Cc: Hannes Reinecke 
> Cc: Christoph Hellwig 
> Cc: Doug Gilbert 
> ---
>  drivers/scsi/sg.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
> index 0a38ba01b7b4..abfde23fa186 100644
> --- a/drivers/scsi/sg.c
> +++ b/drivers/scsi/sg.c
> @@ -2078,7 +2078,7 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
>   }
>   }
>   write_unlock_irqrestore(>rq_list_lock, iflags);
> - return resp;
> + return (resp->done == 2) ? resp : NULL;
>  }
>  
>  /* always adds to end of list */
> 
Not quite.
Please return 'resp' directly from within the loop.
With this fix we run into the risk that by chance the uninitialized
'resp' pointer contains a '2' at the 'done' location, triggering this
issue again.

Cheers,

Hannes
-- 
Dr. Hannes ReineckeTeamlead Storage & Networking
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)


[PATCH] scsi: sg: don't return bogus Sg_requests

2017-05-10 Thread Johannes Thumshirn
If the list search in sg_get_rq_mark() fails to find a valid request, we
return a bogus element. This then can later lead to a GPF in sg_remove_scat().

So don't return bogus Sg_requests in sg_get_rq_mark() but NULL in case the
list search doesn't find a valid request.

Signed-off-by: Johannes Thumshirn 
Reported-by: Andrey Konovalov 
Cc: Hannes Reinecke 
Cc: Christoph Hellwig 
Cc: Doug Gilbert 
---
 drivers/scsi/sg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 0a38ba01b7b4..abfde23fa186 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -2078,7 +2078,7 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
}
}
write_unlock_irqrestore(>rq_list_lock, iflags);
-   return resp;
+   return (resp->done == 2) ? resp : NULL;
 }
 
 /* always adds to end of list */
-- 
2.12.0



[PATCH V2 17/19] aacraid : Add reset debugging statements

2017-05-10 Thread Raghava Aditya Renukunta
Added info and error messages in controller reset function to log
information about the status of the IOP/SOFT reset.

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/src.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 10a589b..5367d3f 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -761,8 +761,7 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int 
bled, u8 reset_type)
goto invalid_out;
 
if (bled)
-   pr_err("%s%d: adapter kernel panic'd %x.\n",
-   dev->name, dev->id, bled);
+   dev_err(>pdev->dev, "adapter kernel panic'd %x.\n", bled);
 
/*
 * When there is a BlinkLED, IOP_RESET has not effect
@@ -772,7 +771,10 @@ static int aac_src_restart_adapter(struct aac_dev *dev, 
int bled, u8 reset_type)
 
dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
 
+   dev_err(>pdev->dev, "Controller reset type is %d\n", reset_type);
+
if (reset_type & HW_IOP_RESET) {
+   dev_info(>pdev->dev, "Issuing IOP reset\n");
aac_send_iop_reset(dev);
 
/*
@@ -781,16 +783,20 @@ static int aac_src_restart_adapter(struct aac_dev *dev, 
int bled, u8 reset_type)
is_ctrl_up = aac_is_ctrl_up_and_running(dev);
if (!is_ctrl_up)
dev_err(>pdev->dev, "IOP reset failed\n");
-   else
+   else {
+   dev_info(>pdev->dev, "IOP reset succeded\n");
goto set_startup;
+   }
}
 
if (!dev->sa_firmware) {
+   dev_err(>pdev->dev, "ARC Reset attempt failed\n");
ret = -ENODEV;
goto out;
}
 
if (reset_type & HW_SOFT_RESET) {
+   dev_info(>pdev->dev, "Issuing SOFT reset\n");
aac_send_hardware_soft_reset(dev);
dev->msi_enabled = 0;
 
@@ -799,7 +805,8 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int 
bled, u8 reset_type)
dev_err(>pdev->dev, "SOFT reset failed\n");
ret = -ENODEV;
goto out;
-   }
+   } else
+   dev_info(>pdev->dev, "SOFT reset succeded\n");
}
 
 set_startup:
-- 
2.7.4



[PATCH V2 11/19] aacraid: Add periodic checks to see IOP reset status

2017-05-10 Thread Raghava Aditya Renukunta
Added function that waits with a timeout for the ctrl to be up and running
after triggering an IOP reset. Also removed 30 sec sleep as it is not
needed.

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/aacraid.h |  1 +
 drivers/scsi/aacraid/src.c | 45 --
 2 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 993f134..829f3d8 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -2519,6 +2519,7 @@ struct aac_hba_info {
 
 #defineSELF_TEST_FAILED0x0004
 #defineMONITOR_PANIC   0x0020
+#defineKERNEL_BOOTING  0x0040
 #defineKERNEL_UP_AND_RUNNING   0x0080
 #defineKERNEL_PANIC0x0100
 #defineFLASH_UPD_PENDING   0x2000
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index e8e9178..67185eb 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -694,6 +694,37 @@ static void aac_dump_fw_fib_iop_reset(struct aac_dev *dev)
0, 0, 0,  0, 0, 0, NULL, NULL, NULL, NULL, NULL);
 }
 
+static bool aac_is_ctrl_up_and_running(struct aac_dev *dev)
+{
+   bool ctrl_up = true;
+   unsigned long status, start;
+   bool is_up = false;
+
+   start = jiffies;
+   do {
+   schedule();
+   status = src_readl(dev, MUnit.OMR);
+
+   if (status == 0x)
+   status = 0;
+
+   if (status & KERNEL_BOOTING) {
+   start = jiffies;
+   continue;
+   }
+
+   if (time_after(jiffies, start+HZ*SOFT_RESET_TIME)) {
+   ctrl_up = false;
+   break;
+   }
+
+   is_up = status & KERNEL_UP_AND_RUNNING;
+
+   } while (!is_up);
+
+   return ctrl_up;
+}
+
 static void aac_notify_fw_of_iop_reset(struct aac_dev *dev)
 {
aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, 0, 0, 0, 0, 0, 0, NULL,
@@ -709,8 +740,6 @@ static void aac_send_iop_reset(struct aac_dev *dev)
aac_set_intx_mode(dev);
 
src_writel(dev, MUnit.IDR, IOP_SRC_RESET_MASK);
-
-   msleep(3);
 }
 
 static void aac_send_hardware_soft_reset(struct aac_dev *dev)
@@ -726,6 +755,7 @@ static void aac_send_hardware_soft_reset(struct aac_dev 
*dev)
 static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 
reset_type)
 {
unsigned long status, start;
+   bool is_ctrl_up;
 
if (bled < 0)
goto invalid_out;
@@ -745,6 +775,16 @@ static int aac_src_restart_adapter(struct aac_dev *dev, 
int bled, u8 reset_type)
switch (reset_type) {
case IOP_HWSOFT_RESET:
aac_send_iop_reset(dev);
+
+   /*
+* Creates a delay or wait till up and running comes thru
+*/
+   is_ctrl_up = aac_is_ctrl_up_and_running(dev);
+   if (!is_ctrl_up)
+   dev_err(>pdev->dev, "IOP reset failed\n");
+   else
+   goto set_startup;
+
/*
 * Check to see if KERNEL_UP_AND_RUNNING
 * Wait for the adapter to be up and running.
@@ -780,6 +820,7 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int 
bled, u8 reset_type)
if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
return -ENODEV;
 
+set_startup:
if (startup_timeout < 300)
startup_timeout = 300;
 
-- 
2.7.4



[PATCH V2 09/19] aacraid: Using single reset mask for IOP reset

2017-05-10 Thread Raghava Aditya Renukunta
The driver can now trigger IOP reset with a single reset mask. Removed
code that retrieves a reset_mask from the firmware.

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/aacraid.h |  5 -
 drivers/scsi/aacraid/src.c | 16 ++--
 2 files changed, 6 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 3ede6de..993f134 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -2381,6 +2381,7 @@ struct revision
 #define SOFT_RESET_TIME60
 
 
+
 struct aac_common
 {
/*
@@ -2491,7 +2492,9 @@ struct aac_hba_info {
 #define IOP_RESET_FW_FIB_DUMP  0x0034
 #define IOP_RESET  0x1000
 #define IOP_RESET_ALWAYS   0x1001
-#define RE_INIT_ADAPTER0x00ee
+#define RE_INIT_ADAPTER0x00ee
+
+#define IOP_SRC_RESET_MASK 0x0100
 
 /*
  * Adapter Status Register
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 2e5338d..c0e5242 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -704,22 +704,10 @@ static void aac_send_iop_reset(struct aac_dev *dev, int 
bled)
0, 0, 0, 0, 0, 0, ,
_mask, NULL, NULL, NULL);
 
-   if ((bled || var != 0x0001) && !dev->doorbell_mask)
-   bled = -EINVAL;
-   else if (dev->doorbell_mask) {
-   reset_mask = dev->doorbell_mask;
-   bled = 0;
-   var = 0x0001;
-   }
-
aac_set_intx_mode(dev);
 
-   if (!bled && (dev->supplement_adapter_info.supported_options2 &
-   AAC_OPTION_DOORBELL_RESET)) {
-   src_writel(dev, MUnit.IDR, reset_mask);
-   } else {
-   src_writel(dev, MUnit.IDR, 0x100);
-   }
+   src_writel(dev, MUnit.IDR, IOP_SRC_RESET_MASK);
+
msleep(3);
 }
 
-- 
2.7.4



[PATCH V2 18/19] aacraid: Remove reference to Series-9

2017-05-10 Thread Raghava Aditya Renukunta
Remove reference to Series-9 HBA and created arc ctrl check function.

Signed-off-by: Prasad B Munirathnam 
Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/aacraid.h  | 13 -
 drivers/scsi/aacraid/comminit.c | 18 --
 drivers/scsi/aacraid/commsup.c  |  5 +
 drivers/scsi/aacraid/linit.c|  9 ++---
 4 files changed, 19 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 829f3d8..58ccd2a 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -424,7 +424,6 @@ struct aac_ciss_identify_pd {
 #define PMC_DEVICE_S6  0x28b
 #define PMC_DEVICE_S7  0x28c
 #define PMC_DEVICE_S8  0x28d
-#define PMC_DEVICE_S9  0x28f
 
 #define aac_phys_to_logical(x)  ((x)+1)
 #define aac_logical_to_phys(x)  ((x)?(x)-1:0)
@@ -2684,6 +2683,18 @@ int aac_probe_container(struct aac_dev *dev, int cid);
 int _aac_rx_init(struct aac_dev *dev);
 int aac_rx_select_comm(struct aac_dev *dev, int comm);
 int aac_rx_deliver_producer(struct fib * fib);
+
+static inline int aac_is_src(struct aac_dev *dev)
+{
+   u16 device = dev->pdev->device;
+
+   if (device == PMC_DEVICE_S6 ||
+   device == PMC_DEVICE_S7 ||
+   device == PMC_DEVICE_S8)
+   return 1;
+   return 0;
+}
+
 char * get_container_type(unsigned type);
 extern int numacb;
 extern char aac_driver_version[];
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 1151505..9ee025b 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -53,11 +53,8 @@ static inline int aac_is_msix_mode(struct aac_dev *dev)
 {
u32 status = 0;
 
-   if (dev->pdev->device == PMC_DEVICE_S6 ||
-   dev->pdev->device == PMC_DEVICE_S7 ||
-   dev->pdev->device == PMC_DEVICE_S8) {
+   if (aac_is_src(dev))
status = src_readl(dev, MUnit.OMR);
-   }
return (status & AAC_INT_MODE_MSIX);
 }
 
@@ -325,9 +322,7 @@ int aac_send_shutdown(struct aac_dev * dev)
/* FIB should be freed only after getting the response from the F/W */
if (status != -ERESTARTSYS)
aac_fib_free(fibctx);
-   if ((dev->pdev->device == PMC_DEVICE_S7 ||
-dev->pdev->device == PMC_DEVICE_S8 ||
-dev->pdev->device == PMC_DEVICE_S9) &&
+   if (aac_is_src(dev) &&
 dev->msi_enabled)
aac_set_intx_mode(dev);
return status;
@@ -583,9 +578,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
dev->max_fib_size = status[1] & 0xFFE0;
host->sg_tablesize = status[2] >> 16;
dev->sg_tablesize = status[2] & 0x;
-   if (dev->pdev->device == PMC_DEVICE_S7 ||
-   dev->pdev->device == PMC_DEVICE_S8 ||
-   dev->pdev->device == PMC_DEVICE_S9) {
+   if (aac_is_src(dev)) {
if (host->can_queue > (status[3] >> 16) -
AAC_NUM_MGT_FIB)
host->can_queue = (status[3] >> 16) -
@@ -604,10 +597,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
pr_warn("numacb=%d ignored\n", numacb);
}
 
-   if (dev->pdev->device == PMC_DEVICE_S6 ||
-   dev->pdev->device == PMC_DEVICE_S7 ||
-   dev->pdev->device == PMC_DEVICE_S8 ||
-   dev->pdev->device == PMC_DEVICE_S9)
+   if (aac_is_src(dev))
aac_define_int_mode(dev);
/*
 *  Ok now init the communication subsystem
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 7bb0253..1a262c5 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -2592,10 +2592,7 @@ void aac_free_irq(struct aac_dev *dev)
int cpu;
 
cpu = cpumask_first(cpu_online_mask);
-   if (dev->pdev->device == PMC_DEVICE_S6 ||
-   dev->pdev->device == PMC_DEVICE_S7 ||
-   dev->pdev->device == PMC_DEVICE_S8 ||
-   dev->pdev->device == PMC_DEVICE_S9) {
+   if (aac_is_src(dev)) {
if (dev->max_msix > 1) {
for (i = 0; i < dev->max_msix; i++)
free_irq(pci_irq_vector(dev->pdev, i),
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index d933d2f..0f277df 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1416,10 +1416,7 @@ static void __aac_shutdown(struct aac_dev * aac)
kthread_stop(aac->thread);
}
aac_adapter_disable_int(aac);
-   if (aac->pdev->device == PMC_DEVICE_S6 ||
-   aac->pdev->device == PMC_DEVICE_S7 ||
-   aac->pdev->device == 

[PATCH V2 12/19] aacraid: Rework SOFT reset code

2017-05-10 Thread Raghava Aditya Renukunta
Now the driver issues a soft reset and waits for the controller to be up
and running by periodically checking on the status of the controller
health registers. Also prevents ARC adapters from issuing soft reset if
IOP resets failed.

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/src.c | 38 ++
 1 file changed, 18 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 67185eb..8ed7be0 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -754,8 +754,8 @@ static void aac_send_hardware_soft_reset(struct aac_dev 
*dev)
 
 static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 
reset_type)
 {
-   unsigned long status, start;
bool is_ctrl_up;
+   int ret = 0;
 
if (bled < 0)
goto invalid_out;
@@ -785,24 +785,21 @@ static int aac_src_restart_adapter(struct aac_dev *dev, 
int bled, u8 reset_type)
else
goto set_startup;
 
-   /*
-* Check to see if KERNEL_UP_AND_RUNNING
-* Wait for the adapter to be up and running.
-* If !KERNEL_UP_AND_RUNNING issue HW Soft Reset
-*/
-   status = src_readl(dev, MUnit.OMR);
-   if (dev->sa_firmware
-&& !(status & KERNEL_UP_AND_RUNNING)) {
-   start = jiffies;
-   do {
-   status = src_readl(dev, MUnit.OMR);
-   if (time_after(jiffies,
-start+HZ*SOFT_RESET_TIME)) {
-   aac_send_hardware_soft_reset(dev);
-   start = jiffies;
-   }
-   } while (!(status & KERNEL_UP_AND_RUNNING));
+   if (!dev->sa_firmware) {
+   ret = -ENODEV;
+   goto out;
}
+
+   aac_send_hardware_soft_reset(dev);
+   dev->msi_enabled = 0;
+
+   is_ctrl_up = aac_is_ctrl_up_and_running(dev);
+   if (!is_ctrl_up) {
+   dev_err(>pdev->dev, "SOFT reset failed\n");
+   ret = -ENODEV;
+   goto out;
+   }
+
break;
case HW_SOFT_RESET:
if (dev->sa_firmware) {
@@ -818,13 +815,14 @@ static int aac_src_restart_adapter(struct aac_dev *dev, 
int bled, u8 reset_type)
 invalid_out:
 
if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
-   return -ENODEV;
+   ret = -ENODEV;
 
 set_startup:
if (startup_timeout < 300)
startup_timeout = 300;
 
-   return 0;
+out:
+   return ret;
 }
 
 /**
-- 
2.7.4



[PATCH V2 16/19] aacraid: Enable ctrl reset for both hba and arc

2017-05-10 Thread Raghava Aditya Renukunta
Make sure that IOP and SOFT reset are enabled for both for both
arc and hba1000 controllers.

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/linit.c | 77 +++-
 1 file changed, 40 insertions(+), 37 deletions(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 3dea438..d933d2f 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -828,6 +828,11 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
u32 bus, cid;
int ret = FAILED;
int status = 0;
+   __le32 supported_options2 = 0;
+   bool is_mu_reset;
+   bool is_ignore_reset;
+   bool is_doorbell_reset;
+
 
bus = aac_logical_to_phys(scmd_channel(cmd));
cid = scmd_id(cmd);
@@ -900,9 +905,9 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
msleep(1000);
}
 
-   if (ret != SUCCESS)
-   pr_err("%s: Host adapter reset request timed out\n",
-   AAC_DRIVERNAME);
+   if (ret == SUCCESS)
+   goto out;
+
} else {
 
/* Mark the assoc. FIB to not complete, eh handler does this */
@@ -918,44 +923,42 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
}
}
+   }
 
-   pr_err("%s: Host adapter reset request. SCSI hang ?\n",
-   AAC_DRIVERNAME);
+   pr_err("%s: Host adapter reset request. SCSI hang ?\n", AAC_DRIVERNAME);
+
+   /*
+* Check the health of the controller
+*/
+   status = aac_adapter_check_health(aac);
+   if (status)
+   dev_err(>pdev->dev, "Adapter health - %d\n", status);
+
+   count = get_num_of_incomplete_fibs(aac);
+   if (count == 0)
+   return SUCCESS;
 
-   /*
-* Check the health of the controller
-*/
-   status = aac_adapter_check_health(aac);
-   if (status)
-   dev_err(>pdev->dev, "Adapter health - %d\n",
-   status);
-
-   count = get_num_of_incomplete_fibs(aac);
-   if (count == 0)
-   return SUCCESS;
-
-   /*
-* This adapter needs a blind reset, only do so for
-* Adapters that support a register, instead of a commanded,
-* reset.
-*/
-   if (((aac->supplement_adapter_info.supported_options2 &
- AAC_OPTION_MU_RESET) ||
- (aac->supplement_adapter_info.supported_options2 &
- AAC_OPTION_DOORBELL_RESET)) &&
- aac_check_reset &&
- ((aac_check_reset != 1) ||
-  !(aac->supplement_adapter_info.supported_options2 &
-   AAC_OPTION_IGNORE_RESET))) {
-   /* Bypass wait for command quiesce */
-   aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET);
-   }
-   ret = SUCCESS;
-   }
/*
-* Cause an immediate retry of the command with a ten second delay
-* after successful tur
+* Check if reset is supported by the firmware
 */
+   supported_options2 = aac->supplement_adapter_info.supported_options2;
+   is_mu_reset = supported_options2 & AAC_OPTION_MU_RESET;
+   is_doorbell_reset = supported_options2 & AAC_OPTION_DOORBELL_RESET;
+   is_ignore_reset = supported_options2 & AAC_OPTION_IGNORE_RESET;
+   /*
+* This adapter needs a blind reset, only do so for
+* Adapters that support a register, instead of a commanded,
+* reset.
+*/
+   if ((is_mu_reset || is_doorbell_reset)
+&& aac_check_reset
+&& (aac_check_reset != -1 || !is_ignore_reset)) {
+   /* Bypass wait for command quiesce */
+   aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET);
+   }
+   ret = SUCCESS;
+
+out:
return ret;
 }
 
-- 
2.7.4



[PATCH V2 15/19] aacraid: Make sure ioctl returns on controller reset

2017-05-10 Thread Raghava Aditya Renukunta
Made sure that ioctl commands return in case of a controller reset.

Signed-off-by: Raghava Aditya Renukunta 

---
Changes in V2:
Removed incorrect up
Cleared wait flag once event is received not before

 drivers/scsi/aacraid/commsup.c | 25 ++---
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index f26543a..7bb0253 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -803,11 +803,11 @@ int aac_hba_send(u8 command, struct fib *fibptr, 
fib_callback callback,
if (aac_check_eeh_failure(dev))
return -EFAULT;
 
-   /* Only set for first known interruptable command */
-   if (down_interruptible(>event_wait)) {
+   fibptr->flags |= FIB_CONTEXT_FLAG_WAIT;
+   if (down_interruptible(>event_wait))
fibptr->done = 2;
-   up(>event_wait);
-   }
+   fibptr->flags &= ~(FIB_CONTEXT_FLAG_WAIT);
+
spin_lock_irqsave(>event_lock, flags);
if ((fibptr->done == 0) || (fibptr->done == 2)) {
fibptr->done = 2; /* Tell interrupt we aborted */
@@ -1514,6 +1514,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int 
forced, u8 reset_type)
int jafo = 0;
int bled;
u64 dmamask;
+   int num_of_fibs = 0;
 
/*
 * Assumptions:
@@ -1547,10 +1548,20 @@ static int _aac_reset_adapter(struct aac_dev *aac, int 
forced, u8 reset_type)
/*
 *  Loop through the fibs, close the synchronous FIBS
 */
-   for (retval = 1, index = 0; index < (aac->scsi_host_ptr->can_queue + 
AAC_NUM_MGT_FIB); index++) {
+   retval = 1;
+   num_of_fibs = aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB;
+   for (index = 0; index <  num_of_fibs; index++) {
+
struct fib *fib = >fibs[index];
-   if (!(fib->hw_fib_va->header.XferState & 
cpu_to_le32(NoResponseExpected | Async)) &&
- (fib->hw_fib_va->header.XferState & 
cpu_to_le32(ResponseExpected))) {
+   __le32 XferState = fib->hw_fib_va->header.XferState;
+   bool is_response_expected = false;
+
+   if (!(XferState & cpu_to_le32(NoResponseExpected | Async)) &&
+  (XferState & cpu_to_le32(ResponseExpected)))
+   is_response_expected = true;
+
+   if (is_response_expected
+ || fib->flags & FIB_CONTEXT_FLAG_WAIT) {
unsigned long flagv;
spin_lock_irqsave(>event_lock, flagv);
up(>event_wait);
-- 
2.7.4



[PATCH V2 07/19] aacraid: Log count info of scsi cmds before reset

2017-05-10 Thread Raghava Aditya Renukunta
Log the location of the scsi cmds before triggering a reset. This
information is useful for debugging.

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/linit.c | 90 ++--
 1 file changed, 53 insertions(+), 37 deletions(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index f6a11af..0a8d303 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -624,6 +624,56 @@ static int aac_ioctl(struct scsi_device *sdev, int cmd, 
void __user * arg)
return aac_do_ioctl(dev, cmd, arg);
 }
 
+static int get_num_of_incomplete_fibs(struct aac_dev *aac)
+{
+
+   unsigned long flags;
+   struct scsi_device *sdev = NULL;
+   struct Scsi_Host *shost = aac->scsi_host_ptr;
+   struct scsi_cmnd *scmnd = NULL;
+   struct device *ctrl_dev;
+
+   int mlcnt  = 0;
+   int llcnt  = 0;
+   int ehcnt  = 0;
+   int fwcnt  = 0;
+   int krlcnt = 0;
+
+   __shost_for_each_device(sdev, shost) {
+   spin_lock_irqsave(>list_lock, flags);
+   list_for_each_entry(scmnd, >cmd_list, list) {
+   switch (scmnd->SCp.phase) {
+   case AAC_OWNER_FIRMWARE:
+   fwcnt++;
+   break;
+   case AAC_OWNER_ERROR_HANDLER:
+   ehcnt++;
+   break;
+   case AAC_OWNER_LOWLEVEL:
+   llcnt++;
+   break;
+   case AAC_OWNER_MIDLEVEL:
+   mlcnt++;
+   break;
+   default:
+   krlcnt++;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(>list_lock, flags);
+   }
+
+   ctrl_dev = >pdev->dev;
+
+   dev_info(ctrl_dev, "outstanding cmd: midlevel-%d\n", mlcnt);
+   dev_info(ctrl_dev, "outstanding cmd: lowlevel-%d\n", llcnt);
+   dev_info(ctrl_dev, "outstanding cmd: error handler-%d\n", ehcnt);
+   dev_info(ctrl_dev, "outstanding cmd: firmware-%d\n", fwcnt);
+   dev_info(ctrl_dev, "outstanding cmd: kernel-%d\n", krlcnt);
+
+   return mlcnt + llcnt + ehcnt + fwcnt;
+}
+
 static int aac_eh_abort(struct scsi_cmnd* cmd)
 {
struct scsi_device * dev = cmd->device;
@@ -853,8 +903,6 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
pr_err("%s: Host adapter reset request timed out\n",
AAC_DRIVERNAME);
} else {
-   struct scsi_cmnd *command;
-   unsigned long flags;
 
/* Mark the assoc. FIB to not complete, eh handler does this */
for (count = 0;
@@ -873,41 +921,9 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
pr_err("%s: Host adapter reset request. SCSI hang ?\n",
AAC_DRIVERNAME);
 
-   count = aac_check_health(aac);
-   if (count)
-   return count;
-   /*
-* Wait for all commands to complete to this specific
-* target (block maximum 60 seconds).
-*/
-   for (count = 60; count; --count) {
-   int active = aac->in_reset;
-
-   if (active == 0)
-   __shost_for_each_device(dev, host) {
-   spin_lock_irqsave(>list_lock, flags);
-   list_for_each_entry(command, >cmd_list,
-   list) {
-   if ((command != cmd) &&
-   (command->SCp.phase ==
-   AAC_OWNER_FIRMWARE)) {
-   active++;
-   break;
-   }
-   }
-   spin_unlock_irqrestore(>list_lock, flags);
-   if (active)
-   break;
-
-   }
-   /*
-* We can exit If all the commands are complete
-*/
-   if (active == 0)
-   return SUCCESS;
-   ssleep(1);
-   }
-   pr_err("%s: SCSI bus appears hung\n", AAC_DRIVERNAME);
+   count = get_num_of_incomplete_fibs(aac);
+   if (count == 0)
+   return SUCCESS;
 
/*
 * This adapter needs a blind reset, only do so 

[PATCH V2 13/19] aacraid: Rework aac_src_restart

2017-05-10 Thread Raghava Aditya Renukunta
Removed switch case and replaced with if mask checks. Moved KERNEL_PANIC
check to when bled is less than 0.

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/src.c | 34 --
 1 file changed, 12 insertions(+), 22 deletions(-)

diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 8ed7be0..10a589b 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -772,8 +772,7 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int 
bled, u8 reset_type)
 
dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
 
-   switch (reset_type) {
-   case IOP_HWSOFT_RESET:
+   if (reset_type & HW_IOP_RESET) {
aac_send_iop_reset(dev);
 
/*
@@ -784,12 +783,14 @@ static int aac_src_restart_adapter(struct aac_dev *dev, 
int bled, u8 reset_type)
dev_err(>pdev->dev, "IOP reset failed\n");
else
goto set_startup;
+   }
 
-   if (!dev->sa_firmware) {
-   ret = -ENODEV;
-   goto out;
-   }
+   if (!dev->sa_firmware) {
+   ret = -ENODEV;
+   goto out;
+   }
 
+   if (reset_type & HW_SOFT_RESET) {
aac_send_hardware_soft_reset(dev);
dev->msi_enabled = 0;
 
@@ -799,30 +800,19 @@ static int aac_src_restart_adapter(struct aac_dev *dev, 
int bled, u8 reset_type)
ret = -ENODEV;
goto out;
}
-
-   break;
-   case HW_SOFT_RESET:
-   if (dev->sa_firmware) {
-   aac_send_hardware_soft_reset(dev);
-   aac_set_intx_mode(dev);
-   }
-   break;
-   default:
-   aac_send_iop_reset(dev);
-   break;
}
 
-invalid_out:
-
-   if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
-   ret = -ENODEV;
-
 set_startup:
if (startup_timeout < 300)
startup_timeout = 300;
 
 out:
return ret;
+
+invalid_out:
+   if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
+   ret = -ENODEV;
+goto out;
 }
 
 /**
-- 
2.7.4



[PATCH V2 10/19] aacraid: Rework IOP reset

2017-05-10 Thread Raghava Aditya Renukunta
Reworked IOP reset to remove unneeded variable and created a helper
function to notify fw of an imminent IOP reset.

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/src.c | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index c0e5242..e8e9178 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -694,15 +694,17 @@ static void aac_dump_fw_fib_iop_reset(struct aac_dev *dev)
0, 0, 0,  0, 0, 0, NULL, NULL, NULL, NULL, NULL);
 }
 
-static void aac_send_iop_reset(struct aac_dev *dev, int bled)
+static void aac_notify_fw_of_iop_reset(struct aac_dev *dev)
 {
-   u32 var, reset_mask;
+   aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, 0, 0, 0, 0, 0, 0, NULL,
+   NULL, NULL, NULL, NULL);
+}
 
+static void aac_send_iop_reset(struct aac_dev *dev)
+{
aac_dump_fw_fib_iop_reset(dev);
 
-   bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
-   0, 0, 0, 0, 0, 0, ,
-   _mask, NULL, NULL, NULL);
+   aac_notify_fw_of_iop_reset(dev);
 
aac_set_intx_mode(dev);
 
@@ -742,7 +744,7 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int 
bled, u8 reset_type)
 
switch (reset_type) {
case IOP_HWSOFT_RESET:
-   aac_send_iop_reset(dev, bled);
+   aac_send_iop_reset(dev);
/*
 * Check to see if KERNEL_UP_AND_RUNNING
 * Wait for the adapter to be up and running.
@@ -769,7 +771,7 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int 
bled, u8 reset_type)
}
break;
default:
-   aac_send_iop_reset(dev, bled);
+   aac_send_iop_reset(dev);
break;
}
 
-- 
2.7.4



[PATCH V2 14/19] aacraid: Use correct function to get ctrl health

2017-05-10 Thread Raghava Aditya Renukunta
The command thread checks the ctrl health periodically before sending
updates to the controller. The function that it uses is aac_check_health
which does more than get the health status.

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/commsup.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 3299012..f26543a 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -2476,7 +2476,7 @@ int aac_command_thread(void *data)
if ((time_before(next_check_jiffies,next_jiffies))
 && ((difference = next_check_jiffies - jiffies) <= 0)) {
next_check_jiffies = next_jiffies;
-   if (aac_check_health(dev) == 0) {
+   if (aac_adapter_check_health(dev) == 0) {
difference = ((long)(unsigned)check_interval)
   * HZ;
next_check_jiffies = jiffies + difference;
@@ -2489,7 +2489,7 @@ int aac_command_thread(void *data)
int ret;
 
/* Don't even try to talk to adapter if its sick */
-   ret = aac_check_health(dev);
+   ret = aac_adapter_check_health(dev);
if (ret || !dev->queues)
break;
next_check_jiffies = jiffies
-- 
2.7.4



[PATCH V2 19/19] aacraid: Update driver version to 50834

2017-05-10 Thread Raghava Aditya Renukunta
Update the driver version to 50834

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/aacraid.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 58ccd2a..0995265 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -97,7 +97,7 @@ enum {
 #definePMC_GLOBAL_INT_BIT0 0x0001
 
 #ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 50792
+# define AAC_DRIVER_BUILD 50834
 # define AAC_DRIVER_BRANCH "-custom"
 #endif
 #define MAXIMUM_NUM_CONTAINERS 32
-- 
2.7.4



[PATCH V2 08/19] aacraid: Print ctrl status before eh reset

2017-05-10 Thread Raghava Aditya Renukunta
Log the status of the controller before issuing a reset.

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/linit.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 0a8d303..3dea438 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -827,6 +827,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
int count;
u32 bus, cid;
int ret = FAILED;
+   int status = 0;
 
bus = aac_logical_to_phys(scmd_channel(cmd));
cid = scmd_id(cmd);
@@ -921,6 +922,14 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
pr_err("%s: Host adapter reset request. SCSI hang ?\n",
AAC_DRIVERNAME);
 
+   /*
+* Check the health of the controller
+*/
+   status = aac_adapter_check_health(aac);
+   if (status)
+   dev_err(>pdev->dev, "Adapter health - %d\n",
+   status);
+
count = get_num_of_incomplete_fibs(aac);
if (count == 0)
return SUCCESS;
-- 
2.7.4



[PATCH V2 02/19] aacraid: Fix DMAR issues with iommu=pt

2017-05-10 Thread Raghava Aditya Renukunta
The driver changed the DMA consistent map after consistent memory was
allocated, this invalidated the IOMMU identity mapping. The fix was to
make sure that we set the DMA consistent mask setting once depending on
the controller card.

Signed-off-by: Raghava Aditya Renukunta 

---
Changes in V2:
None

 drivers/scsi/aacraid/aachba.c  | 17 ++---
 drivers/scsi/aacraid/commsup.c | 29 ++---
 drivers/scsi/aacraid/linit.c   | 32 +++-
 3 files changed, 43 insertions(+), 35 deletions(-)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 43d8838..707ee2f 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -2071,20 +2071,15 @@ int aac_get_adapter_info(struct aac_dev* dev)
expose_physicals = 0;
}
 
-   if(dev->dac_support != 0) {
-   if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(64)) &&
-   !pci_set_consistent_dma_mask(dev->pdev, 
DMA_BIT_MASK(64))) {
+   if (dev->dac_support) {
+   if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(64))) {
if (!dev->in_reset)
-   printk(KERN_INFO"%s%d: 64 Bit DAC enabled\n",
-   dev->name, dev->id);
-   } else if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(32)) &&
-   !pci_set_consistent_dma_mask(dev->pdev, 
DMA_BIT_MASK(32))) {
-   printk(KERN_INFO"%s%d: DMA mask set failed, 64 Bit DAC 
disabled\n",
-   dev->name, dev->id);
+   dev_info(>pdev->dev, "64 Bit DAC 
enabled\n");
+   } else if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(32))) {
+   dev_info(>pdev->dev, "DMA mask set failed, 64 Bit 
DAC disabled\n");
dev->dac_support = 0;
} else {
-   printk(KERN_WARNING"%s%d: No suitable DMA available.\n",
-   dev->name, dev->id);
+   dev_info(>pdev->dev, "No suitable DMA 
available\n");
rcode = -ENOMEM;
}
}
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index d08920d..47068b2 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1513,6 +1513,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int 
forced, u8 reset_type)
struct scsi_cmnd *command_list;
int jafo = 0;
int bled;
+   u64 dmamask;
 
/*
 * Assumptions:
@@ -1580,21 +1581,27 @@ static int _aac_reset_adapter(struct aac_dev *aac, int 
forced, u8 reset_type)
aac_free_irq(aac);
kfree(aac->fsa_dev);
aac->fsa_dev = NULL;
+
+   dmamask = DMA_BIT_MASK(32);
quirks = aac_get_driver_ident(index)->quirks;
-   if (quirks & AAC_QUIRK_31BIT) {
-   if (((retval = pci_set_dma_mask(aac->pdev, DMA_BIT_MASK(31 
||
- ((retval = pci_set_consistent_dma_mask(aac->pdev, 
DMA_BIT_MASK(31)
-   goto out;
-   } else {
-   if (((retval = pci_set_dma_mask(aac->pdev, DMA_BIT_MASK(32 
||
- ((retval = pci_set_consistent_dma_mask(aac->pdev, 
DMA_BIT_MASK(32)
-   goto out;
+   if (quirks & AAC_QUIRK_31BIT)
+   retval = pci_set_dma_mask(aac->pdev, dmamask);
+   else if (!(quirks & AAC_QUIRK_SRC))
+   retval = pci_set_dma_mask(aac->pdev, dmamask);
+   else
+   retval = pci_set_consistent_dma_mask(aac->pdev, dmamask);
+
+   if (quirks & AAC_QUIRK_31BIT && !retval) {
+   dmamask = DMA_BIT_MASK(31);
+   retval = pci_set_consistent_dma_mask(aac->pdev, dmamask);
}
+
+   if (retval)
+   goto out;
+
if ((retval = (*(aac_get_driver_ident(index)->init))(aac)))
goto out;
-   if (quirks & AAC_QUIRK_31BIT)
-   if ((retval = pci_set_dma_mask(aac->pdev, DMA_BIT_MASK(32
-   goto out;
+
if (jafo) {
aac->thread = kthread_run(aac_command_thread, aac, "%s",
  aac->name);
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 372a075..5a201da 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1403,6 +1403,7 @@ static int aac_probe_one(struct pci_dev *pdev, const 
struct pci_device_id *id)
int error = -ENODEV;
int unique_id = 0;
u64 dmamask;
+   int mask_bits = 0;
extern int aac_sync_mode;
 
/*
@@ -1426,18 +1427,32 @@ static int aac_probe_one(struct pci_dev *pdev, const 
struct pci_device_id *id)
goto out;
error = -ENODEV;
 
+   if (!(aac_drivers[index].quirks & 

[PATCH V2 04/19] aacraid: Set correct Queue Depth for HBA1000 RAW disks

2017-05-10 Thread Raghava Aditya Renukunta
The default queue depth for non NATIVE RAW disks is calculated from the
number of fibs and number of disks or a max of 256. This causes poor disk
IO performance.

The fix is to set default qd based on the type of disks
(SATA -32 and SAS -64)

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

--
Changes in V2:
None
-
 drivers/scsi/aacraid/linit.c | 28 
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 5e1a2d6..9ef98e4 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -405,17 +405,23 @@ static int aac_slave_configure(struct scsi_device *sdev)
int chn, tid;
unsigned int depth = 0;
unsigned int set_timeout = 0;
+   bool set_qd_dev_type = false;
+   u8 devtype = 0;
 
chn = aac_logical_to_phys(sdev_channel(sdev));
tid = sdev_id(sdev);
-   if (chn < AAC_MAX_BUSES && tid < AAC_MAX_TARGETS &&
-   aac->hba_map[chn][tid].devtype == AAC_DEVTYPE_NATIVE_RAW) {
-   depth = aac->hba_map[chn][tid].qd_limit;
+   if (chn < AAC_MAX_BUSES && tid < AAC_MAX_TARGETS && aac->sa_firmware) {
+   devtype = aac->hba_map[chn][tid].devtype;
+
+   if (devtype == AAC_DEVTYPE_NATIVE_RAW)
+   depth = aac->hba_map[chn][tid].qd_limit;
+   else if (devtype == AAC_DEVTYPE_ARC_RAW)
+   set_qd_dev_type = true;
+
set_timeout = 1;
goto common_config;
}
 
-
if (aac->jbod && (sdev->type == TYPE_DISK))
sdev->removable = 1;
 
@@ -470,16 +476,22 @@ static int aac_slave_configure(struct scsi_device *sdev)
if (sdev_channel(sdev) != NATIVE_CHANNEL)
goto common_config;
 
-   /*
-* Check if SATA drive
-*/
+   set_qd_dev_type = true;
+
+   }
+
+common_config:
+
+   /*
+* Check if SATA drive
+*/
+   if (set_qd_dev_type) {
if (strncmp(sdev->vendor, "ATA", 3) == 0)
depth = 32;
else
depth = 64;
}
 
-common_config:
/*
 * Firmware has an individual device recovery time typically
 * of 35 seconds, give us a margin.
-- 
2.7.4



[PATCH V2 05/19] aacraid: Remove reset support from check_health

2017-05-10 Thread Raghava Aditya Renukunta
Check health does not need to reset the ctrl but just return the
controller health status.

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/commsup.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 47068b2..3299012 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1775,8 +1775,6 @@ int aac_check_health(struct aac_dev * aac)
int BlinkLED;
unsigned long time_now, flagv = 0;
struct list_head * entry;
-   struct Scsi_Host * host;
-   int bled;
 
/* Extending the scope of fib_lock slightly to protect aac->in_reset */
if (spin_trylock_irqsave(>fib_lock, flagv) == 0)
@@ -1887,19 +1885,6 @@ int aac_check_health(struct aac_dev * aac)
 
printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, 
BlinkLED);
 
-   if (!aac_check_reset || ((aac_check_reset == 1) &&
-   (aac->supplement_adapter_info.supported_options2 &
-   AAC_OPTION_IGNORE_RESET)))
-   goto out;
-   host = aac->scsi_host_ptr;
-   if (aac->thread->pid != current->pid)
-   spin_lock_irqsave(host->host_lock, flagv);
-   bled = aac_check_reset != 1 ? 1 : 0;
-   _aac_reset_adapter(aac, bled, IOP_HWSOFT_RESET);
-   if (aac->thread->pid != current->pid)
-   spin_unlock_irqrestore(host->host_lock, flagv);
-   return BlinkLED;
-
 out:
aac->in_reset = 0;
return BlinkLED;
-- 
2.7.4



[PATCH V2 03/19] aacraid: Added 32 and 64 queue depth for arc natives

2017-05-10 Thread Raghava Aditya Renukunta
The qd for ARC Native disks is calculated by dividing the max IO 1024
by the number of disks or 256 which ever is lower. This causes poor
disk IO performance.

The fix is set the qd based on the type of disk (SAS - 64 and SATA -
32).

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/aacraid.h |  1 +
 drivers/scsi/aacraid/linit.c   | 11 +++
 2 files changed, 12 insertions(+)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index d036a80..3ede6de 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -415,6 +415,7 @@ struct aac_ciss_identify_pd {
  * These macros convert from physical channels to virtual channels
  */
 #define CONTAINER_CHANNEL  (0)
+#define NATIVE_CHANNEL (1)
 #define CONTAINER_TO_CHANNEL(cont) (CONTAINER_CHANNEL)
 #define CONTAINER_TO_ID(cont)  (cont)
 #define CONTAINER_TO_LUN(cont) (0)
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 5a201da..5e1a2d6 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -466,6 +466,17 @@ static int aac_slave_configure(struct scsi_device *sdev)
++num_lsu;
 
depth = (host->can_queue - num_one) / num_lsu;
+
+   if (sdev_channel(sdev) != NATIVE_CHANNEL)
+   goto common_config;
+
+   /*
+* Check if SATA drive
+*/
+   if (strncmp(sdev->vendor, "ATA", 3) == 0)
+   depth = 32;
+   else
+   depth = 64;
}
 
 common_config:
-- 
2.7.4



[PATCH V2 06/19] aacraid: Change wait time for fib completion

2017-05-10 Thread Raghava Aditya Renukunta
Change the completion wait time for the fibs in the reset and abort
callback from 2 minutes to 15 seconds.

2 minutes is too long for waiting for completion.

Signed-off-by: Raghava Aditya Renukunta 
Reviewed-by: David Carroll 

---
Changes in V2:
None

 drivers/scsi/aacraid/linit.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 9ef98e4..f6a11af 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -684,8 +684,8 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
  (fib_callback) aac_hba_callback,
  (void *) cmd);
 
-   /* Wait up to 2 minutes for completion */
-   for (count = 0; count < 120; ++count) {
+   /* Wait up to 15 secs for completion */
+   for (count = 0; count < 15; ++count) {
if (cmd->SCp.sent_command) {
ret = SUCCESS;
break;
@@ -840,8 +840,8 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
  (fib_callback) aac_hba_callback,
  (void *) cmd);
 
-   /* Wait up to 2 minutes for completion */
-   for (count = 0; count < 120; ++count) {
+   /* Wait up to 15 seconds for completion */
+   for (count = 0; count < 15; ++count) {
if (cmd->SCp.sent_command) {
ret = SUCCESS;
break;
-- 
2.7.4



[PATCH V2 00/19] aacraid: Patchset with reset rework and misc fixes

2017-05-10 Thread Raghava Aditya Renukunta
This patchset primarily focuses on tweaking and hardening the controller
reset support for both ARC and HBA1000 devices. Now the driver can only
reset the controller thru eh reset. Included a srb memory fix and pci dma
allocation fix.

Changes in V2:
 - Corrected heading and description for srb memory patch and removed stray
   comment.
 - Removed incorrect up function call and cleared fib wait flag after call
   to down interruptible in the ioctl return on ctrl reset patch.
 - Added review acknowledgements by David Carroll thank you Dave for
   finding the above issues in the above 2 patches.

Raghava Aditya Renukunta (19):
 [SCSI] aacraid: Remove __GFP_DMA for raw srb memory
 [SCSI] aacraid: Fix DMAR issues with  iommu=pt
 [SCSI] aacraid: Added 32 and 64 queue depth for arc natives
 [SCSI] aacraid: Set correct Queue Depth for HBA1000 RAW disks
 [SCSI] aacraid: Remove reset support from check_health
 [SCSI] aacraid: Change wait time for fib completion
 [SCSI] aacraid: Log count info of scsi cmds before reset
 [SCSI] aacraid: Print ctrl status before eh reset
 [SCSI] aacraid: Using single reset mask for IOP reset
 [SCSI] aacraid: Rework IOP reset
 [SCSI] aacraid: Add periodic checks to see IOP reset status
 [SCSI] aacraid: Rework SOFT reset code
 [SCSI] aacraid: Rework aac_src_restart
 [SCSI] aacraid: Use correct function to get ctrl health
 [SCSI] aacraid: Make sure ioctl returns on controller reset
 [SCSI] aacraid: Enable ctrl reset for both hba and arc
 [SCSI] aacraid: Add reset debugging statements
 [SCSI] aacraid: Remove reference to Series-9
 [SCSI] aacraid: Update driver version to 50834

 drivers/scsi/aacraid/aachba.c   |  17 ++-
 drivers/scsi/aacraid/aacraid.h  |  22 +++-
 drivers/scsi/aacraid/commctrl.c |  15 ++-
 drivers/scsi/aacraid/comminit.c |  18 +---
 drivers/scsi/aacraid/commsup.c  |  78 +++---
 drivers/scsi/aacraid/linit.c| 232 
 drivers/scsi/aacraid/src.c  | 136 +--
 7 files changed, 298 insertions(+), 220 deletions(-)

-- 
2.7.4



[PATCH V2 01/19] aacraid: Remove __GFP_DMA for raw srb memory

2017-05-10 Thread Raghava Aditya Renukunta
The raw srb commands do not requires memory that in the ZONE_DMA
memory space. For 32bit srb commands use GFP_DMA32 to limit the memory
to 32bit memory range (4GB).

Signed-off-by: Raghava Aditya Renukunta 

---
Changes in V2:
Corrected flag name to GFP_DMA32 in patch description and corrected
GFP_DMA to __GFP_DMA in patch heading
Removed comment

 drivers/scsi/aacraid/commctrl.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index d2f8d59..106b933 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -668,7 +668,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void 
__user * arg)
goto cleanup;
}
 
-   p = kmalloc(sg_count[i], GFP_KERNEL|__GFP_DMA);
+   p = kmalloc(sg_count[i], GFP_KERNEL);
if (!p) {
rcode = -ENOMEM;
goto cleanup;
@@ -732,8 +732,8 @@ static int aac_send_raw_srb(struct aac_dev* dev, void 
__user * arg)
rcode = -EINVAL;
goto cleanup;
}
-   /* Does this really need to be GFP_DMA? */
-   p = kmalloc(sg_count[i], GFP_KERNEL|__GFP_DMA);
+
+   p = kmalloc(sg_count[i], GFP_KERNEL);
if(!p) {
dprintk((KERN_DEBUG"aacraid: Could not 
allocate SG buffer - size = %d buffer number %d of %d\n",
  sg_count[i], i, upsg->count));
@@ -788,8 +788,8 @@ static int aac_send_raw_srb(struct aac_dev* dev, void 
__user * arg)
rcode = -EINVAL;
goto cleanup;
}
-   /* Does this really need to be GFP_DMA? */
-   p = kmalloc(sg_count[i], GFP_KERNEL|__GFP_DMA);
+
+   p = kmalloc(sg_count[i], GFP_KERNEL);
if(!p) {
dprintk((KERN_DEBUG "aacraid: Could not 
allocate SG buffer - size = %d buffer number %d of %d\n",
sg_count[i], i, usg->count));
@@ -845,8 +845,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void 
__user * arg)
rcode = -EINVAL;
goto cleanup;
}
-   /* Does this really need to be GFP_DMA? */
-   p = kmalloc(sg_count[i], GFP_KERNEL|__GFP_DMA);
+   p = kmalloc(sg_count[i], GFP_KERNEL|GFP_DMA32);
if (!p) {
dprintk((KERN_DEBUG"aacraid: Could not 
allocate SG buffer - size = %d buffer number %d of %d\n",
sg_count[i], i, usg->count));
@@ -887,7 +886,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void 
__user * arg)
rcode = -EINVAL;
goto cleanup;
}
-   p = kmalloc(sg_count[i], GFP_KERNEL);
+   p = kmalloc(sg_count[i], GFP_KERNEL|GFP_DMA32);
if (!p) {
dprintk((KERN_DEBUG"aacraid: Could not 
allocate SG buffer - size = %d buffer number %d of %d\n",
  sg_count[i], i, upsg->count));
-- 
2.7.4