[PATCH v2 7/7] qla2xxx: Fix crash due to NULL pointer dereference of ctx.

2017-05-24 Thread Himanshu Madhani
From: Joe Carnuccio <joe.carnuc...@cavium.com>

Fixes following signature in the stack trace:

BUG: unable to handle kernel NULL pointer dereference at 0374
IP: [] qla2x00_sp_free_dma+0xeb/0x2a0 [qla2xxx]

Cc: <sta...@vger.kernel.org> # 4.10
Signed-off-by: Joe Carnuccio <joe.carnuc...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_inline.h | 26 +++---
 drivers/scsi/qla2xxx/qla_os.c | 30 +++---
 drivers/scsi/qla2xxx/qla_target.c |  8 +---
 3 files changed, 31 insertions(+), 33 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index 66df6cec59da..c61a6a871c8e 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -129,28 +129,16 @@ qla2x00_clear_loop_id(fc_port_t *fcport) {
 }
 
 static inline void
-qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp,
-   struct qla_tgt_cmd *tc)
+qla2x00_clean_dsd_pool(struct qla_hw_data *ha, struct crc_context *ctx)
 {
-   struct dsd_dma *dsd_ptr, *tdsd_ptr;
-   struct crc_context *ctx;
-
-   if (sp)
-   ctx = (struct crc_context *)GET_CMD_CTX_SP(sp);
-   else if (tc)
-   ctx = (struct crc_context *)tc->ctx;
-   else {
-   BUG();
-   return;
-   }
+   struct dsd_dma *dsd, *tdsd;
 
/* clean up allocated prev pool */
-   list_for_each_entry_safe(dsd_ptr, tdsd_ptr,
-   >dsd_list, list) {
-   dma_pool_free(ha->dl_dma_pool, dsd_ptr->dsd_addr,
-   dsd_ptr->dsd_list_dma);
-   list_del(_ptr->list);
-   kfree(dsd_ptr);
+   list_for_each_entry_safe(dsd, tdsd, >dsd_list, list) {
+   dma_pool_free(ha->dl_dma_pool, dsd->dsd_addr,
+   dsd->dsd_list_dma);
+   list_del(>list);
+   kfree(dsd);
}
INIT_LIST_HEAD(>dsd_list);
 }
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 1c7957903283..c8282a1ab6dc 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -630,29 +630,34 @@ qla2x00_sp_free_dma(void *ptr)
sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
}
 
+   if (!ctx)
+   goto end;
+
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
/* List assured to be having elements */
-   qla2x00_clean_dsd_pool(ha, sp, NULL);
+   qla2x00_clean_dsd_pool(ha, ctx);
sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
}
 
if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
-   dma_pool_free(ha->dl_dma_pool, ctx,
-   ((struct crc_context *)ctx)->crc_ctx_dma);
+   struct crc_context *ctx0 = ctx;
+
+   dma_pool_free(ha->dl_dma_pool, ctx0, ctx0->crc_ctx_dma);
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
}
 
if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
-   struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx;
+   struct ct6_dsd *ctx1 = ctx;
 
dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
-   ctx1->fcp_cmnd_dma);
+   ctx1->fcp_cmnd_dma);
list_splice(>dsd_list, >gbl_dsd_list);
ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt;
ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
mempool_free(ctx1, ha->ctx_mempool);
}
 
+end:
CMD_SP(cmd) = NULL;
qla2x00_rel_sp(sp);
 }
@@ -699,21 +704,24 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
}
 
+   if (!ctx)
+   goto end;
+
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
/* List assured to be having elements */
-   qla2x00_clean_dsd_pool(ha, sp, NULL);
+   qla2x00_clean_dsd_pool(ha, ctx);
sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
}
 
if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
-   dma_pool_free(ha->dl_dma_pool, ctx,
-   ((struct crc_context *)ctx)->crc_ctx_dma);
+   struct crc_context *ctx0 = ctx;
+
+   dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma);
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
}
 
if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
-   struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx;
-
+   struct ct6_dsd *ctx1 = ctx;
dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
ctx1->fcp_cmnd_dma);
list_splice(>dsd_list, >gbl_dsd_list);
@@ -721,7 +729,7 @@ qla2xxx_qpair_sp_free_dma(void *ptr)

[PATCH v2 5/7] qla2xxx: Set bit 15 for DIAG_ECHO_TEST MBC.

2017-05-24 Thread Himanshu Madhani
From: Joe Carnuccio <joe.carnuc...@cavium.com>

Set bit (BIT_15) to send right ECHO payload information
for Diagnostic Echo Test command.

Cc: <sta...@vger.kernel.org> # 4.10
Signed-off-by: Joe Carnuccio <joe.carnuc...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_bsg.c | 9 +
 drivers/scsi/qla2xxx/qla_mbx.c | 4 ++--
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 16d1cd50feed..ca3420de5a01 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -730,6 +730,8 @@ qla2x00_process_loopback(struct bsg_job *bsg_job)
return -EIO;
}
 
+   memset(, 0, sizeof(elreq));
+
elreq.req_sg_cnt = dma_map_sg(>pdev->dev,
bsg_job->request_payload.sg_list, 
bsg_job->request_payload.sg_cnt,
DMA_TO_DEVICE);
@@ -795,10 +797,9 @@ qla2x00_process_loopback(struct bsg_job *bsg_job)
 
if (atomic_read(>loop_state) == LOOP_READY &&
(ha->current_topology == ISP_CFG_F ||
-   ((IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) &&
-   le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE
-   && req_data_len == MAX_ELS_FRAME_PAYLOAD)) &&
-   elreq.options == EXTERNAL_LOOPBACK) {
+   (le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE &&
+req_data_len == MAX_ELS_FRAME_PAYLOAD)) &&
+   elreq.options == EXTERNAL_LOOPBACK) {
type = "FC_BSG_HST_VENDOR_ECHO_DIAG";
ql_dbg(ql_dbg_user, vha, 0x701e,
"BSG request type: %s.\n", type);
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 12fea77e31c6..cba1fc5e8be9 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -4812,9 +4812,9 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct 
msg_echo_lb *mreq,
 
memset(mcp->mb, 0 , sizeof(mcp->mb));
mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
-   mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit 
address */
+   /* BIT_6 specifies 64bit address */
+   mcp->mb[1] = mreq->options | BIT_15 | BIT_6;
if (IS_CNA_CAPABLE(ha)) {
-   mcp->mb[1] |= BIT_15;
mcp->mb[2] = vha->fcoe_fcf_idx;
}
mcp->mb[16] = LSW(mreq->rcv_dma);
-- 
2.12.0



[PATCH v2 6/7] qla2xxx: Fix mailbox pointer error in fwdump capture.

2017-05-24 Thread Himanshu Madhani
From: Joe Carnuccio <joe.carnuc...@qlogic.com>

Cc: <sta...@vger.kernel.org> # 4.10
Signed-off-by: Joe Carnuccio <joe.carnuc...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 51b4179469d1..88748a6ab73f 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -1131,7 +1131,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
/* Mailbox registers. */
mbx_reg = >mailbox0;
-   for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, dmp_reg++)
+   for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)
fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));
 
/* Transfer sequence registers. */
@@ -2090,7 +2090,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
/* Mailbox registers. */
mbx_reg = >mailbox0;
-   for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, dmp_reg++)
+   for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)
fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));
 
/* Transfer sequence registers. */
-- 
2.12.0



[PATCH v2 2/7] qla2xxx: Fix NULL pointer access due to redundant fc_host_port_name call

2017-05-24 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Remove redundant fc_host_port_name calls to prevent
early access of scsi_host->shost_data buffer. This
prevent null pointer access.

Following stack trace is seen

BUG: unable to handle kernel NULL pointer dereference at 08
IP: qla24xx_report_id_acquisition+0x22d/0x3a0 [qla2xxx]

Cc: <sta...@vger.kernel.org> # 4.11
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_mbx.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index a113ab3592a7..12fea77e31c6 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -3676,15 +3676,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
qlt_update_host_map(vha, id);
}
 
-   fc_host_port_name(vha->host) =
-   wwn_to_u64(vha->port_name);
-
-   if (qla_ini_mode_enabled(vha))
-   ql_dbg(ql_dbg_mbx, vha, 0x1018,
-   "FA-WWN portname %016llx (%x)\n",
-   fc_host_port_name(vha->host),
-   rptid_entry->vp_status);
-
set_bit(REGISTER_FC4_NEEDED, >dpc_flags);
set_bit(REGISTER_FDMI_NEEDED, >dpc_flags);
} else {
-- 
2.12.0



[PATCH v2 0/7] qla2xxx: Bug Fixes for driver.

2017-05-24 Thread Himanshu Madhani
Hi Martin,

I have reduced the series for 4.12 rc merge to 1-10 patches that
were submitted earlier.

Changes from v1 --> v2
o Drop patches that can be queued for 4.13 scsi-misc merge and will be
  sent as new series.
o Addressed commit summary of patches from Bart's review where applicable.

Please include them in 4.12.0-rc3 fixes at your earliest convenience.

Thanks,
Himanshu

Himanshu Madhani (1):
  qla2xxx: Fix recursive loop during target mode configuration for
ISP25XX leaving system unresponsive.

Joe Carnuccio (4):
  qla2xxx: Modify T262 FW dump template to specify same start/end to
debug customer issues.
  qla2xxx: Set bit 15 for DIAG_ECHO_TEST MBC.
  qla2xxx: Fix mailbox pointer error in fwdump capture.
  qla2xxx: Fix crash due to NULL pointer dereference of ctx.

Quinn Tran (1):
  qla2xxx: Fix NULL pointer access due to redundant fc_host_port_name
call

Sawan Chandak (1):
  qla2xxx: Fix crash due to mismatch mumber of Q-pair creation for Multi
queue

 drivers/scsi/qla2xxx/qla_bsg.c|  9 +
 drivers/scsi/qla2xxx/qla_dbg.c|  4 ++--
 drivers/scsi/qla2xxx/qla_def.h|  1 +
 drivers/scsi/qla2xxx/qla_init.c   |  5 -
 drivers/scsi/qla2xxx/qla_inline.h | 26 +++---
 drivers/scsi/qla2xxx/qla_isr.c|  2 +-
 drivers/scsi/qla2xxx/qla_mbx.c| 13 ++---
 drivers/scsi/qla2xxx/qla_os.c | 30 +++---
 drivers/scsi/qla2xxx/qla_target.c |  8 +---
 drivers/scsi/qla2xxx/qla_tmpl.c   |  2 +-
 10 files changed, 47 insertions(+), 53 deletions(-)

-- 
2.12.0



[PATCH v3 09/15] qla2xxx: Cleanup debug message IDs

2017-06-02 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Assign unique id to all traces and logs for debug purpose.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_attr.c   |   2 +-
 drivers/scsi/qla2xxx/qla_bsg.c|   2 +-
 drivers/scsi/qla2xxx/qla_dbg.c|   2 +-
 drivers/scsi/qla2xxx/qla_dfs.c|   8 +-
 drivers/scsi/qla2xxx/qla_gs.c | 100 +++--
 drivers/scsi/qla2xxx/qla_init.c   | 290 +++---
 drivers/scsi/qla2xxx/qla_isr.c|  18 +--
 drivers/scsi/qla2xxx/qla_mbx.c|  52 +++
 drivers/scsi/qla2xxx/qla_os.c |  30 ++--
 drivers/scsi/qla2xxx/qla_target.c | 217 ++--
 10 files changed, 352 insertions(+), 369 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 7c8d6c54ab70..a93eb42718e5 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -769,7 +769,7 @@ qla2x00_issue_logo(struct file *filp, struct kobject *kobj,
did.b.area = (type & 0xff00) >> 8;
did.b.al_pa = (type & 0x00ff);
 
-   ql_log(ql_log_info, vha, 0x70e3, "portid=%02x%02x%02x done\n",
+   ql_log(ql_log_info, vha, 0xd04d, "portid=%02x%02x%02x done\n",
did.b.domain, did.b.area, did.b.al_pa);
 
ql_log(ql_log_info, vha, 0x70e4, "%s: %d\n", __func__, type);
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index ca3420de5a01..e093795a0371 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -2135,7 +2135,7 @@ qla8044_serdes_op(struct bsg_job *bsg_job)
bsg_reply->reply_payload_rcv_len = sizeof(sr);
break;
default:
-   ql_dbg(ql_dbg_user, vha, 0x70cf,
+   ql_dbg(ql_dbg_user, vha, 0x7020,
"Unknown serdes cmd %x.\n", sr.cmd);
rval = -EINVAL;
break;
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 88748a6ab73f..11e097e123bd 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -62,7 +62,7 @@
  * | Misc |   0xd301   | 0xd031-0xd0ff |
  * |  || 0xd101-0xd1fe |
  * |  || 0xd214-0xd2fe |
- * | Target Mode |   0xe080   ||
+ * | Target Mode |   0xe081   ||
  * | Target Mode Management  |   0xf09b   | 0xf002 |
  * |  || 0xf046-0xf049  |
  * | Target Mode Task Management  |  0x1000d  ||
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 989e17b0758c..391c50be2297 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -70,7 +70,7 @@ qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void 
*unused)
qla2x00_gid_list_size(ha),
_list_dma, GFP_KERNEL);
if (!gid_list) {
-   ql_dbg(ql_dbg_user, vha, 0x705c,
+   ql_dbg(ql_dbg_user, vha, 0x7018,
"DMA allocation failed for %u\n",
 qla2x00_gid_list_size(ha));
return 0;
@@ -370,7 +370,7 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha)
ha->tgt.dfs_tgt_port_database = debugfs_create_file("tgt_port_database",
S_IRUSR,  ha->dfs_dir, vha, _tgt_port_database_ops);
if (!ha->tgt.dfs_tgt_port_database) {
-   ql_log(ql_log_warn, vha, 0x,
+   ql_log(ql_log_warn, vha, 0xd03f,
"Unable to create debugFS tgt_port_database node.\n");
goto out;
}
@@ -386,8 +386,8 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha)
ha->tgt.dfs_tgt_sess = debugfs_create_file("tgt_sess",
S_IRUSR, ha->dfs_dir, vha, _tgt_sess_ops);
if (!ha->tgt.dfs_tgt_sess) {
-   ql_log(ql_log_warn, vha, 0x,
-   "Unable to create debugFS tgt_sess node.\n");
+   ql_log(ql_log_warn, vha, 0xd040,
+   "Unable to create debugFS tgt_sess node.\n");
goto out;
}
 
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index ef8e8891d54f..540fec524ccb 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -2024,7 +2024,7 @@ qla2x00_fdmiv2_rhba(scsi_qla_host_t *vha)
eiter->len = cpu_to_be16(4 + alen);
size += 4 + alen;
 
-   ql_dbg(ql_dbg_disc, vha, 0x20b1,
+   ql_dbg(ql_dbg_disc, vha, 0x201b,
&qu

[PATCH v3 10/15] qla2xxx: Turn on FW option for exchange check

2017-06-02 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Tell FW to track exchange/cmd state to prevent driver
from using stale exchange or exchange that is not meant
for this command.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_init.c   | 18 ++
 drivers/scsi/qla2xxx/qla_target.c | 26 +++---
 drivers/scsi/qla2xxx/qla_target.h |  2 +-
 3 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index c425d061cd80..f92e74639bb1 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -2969,6 +2969,18 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
ha->fw_options[2] &= ~BIT_11;
}
 
+   if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+   /*
+* Tell FW to track each exchange to prevent
+* driver from using stale exchange.
+*/
+   if (qla_tgt_mode_enabled(vha) ||
+   qla_dual_mode_enabled(vha))
+   ha->fw_options[2] |= BIT_4;
+   else
+   ha->fw_options[2] &= ~BIT_4;
+   }
+
ql_dbg(ql_dbg_init, vha, 0x00e8,
"%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
__func__, ha->fw_options[1], ha->fw_options[2],
@@ -7361,6 +7373,12 @@ qla81xx_update_fw_options(scsi_qla_host_t *vha)
ha->fw_options[2] &= ~BIT_11;
}
 
+   if (qla_tgt_mode_enabled(vha) ||
+   qla_dual_mode_enabled(vha))
+   ha->fw_options[2] |= BIT_4;
+   else
+   ha->fw_options[2] &= ~BIT_4;
+
if (ql2xetsenable) {
/* Enable ETS Burst. */
memset(ha->fw_options, 0, sizeof(ha->fw_options));
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 4ad09584d4a8..3cdffdd90279 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2016,8 +2016,9 @@ static void qlt_24xx_send_task_mgmt_ctio(struct 
scsi_qla_host *ha,
ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
ctio->exchange_addr = atio->u.isp24.exchange_addr;
-   ctio->u.status1.flags = (atio->u.isp24.attr << 9) |
-   cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS);
+   temp = (atio->u.isp24.attr << 9)|
+   CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS;
+   ctio->u.status1.flags = cpu_to_le16(temp);
temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
ctio->u.status1.ox_id = cpu_to_le16(temp);
ctio->u.status1.scsi_status =
@@ -2070,8 +2071,9 @@ void qlt_send_resp_ctio(scsi_qla_host_t *vha, struct 
qla_tgt_cmd *cmd,
ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
ctio->exchange_addr = atio->u.isp24.exchange_addr;
-   ctio->u.status1.flags = (atio->u.isp24.attr << 9) |
-   cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS);
+   temp = (atio->u.isp24.attr << 9) |
+   CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS;
+   ctio->u.status1.flags = cpu_to_le16(temp);
temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
ctio->u.status1.ox_id = cpu_to_le16(temp);
ctio->u.status1.scsi_status =
@@ -2359,7 +2361,8 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm 
*prm,
pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
pkt->exchange_addr = atio->u.isp24.exchange_addr;
-   pkt->u.status0.flags |= (atio->u.isp24.attr << 9);
+   temp = atio->u.isp24.attr << 9;
+   pkt->u.status0.flags |= cpu_to_le16(temp);
temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
pkt->u.status0.ox_id = cpu_to_le16(temp);
pkt->u.status0.relative_offset = cpu_to_le32(prm->cmd->offset);
@@ -3484,9 +3487,9 @@ static int __qlt_send_term_exchange(struct scsi_qla_host 
*vha,
ctio24->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
ctio24->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
ctio24->exchange_addr = atio->u.isp24.exchange_addr;
-   ctio24->u.status1.flags = (atio->u.isp24.attr << 9) |
-   cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 |
-   CTIO7_FLAGS_TERMINATE);
+   temp = (atio->u.isp24.attr << 9) | CTIO7_FLAGS_STATUS_MODE_1 |
+   CTIO7_FLAGS_TERMINATE;
+   ctio24-

[PATCH v3 05/15] tcm_qla2xxx: Do not allow aborted cmd to advance.

2017-06-02 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

In case of hardware queue full, commands can loop between
TCM stack and tcm_qla2xx shim layers for retry. While command
is waiting for retry, task mgmt can get ahead and abort the
cmmand that encountered queue full condition. Fix this by
dropping the command, if task mgmt has already started the
command free process.

Acked-by: Nicholas Bellinger <n...@linux-iscsi.org>
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
Reviewed-by: Bart Van Assche <bart.vanass...@sandisk.com>
---
 drivers/scsi/qla2xxx/tcm_qla2xxx.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c 
b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 7443e4efa3ae..1131fe8e2dd2 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -686,6 +686,19 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
struct qla_tgt_cmd, se_cmd);
int xmit_type = QLA_TGT_XMIT_STATUS;
 
+   if (cmd->aborted) {
+   /*
+* Cmd can loop during Q-full. tcm_qla2xxx_aborted_task
+* can get ahead of this cmd. tcm_qla2xxx_aborted_task
+* already kick start the free.
+*/
+   pr_debug(
+   "queue_data_in aborted cmd[%p] refcount %d transport_state 
%x, t_state %x, se_cmd_flags %x\n",
+   cmd, kref_read(>se_cmd.cmd_kref),
+   cmd->se_cmd.transport_state, cmd->se_cmd.t_state,
+   cmd->se_cmd.se_cmd_flags);
+   return 0;
+   }
cmd->bufflen = se_cmd->data_length;
cmd->sg = NULL;
cmd->sg_cnt = 0;
-- 
2.12.0



[PATCH v3 13/15] qla2xxx: Accelerate SCSI BUSY status generation in target mode

2017-06-02 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Accelerate generation of SCSI busy to let initiators slow
down when target is running low in resources.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_init.c | 13 +++--
 drivers/scsi/qla2xxx/qla_mbx.c  |  2 ++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 08000aebe8d4..436968ad4484 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7374,10 +7374,19 @@ qla81xx_update_fw_options(scsi_qla_host_t *vha)
}
 
if (qla_tgt_mode_enabled(vha) ||
-   qla_dual_mode_enabled(vha))
+   qla_dual_mode_enabled(vha)) {
+   /* FW auto send SCSI status during */
+   ha->fw_options[1] |= BIT_8;
+   ha->fw_options[10] |= (u16)SAM_STAT_BUSY << 8;
+
+   /* FW perform Exchange validation */
ha->fw_options[2] |= BIT_4;
-   else
+   } else {
+   ha->fw_options[1]  &= ~BIT_8;
+   ha->fw_options[10] &= 0x00ff;
+
ha->fw_options[2] &= ~BIT_4;
+   }
 
if (ql2xetsenable) {
/* Enable ETS Burst. */
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index bebac42d9e9e..f02a2baffb5b 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -1048,6 +1048,8 @@ qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t 
*fwopts)
mcp->in_mb = MBX_0;
if (IS_FWI2_CAPABLE(vha->hw)) {
mcp->in_mb |= MBX_1;
+   mcp->mb[10] = fwopts[10];
+   mcp->out_mb |= MBX_10;
} else {
mcp->mb[10] = fwopts[10];
mcp->mb[11] = fwopts[11];
-- 
2.12.0



[PATCH v3 11/15] qla2xxx: Add ql2xiniexchg parameter

2017-06-02 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Previously, the ql2xexchoffld module parameter was used to control
the max number of exchanges to be offload onto host memory.

Module parameter ql_dm_tgt_ex_pct was used to control the percentage
of exchanges allocated to the Target side.

With this patch, module parameter ql_dm_tgt_ex_pct is no longer used
to control exchanges for the driver. New module parameter ql2xiniexchg
is added to control exchanges between target mode and initiator mode.

With the updated module parameters, users can control the exact number
of exchanges for either Initiator or Target. The exchange offload feature
will be automatically enabled when the total number of exchanges exceeds
2048 limit.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h|   6 +-
 drivers/scsi/qla2xxx/qla_gbl.h|   3 +-
 drivers/scsi/qla2xxx/qla_init.c   |   2 +-
 drivers/scsi/qla2xxx/qla_inline.h |  16 +
 drivers/scsi/qla2xxx/qla_mbx.c|  14 ++--
 drivers/scsi/qla2xxx/qla_os.c | 136 +++---
 drivers/scsi/qla2xxx/qla_target.c |  48 +++---
 7 files changed, 140 insertions(+), 85 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 51b262b236b4..ddf93efe3986 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -286,7 +286,7 @@ struct name_list_extended {
 #define RESPONSE_ENTRY_CNT_MQ  128 /* Number of response entries.*/
 #define ATIO_ENTRY_CNT_24XX4096/* Number of ATIO entries. */
 #define RESPONSE_ENTRY_CNT_FX00256 /* Number of response 
entries.*/
-#define EXTENDED_EXCH_ENTRY_CNT32768   /* Entries for offload 
case */
+#define FW_DEF_EXCHANGES_CNT 2048
 
 struct req_que;
 struct qla_tgt_sess;
@@ -3593,6 +3593,10 @@ struct qla_hw_data {
 #define IS_SHADOW_REG_CAPABLE(ha)  (IS_QLA27XX(ha))
 #define IS_DPORT_CAPABLE(ha)  (IS_QLA83XX(ha) || IS_QLA27XX(ha))
 #define IS_FAWWN_CAPABLE(ha)   (IS_QLA83XX(ha) || IS_QLA27XX(ha))
+#define IS_EXCHG_OFFLD_CAPABLE(ha) \
+   (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
+#define IS_EXLOGIN_OFFLD_CAPABLE(ha) \
+   (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
 
/* HBA serial number */
uint8_t serial0;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 5b2451745e9f..f8540f5c9e5d 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -137,6 +137,7 @@ extern int ql2xmdcapmask;
 extern int ql2xmdenable;
 extern int ql2xexlogins;
 extern int ql2xexchoffld;
+extern int ql2xiniexchg;
 extern int ql2xfwholdabts;
 extern int ql2xmvasynctoatio;
 
@@ -839,7 +840,7 @@ extern int qla_get_exlogin_status(scsi_qla_host_t *, 
uint16_t *,
uint16_t *);
 extern int qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr);
 extern int qla_get_exchoffld_status(scsi_qla_host_t *, uint16_t *, uint16_t *);
-extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *, dma_addr_t);
+extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *);
 extern void qlt_handle_abts_recv(struct scsi_qla_host *, response_t *);
 
 int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *,
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f92e74639bb1..08000aebe8d4 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -2723,7 +2723,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
if (ql2xexlogins)
ha->flags.exlogins_enabled = 1;
 
-   if (ql2xexchoffld)
+   if (qla_is_exch_offld_enabled(vha))
ha->flags.exchoffld_enabled = 1;
 
rval = qla2x00_execute_fw(vha, srisc_address);
diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index c61a6a871c8e..9996ec0daab1 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -307,3 +307,19 @@ qla2x00_set_retry_delay_timestamp(fc_port_t *fcport, 
uint16_t retry_delay)
fcport->retry_delay_timestamp = jiffies +
(retry_delay * HZ / 10);
 }
+
+static inline bool
+qla_is_exch_offld_enabled(struct scsi_qla_host *vha)
+{
+   if (qla_ini_mode_enabled(vha) &&
+   (ql2xiniexchg > FW_DEF_EXCHANGES_CNT))
+   return true;
+   else if (qla_tgt_mode_enabled(vha) &&
+   (ql2xexchoffld > FW_DEF_EXCHANGES_CNT))
+   return true;
+   else if (qla_dual_mode_enabled(vha) &&
+   ((ql2xiniexchg + ql2xexchoffld) > FW_DEF_EXCHANGES_CNT))
+   return true;
+   else
+   return false;
+}
diff --git a/drivers/scsi/qla2xxx/q

[PATCH v3 03/15] qla2xxx: Retain loop test for fwdump length exceeding buffer length

2017-06-02 Thread Himanshu Madhani
From: Joe Carnuccio <joe.carnuc...@cavium.com>

Signed-off-by: Joe Carnuccio <joe.carnuc...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
Reviewed-by: Bart Van Assche <bart.vanass...@sandisk.com>
---
 drivers/scsi/qla2xxx/qla_init.c |  8 
 drivers/scsi/qla2xxx/qla_tmpl.c | 16 +---
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f6130e8b1ca1..e4876f4220e4 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -6356,8 +6356,8 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t 
*srisc_addr,
"-> template size %x bytes\n", dlen);
if (dlen > risc_size * sizeof(*dcode)) {
ql_log(ql_log_warn, vha, 0x0167,
-   "Failed fwdump template exceeds array by %x bytes\n",
-   (uint32_t)(dlen - risc_size * sizeof(*dcode)));
+   "Failed fwdump template exceeds array by %lx bytes\n",
+   (size_t)(dlen - risc_size * sizeof(*dcode)));
goto default_template;
}
ha->fw_dump_template_len = dlen;
@@ -6658,8 +6658,8 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t 
*srisc_addr)
"-> template size %x bytes\n", dlen);
if (dlen > risc_size * sizeof(*fwcode)) {
ql_log(ql_log_warn, vha, 0x0177,
-   "Failed fwdump template exceeds array by %x bytes\n",
-   (uint32_t)(dlen - risc_size * sizeof(*fwcode)));
+   "Failed fwdump template exceeds array by %lx bytes\n",
+   (size_t)(dlen - risc_size * sizeof(*fwcode)));
goto default_template;
}
ha->fw_dump_template_len = dlen;
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c
index c197972a3e2d..33142610882f 100644
--- a/drivers/scsi/qla2xxx/qla_tmpl.c
+++ b/drivers/scsi/qla2xxx/qla_tmpl.c
@@ -219,8 +219,6 @@ qla27xx_skip_entry(struct qla27xx_fwdt_entry *ent, void 
*buf)
 {
if (buf)
ent->hdr.driver_flags |= DRIVER_FLAG_SKIP_ENTRY;
-   ql_dbg(ql_dbg_misc + ql_dbg_verbose, NULL, 0xd011,
-   "Skipping entry %d\n", ent->hdr.entry_type);
 }
 
 static int
@@ -818,6 +816,8 @@ qla27xx_walk_template(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_misc, vha, 0xd01a,
"%s: entry count %lx\n", __func__, count);
while (count--) {
+   if (buf && *len >= vha->hw->fw_dump_len)
+   break;
if (qla27xx_find_entry(ent->hdr.entry_type)(vha, ent, buf, len))
break;
ent = qla27xx_next_entry(ent);
@@ -825,18 +825,20 @@ qla27xx_walk_template(struct scsi_qla_host *vha,
 
if (count)
ql_dbg(ql_dbg_misc, vha, 0xd018,
-   "%s: residual count (%lx)\n", __func__, count);
+   "%s: entry residual count (%lx)\n", __func__, count);
 
if (ent->hdr.entry_type != ENTRY_TYPE_TMP_END)
ql_dbg(ql_dbg_misc, vha, 0xd019,
-   "%s: missing end (%lx)\n", __func__, count);
+   "%s: missing end entry (%lx)\n", __func__, count);
 
-   ql_dbg(ql_dbg_misc, vha, 0xd01b,
-   "%s: len=%lx\n", __func__, *len);
+   if (buf && *len != vha->hw->fw_dump_len)
+   ql_dbg(ql_dbg_misc, vha, 0xd01b,
+   "%s: length=%#lx residual=%+ld\n",
+   __func__, *len, vha->hw->fw_dump_len - *len);
 
if (buf) {
ql_log(ql_log_warn, vha, 0xd015,
-   "Firmware dump saved to temp buffer (%ld/%p)\n",
+   "Firmware dump saved to temp buffer (%lu/%p)\n",
vha->host_no, vha->hw->fw_dump);
qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
}
-- 
2.12.0



[PATCH v3 01/15] qla2xxx: Allow ABTS, PURX, RIDA on ATIOQ for ISP83XX/27XX

2017-06-02 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Driver added mechanism to move ABTS/PUREX/RIDA mailbox to
ATIO queue as part of commit id 41dc529a4602ac737020f423f84686a81de38e6d
("qla2xxx: Improve RSCN handling in driver").

This patch adds a check to only allow ABTS/PURX/RIDA
to be moved to ATIO Queue for ISP83XX and ISP27XX.

Cc: <sta...@vger.kernel.org> # 4.11
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
Reviewed-by: Bart Van Assche <bart.vanass...@sandisk.com>
---
 drivers/scsi/qla2xxx/qla_init.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 0391fc317003..f6130e8b1ca1 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -2946,7 +2946,8 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
}
 
/* Move PUREX, ABTS RX & RIDA to ATIOQ */
-   if (ql2xmvasynctoatio) {
+   if (ql2xmvasynctoatio &&
+   (IS_QLA83XX(ha) || IS_QLA27XX(ha))) {
if (qla_tgt_mode_enabled(vha) ||
qla_dual_mode_enabled(vha))
ha->fw_options[2] |= BIT_11;
@@ -2958,7 +2959,9 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
"%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
__func__, ha->fw_options[1], ha->fw_options[2],
ha->fw_options[3], vha->host->active_mode);
-   qla2x00_set_fw_options(vha, ha->fw_options);
+
+   if (ha->fw_options[1] || ha->fw_options[2] || ha->fw_options[3])
+   qla2x00_set_fw_options(vha, ha->fw_options);
 
/* Update Serial Link options. */
if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0)
-- 
2.12.0



[PATCH v3 00/15] qla2xxx: Cleanup and minor fixes

2017-06-02 Thread Himanshu Madhani
Hi Martin,

This series contains patches that were dropped from 4.12.0-rc3 inclusion, since
they can go to 4.13 merge window.

Changes from v2 --> v3
o Added Reviewed-by tag from Bart. 
o Droped couple patches for rework. 
o Addressed minor comments from Bart where applicable. 

Changes from v1 --> v2
o Addressed 0-day kernel warning.
o Addressed cleanups and updates as per Bart's comments.
o Added Acked-by tag from Nicholas to applicable patches.

Please apply this series to for-next branch to be included in 4.13 merge window.

Thanks,
Himanshu
 
Joe Carnuccio (1):
  qla2xxx: Retain loop test for fwdump length exceeding buffer length

Quinn Tran (13):
  qla2xxx: Allow ABTS, PURX, RIDA on ATIOQ for ISP83XX/27XX
  qla2xxx: Replace usage of spin_lock with spin_lock_irqsave
  qla2xxx: Fix path recovery
  tcm_qla2xxx: Do not allow aborted cmd to advance.
  qla2xxx: Convert 32-bit LUN usage to 64-bit
  qla2xxx: Fix name server relogin
  qla2xxx: Cleanup debug message IDs
  qla2xxx: Turn on FW option for exchange check
  qla2xxx: Add ql2xiniexchg parameter
  qla2xxx: Remove redundant wait when target is stopped.
  qla2xxx: Accelerate SCSI BUSY status generation in target mode
  qla2xxx: Remove unused irq_cmd_count field.
  qla2xxx: Remove extra register read

Sawan Chandak (1):
  qla2xxx: Use flag PFLG_DISCONNECTED.

 drivers/scsi/qla2xxx/qla_attr.c|   2 +-
 drivers/scsi/qla2xxx/qla_bsg.c |   2 +-
 drivers/scsi/qla2xxx/qla_dbg.c |   2 +-
 drivers/scsi/qla2xxx/qla_def.h |   9 +-
 drivers/scsi/qla2xxx/qla_dfs.c |   8 +-
 drivers/scsi/qla2xxx/qla_gbl.h |   3 +-
 drivers/scsi/qla2xxx/qla_gs.c  | 141 +++--
 drivers/scsi/qla2xxx/qla_init.c| 372 --
 drivers/scsi/qla2xxx/qla_inline.h  |  16 ++
 drivers/scsi/qla2xxx/qla_iocb.c|   4 +-
 drivers/scsi/qla2xxx/qla_isr.c |  35 +++-
 drivers/scsi/qla2xxx/qla_mbx.c |  73 +++
 drivers/scsi/qla2xxx/qla_os.c  | 166 ++-
 drivers/scsi/qla2xxx/qla_target.c  | 402 -
 drivers/scsi/qla2xxx/qla_target.h  |   7 +-
 drivers/scsi/qla2xxx/qla_tmpl.c|  16 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  15 +-
 17 files changed, 716 insertions(+), 557 deletions(-)

-- 
2.12.0



[PATCH v3 08/15] qla2xxx: Fix name server relogin

2017-06-02 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Name server login is normally handle by FW. In some
rare case where one of the switches is being updated,
name server login could get affected. Trigger relogin
to name server when driver detects this condition.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h  |  2 ++
 drivers/scsi/qla2xxx/qla_gs.c   | 20 
 drivers/scsi/qla2xxx/qla_init.c | 38 +-
 drivers/scsi/qla2xxx/qla_isr.c  | 17 +
 4 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 4127f35b669c..51b262b236b4 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -252,6 +252,8 @@
 #define NPH_F_PORT 0x7fe   /*  FE */
 #define NPH_IP_BROADCAST   0x7ff   /*  FF */
 
+#define NPH_SNS_LID(ha)(IS_FWI2_CAPABLE(ha) ? NPH_SNS : 
SIMPLE_NAME_SERVER)
+
 #define MAX_CMDSZ  16  /* SCSI maximum CDB size. */
 #include "qla_fw.h"
 
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 5acebaf57796..ef8e8891d54f 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -124,6 +124,7 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t 
*ms_pkt,
int rval;
uint16_t comp_status;
struct qla_hw_data *ha = vha->hw;
+   bool lid_is_sns = false;
 
rval = QLA_FUNCTION_FAILED;
if (ms_pkt->entry_status != 0) {
@@ -155,6 +156,25 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, 
ms_iocb_entry_t *ms_pkt,
} else
rval = QLA_SUCCESS;
break;
+   case CS_PORT_LOGGED_OUT:
+   if (IS_FWI2_CAPABLE(ha)) {
+   if (le16_to_cpu(ms_pkt->loop_id.extended) ==
+   NPH_SNS)
+   lid_is_sns = true;
+   } else {
+   if (le16_to_cpu(ms_pkt->loop_id.extended) ==
+   SIMPLE_NAME_SERVER)
+   lid_is_sns = true;
+   }
+   if (lid_is_sns) {
+   ql_dbg(ql_dbg_async, vha, 0x502b,
+   "%s failed, Name server has logged out",
+   routine);
+   rval = QLA_NOT_LOGGED_IN;
+   set_bit(LOOP_RESYNC_NEEDED, >dpc_flags);
+   set_bit(LOCAL_LOOP_UPDATE, >dpc_flags);
+   }
+   break;
default:
ql_dbg(ql_dbg_disc, vha, 0x2033,
"%s failed, completion status (%x) on port_id: "
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index e4876f4220e4..4ea4aa5bddaa 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1041,6 +1041,20 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, 
struct event_arg *ea)
 
switch (ea->event) {
case FCME_RELOGIN:
+   case FCME_RSCN:
+   case FCME_GIDPN_DONE:
+   case FCME_GPSC_DONE:
+   case FCME_GPNID_DONE:
+   if (test_bit(LOOP_RESYNC_NEEDED, >dpc_flags) ||
+   test_bit(LOOP_RESYNC_ACTIVE, >dpc_flags))
+   return;
+   break;
+   default:
+   break;
+   }
+
+   switch (ea->event) {
+   case FCME_RELOGIN:
if (test_bit(UNLOADING, >dpc_flags))
return;
 
@@ -4451,20 +4465,31 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
/* EMPTY */
ql_dbg(ql_dbg_disc, vha, 0x2045,
"Register FC-4 TYPE failed.\n");
+   if (test_bit(LOOP_RESYNC_NEEDED,
+   >dpc_flags))
+   break;
}
if (qla2x00_rff_id(vha)) {
/* EMPTY */
ql_dbg(ql_dbg_disc, vha, 0x2049,
"Register FC-4 Features failed.\n");
+   if (test_bit(LOOP_RESYNC_NEEDED,
+   >dpc_flags))
+   break;
}
if (qla2x00_rnn_id(vha)) {
/* EMPTY */
   

[PATCH v3 04/15] qla2xxx: Fix path recovery

2017-06-02 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

If the port is moved/changed, current code would trigger
a deletion. If the port is already deleted, then do relogin.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
Reviewed-by: Bart Van Assche <bart.vanass...@sandisk.com>
---
 drivers/scsi/qla2xxx/qla_gs.c | 21 -
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 9bc9aa9e164a..5acebaf57796 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3118,16 +3118,27 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
 
if (fcport) {
/* cable moved. just plugged in */
-   ql_dbg(ql_dbg_disc, vha, 0x,
-  "%s %d %8phC post del sess\n",
-  __func__, __LINE__, fcport->port_name);
-
fcport->rscn_gen++;
fcport->d_id = ea->id;
fcport->scan_state = QLA_FCPORT_FOUND;
fcport->flags |= FCF_FABRIC_DEVICE;
 
-   qlt_schedule_sess_for_deletion_lock(fcport);
+   switch (fcport->disc_state) {
+   case DSC_DELETED:
+   ql_dbg(ql_dbg_disc, vha, 0x210d,
+   "%s %d %8phC login\n", __func__, __LINE__,
+   fcport->port_name);
+   qla24xx_fcport_handle_login(vha, fcport);
+   break;
+   case DSC_DELETE_PEND:
+   break;
+   default:
+   ql_dbg(ql_dbg_disc, vha, 0x2064,
+   "%s %d %8phC post del sess\n",
+   __func__, __LINE__, fcport->port_name);
+   qlt_schedule_sess_for_deletion_lock(fcport);
+   break;
+   }
} else {
/* create new fcport */
ql_dbg(ql_dbg_disc, vha, 0x,
-- 
2.12.0



[PATCH v3 06/15] qla2xxx: Use flag PFLG_DISCONNECTED.

2017-06-02 Thread Himanshu Madhani
From: Sawan Chandak <sawan.chan...@cavium.com>

There is already flag defined PFLG_DISCONNECTED, which is set
for PCI or register disconnect error condition. There is no need to have
flag PCI_ERR, which has same purpose. Remove use of PCI_ERR flag and use
PFLG_DISCONNECTED flag during error condition.

Signed-off-by: Sawan Chandak <sawan.chan...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h | 1 -
 drivers/scsi/qla2xxx/qla_mbx.c | 5 ++---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index eddbc1218a39..4127f35b669c 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -4017,7 +4017,6 @@ typedef struct scsi_qla_host {
 #define PFLG_DISCONNECTED  0   /* PCI device removed */
 #define PFLG_DRIVER_REMOVING   1   /* PCI driver .remove */
 #define PFLG_DRIVER_PROBING2   /* PCI driver .probe */
-#define PCI_ERR30
 
uint32_tdevice_flags;
 #define SWITCH_FOUND   BIT_0
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index cba1fc5e8be9..fffa1f7cd8d2 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -124,7 +124,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t 
*mcp)
}
 
/* if PCI error, then avoid mbx processing.*/
-   if (test_bit(PCI_ERR, _vha->dpc_flags)) {
+   if (test_bit(PFLG_DISCONNECTED, _vha->dpc_flags) &&
+   test_bit(UNLOADING, _vha->dpc_flags)) {
ql_log(ql_log_warn, vha, 0x1191,
"PCI error, exiting.\n");
return QLA_FUNCTION_TIMEOUT;
@@ -384,8 +385,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t 
*mcp)
 * then only PCI ERR flag would be set.
 * we will do premature exit for above case.
 */
-   if (test_bit(UNLOADING, _vha->dpc_flags))
-   set_bit(PCI_ERR, _vha->dpc_flags);
ha->flags.mbox_busy = 0;
rval = QLA_FUNCTION_TIMEOUT;
goto premature_exit;
-- 
2.12.0



[PATCH v3 07/15] qla2xxx: Convert 32-bit LUN usage to 64-bit

2017-06-02 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Acked-by: Nicholas Bellinger <n...@linux-iscsi.org>
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
Reviewed-by: Bart Van Assche <bart.vanass...@sandisk.com>
---
 drivers/scsi/qla2xxx/qla_target.c  | 32 +++-
 drivers/scsi/qla2xxx/qla_target.h  |  4 ++--
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  2 +-
 3 files changed, 18 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index a2e17a5794ab..a1f33b06019d 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1799,7 +1799,7 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, 
uint32_t tag)
  * for the same lun)
  */
 static void abort_cmds_for_lun(struct scsi_qla_host *vha,
-   uint32_t lun, uint8_t *s_id)
+   u64 lun, uint8_t *s_id)
 {
struct qla_tgt_sess_op *op;
struct qla_tgt_cmd *cmd;
@@ -1810,7 +1810,7 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
spin_lock_irqsave(>cmd_list_lock, flags);
list_for_each_entry(op, >qla_sess_op_cmd_list, cmd_list) {
uint32_t op_key;
-   uint32_t op_lun;
+   u64 op_lun;
 
op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id);
op_lun = scsilun_to_int(
@@ -1832,7 +1832,7 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
 
list_for_each_entry(cmd, >qla_cmd_list, cmd_list) {
uint32_t cmd_key;
-   uint32_t cmd_lun;
+   u64 cmd_lun;
 
cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id);
cmd_lun = scsilun_to_int(
@@ -1850,18 +1850,15 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host 
*vha,
struct qla_hw_data *ha = vha->hw;
struct se_session *se_sess = sess->se_sess;
struct qla_tgt_mgmt_cmd *mcmd;
+   struct qla_tgt_cmd *cmd;
struct se_cmd *se_cmd;
-   u32 lun = 0;
int rc;
bool found_lun = false;
unsigned long flags;
 
spin_lock_irqsave(_sess->sess_cmd_lock, flags);
list_for_each_entry(se_cmd, _sess->sess_cmd_list, se_cmd_list) {
-   struct qla_tgt_cmd *cmd =
-   container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
if (se_cmd->tag == abts->exchange_addr_to_abort) {
-   lun = cmd->unpacked_lun;
found_lun = true;
break;
}
@@ -1895,12 +1892,13 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host 
*vha,
}
memset(mcmd, 0, sizeof(*mcmd));
 
+   cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
mcmd->sess = sess;
memcpy(>orig_iocb.abts, abts, sizeof(mcmd->orig_iocb.abts));
mcmd->reset_count = vha->hw->chip_reset;
mcmd->tmr_func = QLA_TGT_ABTS;
 
-   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, lun, mcmd->tmr_func,
+   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, cmd->unpacked_lun, 
mcmd->tmr_func,
abts->exchange_addr_to_abort);
if (rc != 0) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf052,
@@ -4334,13 +4332,12 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host 
*vha, void *iocb)
struct qla_hw_data *ha = vha->hw;
struct qla_tgt *tgt;
struct fc_port *sess;
-   uint32_t lun, unpacked_lun;
+   u64 unpacked_lun;
int fn;
unsigned long flags;
 
tgt = vha->vha_tgt.qla_tgt;
 
-   lun = a->u.isp24.fcp_cmnd.lun;
fn = a->u.isp24.fcp_cmnd.task_mgmt_flags;
 
spin_lock_irqsave(>tgt.sess_lock, flags);
@@ -4348,7 +4345,8 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host 
*vha, void *iocb)
a->u.isp24.fcp_hdr.s_id);
spin_unlock_irqrestore(>tgt.sess_lock, flags);
 
-   unpacked_lun = scsilun_to_int((struct scsi_lun *));
+   unpacked_lun =
+   scsilun_to_int((struct scsi_lun *)>u.isp24.fcp_cmnd.lun);
 
if (!sess) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf024,
@@ -4371,7 +4369,7 @@ static int __qlt_abort_task(struct scsi_qla_host *vha,
struct atio_from_isp *a = (struct atio_from_isp *)iocb;
struct qla_hw_data *ha = vha->hw;
struct qla_tgt_mgmt_cmd *mcmd;
-   uint32_t lun, unpacked_lun;
+   u64 unpacked_lun;
int rc;
 
mcmd = mempool_alloc(qla_tgt_mgmt_cmd_mempool, GFP_ATOMIC);
@@ -4387,8 +4385,8 @@ static int __qlt_abort_task(struct scsi_qla_host *vha,
memcpy(>orig_iocb.imm_ntfy, iocb,
sizeof(mcmd->orig_iocb.imm_ntfy));
 
-   lun = a->u.isp24.fcp_cmnd.lun;
-   unpacked_lun = scsilun_to_int((struct scsi_lu

[PATCH v3 15/15] qla2xxx: Remove extra register read

2017-06-02 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Remove extra register read in each interrupt processing
to improve performance.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_iocb.c   |  4 +++-
 drivers/scsi/qla2xxx/qla_target.c | 11 ++-
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index ea027f6a7fd4..8404f17f3c6c 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -464,7 +464,9 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct 
req_que *req)
req->ring_ptr++;
 
/* Set chip new ring index. */
-   if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+   if (ha->mqenable || IS_QLA27XX(ha)) {
+   WRT_REG_DWORD(req->req_q_in, req->ring_index);
+   } else if (IS_QLA83XX(ha)) {
WRT_REG_DWORD(req->req_q_in, req->ring_index);
RD_REG_DWORD_RELAXED(>iobase->isp24.hccr);
} else if (IS_QLAFX00(ha)) {
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index a8e57072019b..88eea4d34487 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2252,11 +2252,10 @@ static void qlt_unmap_sg(struct scsi_qla_host *vha, 
struct qla_tgt_cmd *cmd)
 static int qlt_check_reserve_free_req(struct scsi_qla_host *vha,
uint32_t req_cnt)
 {
-   uint32_t cnt, cnt_in;
+   uint32_t cnt;
 
if (vha->req->cnt < (req_cnt + 2)) {
cnt = (uint16_t)RD_REG_DWORD(vha->req->req_q_out);
-   cnt_in = (uint16_t)RD_REG_DWORD(vha->req->req_q_in);
 
if  (vha->req->ring_index < cnt)
vha->req->cnt = cnt - vha->req->ring_index;
@@ -2264,14 +2263,8 @@ static int qlt_check_reserve_free_req(struct 
scsi_qla_host *vha,
vha->req->cnt = vha->req->length -
(vha->req->ring_index - cnt);
 
-   if (unlikely(vha->req->cnt < (req_cnt + 2))) {
-   ql_dbg(ql_dbg_io, vha, 0x305a,
-   "qla_target(%d): There is no room in the request 
ring: vha->req->ring_index=%d, vha->req->cnt=%d, req_cnt=%d Req-out=%d 
Req-in=%d Req-Length=%d\n",
-   vha->vp_idx, vha->req->ring_index,
-   vha->req->cnt, req_cnt, cnt, cnt_in,
-   vha->req->length);
+   if (unlikely(vha->req->cnt < (req_cnt + 2)))
return -EAGAIN;
-   }
}
 
vha->req->cnt -= req_cnt;
-- 
2.12.0



[PATCH v3 14/15] qla2xxx: Remove unused irq_cmd_count field.

2017-06-02 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

When driver is unloaded, all sessions are torn down, all
commmands are flushed, chip is reset to ensure there is
no knowledge of target mode in ISP. The irq_cmd_count field
was used to make sure all commands are processed on top of that.
The irq_cmd_count is now redundant and not needed.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 9 +
 drivers/scsi/qla2xxx/qla_target.h | 1 -
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index f9ccf845d084..a8e57072019b 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -5355,8 +5355,6 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, 
response_t *pkt)
 * Otherwise, some commands can stuck.
 */
 
-   tgt->irq_cmd_count++;
-
switch (pkt->entry_type) {
case CTIO_CRC2:
case CTIO_TYPE7:
@@ -5382,10 +5380,8 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, 
response_t *pkt)
}
 
rc = qlt_chk_qfull_thresh_hold(vha, atio, true);
-   if (rc != 0) {
-   tgt->irq_cmd_count--;
+   if (rc != 0)
return;
-   }
 
rc = qlt_handle_cmd_for_atio(vha, atio);
if (unlikely(rc != 0)) {
@@ -5517,7 +5513,6 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, 
response_t *pkt)
break;
}
 
-   tgt->irq_cmd_count--;
 }
 
 /*
@@ -5547,7 +5542,6 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host 
*vha,
 * Otherwise, some commands can stuck.
 */
 
-   tgt->irq_cmd_count++;
 
switch (code) {
case MBA_RESET: /* Reset */
@@ -5635,7 +5629,6 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host 
*vha,
break;
}
 
-   tgt->irq_cmd_count--;
 }
 
 static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha,
diff --git a/drivers/scsi/qla2xxx/qla_target.h 
b/drivers/scsi/qla2xxx/qla_target.h
index 07ff565485b7..c328a267c4c3 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -790,7 +790,6 @@ struct qla_tgt {
 * because req_pkt() can drop/reaquire HW lock inside. Protected by
 * HW lock.
 */
-   int irq_cmd_count;
int atio_irq_cmd_count;
 
int datasegs_per_cmd, datasegs_per_cont, sg_tablesize;
-- 
2.12.0



[PATCH v3 02/15] qla2xxx: Replace usage of spin_lock with spin_lock_irqsave

2017-06-02 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Convert usage of spin_lock to spin_lock_irqsave because qla2xxx driver
can access all the data structures in an interrupt context.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
Reviewed-by: Bart Van Assche <bart.vanass...@sandisk.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 26 ++
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index e766d8412384..a2e17a5794ab 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1762,13 +1762,13 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, 
uint32_t tag)
 {
struct qla_tgt_sess_op *op;
struct qla_tgt_cmd *cmd;
+   unsigned long flags;
 
-   spin_lock(>cmd_list_lock);
-
+   spin_lock_irqsave(>cmd_list_lock, flags);
list_for_each_entry(op, >qla_sess_op_cmd_list, cmd_list) {
if (tag == op->atio.u.isp24.exchange_addr) {
op->aborted = true;
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
return 1;
}
}
@@ -1776,7 +1776,7 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, 
uint32_t tag)
list_for_each_entry(op, >unknown_atio_list, cmd_list) {
if (tag == op->atio.u.isp24.exchange_addr) {
op->aborted = true;
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
return 1;
}
}
@@ -1784,12 +1784,12 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, 
uint32_t tag)
list_for_each_entry(cmd, >qla_cmd_list, cmd_list) {
if (tag == cmd->atio.u.isp24.exchange_addr) {
cmd->aborted = 1;
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
return 1;
}
}
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
 
-   spin_unlock(>cmd_list_lock);
return 0;
 }
 
@@ -1804,9 +1804,10 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
struct qla_tgt_sess_op *op;
struct qla_tgt_cmd *cmd;
uint32_t key;
+   unsigned long flags;
 
key = sid_to_key(s_id);
-   spin_lock(>cmd_list_lock);
+   spin_lock_irqsave(>cmd_list_lock, flags);
list_for_each_entry(op, >qla_sess_op_cmd_list, cmd_list) {
uint32_t op_key;
uint32_t op_lun;
@@ -1839,7 +1840,7 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
if (cmd_key == key && cmd_lun == lun)
cmd->aborted = 1;
}
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
 }
 
 /* ha->hardware_lock supposed to be held on entry */
@@ -4216,9 +4217,9 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host 
*vha,
memcpy(>atio, atio, sizeof(*atio));
op->vha = vha;
 
-   spin_lock(>cmd_list_lock);
+   spin_lock_irqsave(>cmd_list_lock, flags);
list_add_tail(>cmd_list, >qla_sess_op_cmd_list);
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
 
INIT_WORK(>work, qlt_create_sess_from_atio);
queue_work(qla_tgt_wq, >work);
@@ -4529,12 +4530,13 @@ static int abort_cmds_for_s_id(struct scsi_qla_host 
*vha, port_id_t *s_id)
struct qla_tgt_cmd *cmd;
uint32_t key;
int count = 0;
+   unsigned long flags;
 
key = (((u32)s_id->b.domain << 16) |
   ((u32)s_id->b.area   <<  8) |
   ((u32)s_id->b.al_pa));
 
-   spin_lock(>cmd_list_lock);
+   spin_lock_irqsave(>cmd_list_lock, flags);
list_for_each_entry(op, >qla_sess_op_cmd_list, cmd_list) {
uint32_t op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id);
 
@@ -4559,7 +4561,7 @@ static int abort_cmds_for_s_id(struct scsi_qla_host *vha, 
port_id_t *s_id)
count++;
}
}
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
 
return count;
 }
-- 
2.12.0



[PATCH v3 12/15] qla2xxx: Remove redundant wait when target is stopped.

2017-06-02 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Current code already destroy all target sessions when
target Mode is stopped. Target core would waits for
all commands that belong to each session to purge.
The extra wait for interrupts to settle down is not
relevant.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 33 -
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 324048476d9e..f9ccf845d084 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1427,6 +1427,8 @@ int qlt_stop_phase1(struct qla_tgt *tgt)
 
if (npiv_vports) {
mutex_unlock(_tgt_mutex);
+   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf021,
+   "NPIV is in use. Can not stop target\n");
return -EPERM;
}
}
@@ -1437,7 +1439,7 @@ int qlt_stop_phase1(struct qla_tgt *tgt)
return -EPERM;
}
 
-   ql_dbg(ql_dbg_tgt, vha, 0xe003, "Stopping target for host %ld(%p)\n",
+   ql_dbg(ql_dbg_tgt_mgt, vha, 0xe003, "Stopping target for host 
%ld(%p)\n",
vha->host_no, vha);
/*
 * Mutex needed to sync with qla_tgt_fc_port_[added,deleted].
@@ -1480,9 +1482,7 @@ EXPORT_SYMBOL(qlt_stop_phase1);
 /* Called by tcm_qla2xxx configfs code */
 void qlt_stop_phase2(struct qla_tgt *tgt)
 {
-   struct qla_hw_data *ha = tgt->ha;
-   scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
-   unsigned long flags;
+   scsi_qla_host_t *vha = tgt->vha;
 
if (tgt->tgt_stopped) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04f,
@@ -1490,24 +1490,19 @@ void qlt_stop_phase2(struct qla_tgt *tgt)
dump_stack();
return;
}
-
-   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00b,
-   "Waiting for %d IRQ commands to complete (tgt %p)",
-   tgt->irq_cmd_count, tgt);
+   if (!tgt->tgt_stop) {
+   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00b,
+   "%s: phase1 stop is not completed\n", __func__);
+   dump_stack();
+   return;
+   }
 
mutex_lock(>vha_tgt.tgt_mutex);
-   spin_lock_irqsave(>hardware_lock, flags);
-   while ((tgt->irq_cmd_count != 0) || (tgt->atio_irq_cmd_count != 0)) {
-   spin_unlock_irqrestore(>hardware_lock, flags);
-   udelay(2);
-   spin_lock_irqsave(>hardware_lock, flags);
-   }
tgt->tgt_stop = 0;
tgt->tgt_stopped = 1;
-   spin_unlock_irqrestore(>hardware_lock, flags);
mutex_unlock(>vha_tgt.tgt_mutex);
 
-   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00c, "Stop of tgt %p finished",
+   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00c, "Stop of tgt %p finished\n",
tgt);
 }
 EXPORT_SYMBOL(qlt_stop_phase2);
@@ -1517,6 +1512,10 @@ static void qlt_release(struct qla_tgt *tgt)
 {
scsi_qla_host_t *vha = tgt->vha;
 
+   if ((vha->vha_tgt.qla_tgt != NULL) && !tgt->tgt_stop &&
+   !tgt->tgt_stopped)
+   qlt_stop_phase1(tgt);
+
if ((vha->vha_tgt.qla_tgt != NULL) && !tgt->tgt_stopped)
qlt_stop_phase2(tgt);
 
@@ -5531,7 +5530,7 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host 
*vha,
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
int login_code;
 
-   if (!ha->tgt.tgt_ops)
+   if (!tgt || tgt->tgt_stop || tgt->tgt_stopped)
return;
 
if (unlikely(tgt == NULL)) {
-- 
2.12.0



[PATCH 08/15] qla2xxx: Use shadow register for ISP27XX

2017-06-07 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

For ISP27XX, use shadow register to read FW provided
REQQ's consumer index. The shadow register is dma'ed
by firmware.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h| 1 +
 drivers/scsi/qla2xxx/qla_init.c   | 1 +
 drivers/scsi/qla2xxx/qla_os.c | 1 +
 drivers/scsi/qla2xxx/qla_target.c | 3 ++-
 4 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index dfa001357110..b3ba32773db4 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3266,6 +3266,7 @@ struct qla_qpair {
uint32_t fw_started:1;
uint32_t enable_class_2:1;
uint32_t enable_explicit_conf:1;
+   uint32_t use_shadow_reg:1;
 
uint16_t id;/* qp number used with FW */
uint16_t vp_idx;/* vport ID */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 360abede3f6b..f586f4f7dc57 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7614,6 +7614,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct 
scsi_qla_host *vha, int qos,
qpair->vha = vha;
qpair->qp_lock_ptr = >qp_lock;
spin_lock_init(>qp_lock);
+   qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0;
 
/* Assign available que pair id */
mutex_lock(>mq_lock);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 44be2c8237fd..1d66954b7e5a 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -384,6 +384,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, 
struct req_que *req,
ha->base_qpair->rsp = rsp;
ha->base_qpair->vha = vha;
ha->base_qpair->qp_lock_ptr = >hardware_lock;
+   ha->base_qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0;
/* init qpair to this cpu. Will adjust at run time. */
ha->base_qpair->msix = >msix_entries[QLA_MSIX_RSP_Q];
INIT_LIST_HEAD(>base_qpair->hints_list);
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 66bb4825339f..1d6cc24c0640 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2288,7 +2288,8 @@ static int qlt_check_reserve_free_req(struct qla_qpair 
*qpair,
struct req_que *req = qpair->req;
 
if (req->cnt < (req_cnt + 2)) {
-   cnt = (uint16_t)RD_REG_DWORD(req->req_q_out);
+   cnt = (uint16_t)(qpair->use_shadow_reg ? *req->out_ptr :
+   RD_REG_DWORD_RELAXED(req->req_q_out));
 
if  (req->ring_index < cnt)
req->cnt = cnt - req->ring_index;
-- 
2.12.0



[PATCH 02/15] qla2xxx: Preparation for Target MQ.

2017-06-07 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

In Current code, Req Q 0, Resp Q 0 and hardware_lock
are the main resources for sending and process completion
of Target IO. These resources are now referenced
behind a new qpair ("struct qla_qpair base_qpair").
Main path IO handle will access those resources via the
qpair pointer in preparation for Target MQ.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_attr.c   |   2 +-
 drivers/scsi/qla2xxx/qla_def.h|  17 +-
 drivers/scsi/qla2xxx/qla_gbl.h|  15 +-
 drivers/scsi/qla2xxx/qla_init.c   |  11 +-
 drivers/scsi/qla2xxx/qla_iocb.c   |  30 ++-
 drivers/scsi/qla2xxx/qla_isr.c|  11 +-
 drivers/scsi/qla2xxx/qla_mid.c|  40 +--
 drivers/scsi/qla2xxx/qla_os.c |  23 +-
 drivers/scsi/qla2xxx/qla_target.c | 518 --
 drivers/scsi/qla2xxx/qla_target.h |  10 +-
 10 files changed, 380 insertions(+), 297 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index a93eb42718e5..f0f16d313faf 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -2096,7 +2096,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool 
disable)
}
 
if (qos) {
-   qpair = qla2xxx_create_qpair(vha, qos, vha->vp_idx);
+   qpair = qla2xxx_create_qpair(vha, qos, vha->vp_idx, true);
if (!qpair)
ql_log(ql_log_warn, vha, 0x7084,
"Can't create qpair for VP[%d]\n",
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 1b5049b1ef4a..64109134e276 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3182,6 +3182,9 @@ struct qla_tc_param {
 #define QLA_PRECONFIG_VPORTS 32
 #define QLA_MAX_VPORTS_QLA24XX 128
 #define QLA_MAX_VPORTS_QLA25XX 256
+
+struct qla_qpair;
+
 /* Response queue data structure */
 struct rsp_que {
dma_addr_t  dma;
@@ -3201,6 +3204,7 @@ struct rsp_que {
struct qla_msix_entry *msix;
struct req_que *req;
srb_t *status_srb; /* status continuation entry */
+   struct qla_qpair *qpair;
 
dma_addr_t  dma_fx00;
response_t *ring_fx00;
@@ -3241,6 +3245,14 @@ struct req_que {
 struct qla_qpair {
spinlock_t qp_lock;
atomic_t ref_count;
+
+   /*
+* For qpair 0, qp_lock_ptr will point at hardware_lock due to
+* legacy code. For other Qpair(s), it will point at qp_lock.
+*/
+   spinlock_t *qp_lock_ptr;
+   struct scsi_qla_host *vha;
+
/* distill these fields down to 'online=0/1'
 * ha->flags.eeh_busy
 * ha->flags.pci_channel_io_perm_failure
@@ -3252,10 +3264,7 @@ struct qla_qpair {
uint32_t delete_in_progress:1;
 
uint16_t id;/* qp number used with FW */
-   uint16_t num_active_cmd;/* cmds down at firmware */
-   cpumask_t cpu_mask; /* CPU mask for cpu affinity operation */
uint16_t vp_idx;/* vport ID */
-
mempool_t *srb_mempool;
 
/* to do: New driver: move queues to here instead of pointers */
@@ -3266,7 +3275,7 @@ struct qla_qpair {
struct qla_hw_data *hw;
struct work_struct q_work;
struct list_head qp_list_elem; /* vha->qp_list */
-   struct scsi_qla_host *vha;
+   uint16_t cpuid;
 };
 
 /* Place holder for FW buffer parameters */
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 63355f40ff2f..f5493eda0110 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -77,8 +77,7 @@ struct qla_work_evt *qla2x00_alloc_work(struct scsi_qla_host 
*,
 enum qla_work_type);
 extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *);
 int qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e);
-extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *);
-extern void *qla2x00_alloc_iocbs_ready(struct scsi_qla_host *, srb_t *);
+extern void *qla2x00_alloc_iocbs_ready(struct qla_qpair *, srb_t *);
 extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *);
 
 extern fc_port_t *
@@ -96,7 +95,7 @@ qla2x00_alloc_outstanding_cmds(struct qla_hw_data *, struct 
req_que *);
 extern int qla2x00_init_rings(scsi_qla_host_t *);
 extern uint8_t qla27xx_find_valid_image(struct scsi_qla_host *);
 extern struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *,
-   int, int);
+   int, int, bool);
 extern int qla2xxx_delete_qpair(struct scsi_qla_host *, struct qla_qpair *);
 void qla2x00_fcport_event_handler(scsi_qla_host_t *, struct event_arg *);
 int qla24xx_async_gpdb(struct scsi_qla_host *, fc_port_t *, u8);
@@ -255,7 +254,8 @@ extern int qla2x00_start_bidir(srb_t *, struct 
scsi_qla_host *, uint32_t);
 extern int qla2

[PATCH 00/15] qla2xxx: Add Target Multiqueue support

2017-06-07 Thread Himanshu Madhani
Hi Nic,

This patch series adds support for multiqueue for qla2xxx target mode driver.

I've also added patch ("qla2xxx: Include Exchange offload/Extended Login
into FW dump") which was dropped from earlier series for rework.

Please apply this series to target-pending for inclusion in 4.13 merge window.

Thanks,
Himanshu
 
Himanshu Madhani (1):
  qla2xxx: Update driver version to 9.01.00.00-k

Quinn Tran (13):
  qla2xxx: Combine Active command arrays.
  qla2xxx: Preparation for Target MQ.
  qla2xxx: Enable Target Multi Queue
  qla2xxx: Add debug knob for user control workload
  qla2xxx: Add fw_started flags to qpair
  qla2xxx: Move fields from qla_hw_data to qla_qpair
  qla2xxx: Use shadow register for ISP27XX
  qla2xxx: Add function call to qpair for door bell
  qla2xxx: Add debug logging routine for qpair
  qla2xxx: Remove unused tgt_enable_64bit_addr flag
  qla2xxx: Remove datasegs_per_cmd and datasegs_per_cont field
  qla2xxx: Move target stat counters from vha to qpair.
  qla2xxx: Include Exchange offload/Extended Login into FW dump

Sawan Chandak (1):
  qla2xxx: Fix mailbox failure while deleting Queue pairs

 drivers/scsi/qla2xxx/qla_attr.c|4 +-
 drivers/scsi/qla2xxx/qla_dbg.c |  150 ++
 drivers/scsi/qla2xxx/qla_dbg.h |   17 +
 drivers/scsi/qla2xxx/qla_def.h |  119 -
 drivers/scsi/qla2xxx/qla_dfs.c |  137 -
 drivers/scsi/qla2xxx/qla_gbl.h |   19 +-
 drivers/scsi/qla2xxx/qla_init.c|   53 +-
 drivers/scsi/qla2xxx/qla_inline.h  |   44 ++
 drivers/scsi/qla2xxx/qla_iocb.c|   32 +-
 drivers/scsi/qla2xxx/qla_isr.c |   95 +++-
 drivers/scsi/qla2xxx/qla_mid.c |   44 +-
 drivers/scsi/qla2xxx/qla_os.c  |  156 --
 drivers/scsi/qla2xxx/qla_target.c  | 1028 +---
 drivers/scsi/qla2xxx/qla_target.h  |   50 +-
 drivers/scsi/qla2xxx/qla_version.h |4 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |8 +-
 16 files changed, 1349 insertions(+), 611 deletions(-)

-- 
2.12.0



[PATCH 01/15] qla2xxx: Combine Active command arrays.

2017-06-07 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Merge active/outstanding cmd arrays from target side
and initiator side together in prepration for Target
Multi Queue support.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h|  15 +++-
 drivers/scsi/qla2xxx/qla_gbl.h|   2 -
 drivers/scsi/qla2xxx/qla_inline.h |   1 +
 drivers/scsi/qla2xxx/qla_isr.c|  48 +
 drivers/scsi/qla2xxx/qla_os.c |  75 ++--
 drivers/scsi/qla2xxx/qla_target.c | 144 --
 drivers/scsi/qla2xxx/qla_target.h |  23 --
 7 files changed, 164 insertions(+), 144 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index ddf93efe3986..1b5049b1ef4a 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -437,7 +437,18 @@ struct srb_iocb {
 #define SRB_NACK_PRLI  17
 #define SRB_NACK_LOGO  18
 
+enum {
+   TYPE_SRB,
+   TYPE_TGT_CMD,
+};
+
 typedef struct srb {
+   /*
+* Do not move cmd_type field, it needs to
+* line up with qla_tgt_cmd->cmd_type
+*/
+   uint8_t cmd_type;
+   uint8_t pad[3];
atomic_t ref_count;
struct fc_port *fcport;
struct scsi_qla_host *vha;
@@ -3287,9 +3298,6 @@ struct qlt_hw_data {
uint32_t __iomem *atio_q_out;
 
struct qla_tgt_func_tmpl *tgt_ops;
-   struct qla_tgt_cmd *cmds[DEFAULT_OUTSTANDING_COMMANDS];
-   uint16_t current_handle;
-
struct qla_tgt_vp_map *tgt_vp_map;
 
int saved_set;
@@ -4258,6 +4266,7 @@ enum nexus_wait_type {
WAIT_LUN,
 };
 
+#include "qla_target.h"
 #include "qla_gbl.h"
 #include "qla_dbg.h"
 #include "qla_inline.h"
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index f8540f5c9e5d..63355f40ff2f 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -834,8 +834,6 @@ extern irqreturn_t qla8044_intr_handler(int, void *);
 extern void qla82xx_mbx_completion(scsi_qla_host_t *, uint16_t);
 extern int qla8044_abort_isp(scsi_qla_host_t *);
 extern int qla8044_check_fw_alive(struct scsi_qla_host *);
-
-extern void qlt_host_reset_handler(struct qla_hw_data *ha);
 extern int qla_get_exlogin_status(scsi_qla_host_t *, uint16_t *,
uint16_t *);
 extern int qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr);
diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index 9996ec0daab1..99028d48c664 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -250,6 +250,7 @@ qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, 
gfp_t flag)
 
memset(sp, 0, sizeof(*sp));
sp->fcport = fcport;
+   sp->cmd_type = TYPE_SRB;
sp->iocbs = 1;
sp->vha = vha;
 done:
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 2984abcc29e7..8aaddb75f964 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -17,7 +17,7 @@
 static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
 static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *);
 static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *);
-static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
+static int qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
sts_entry_t *);
 
 /**
@@ -2280,6 +2280,14 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct 
rsp_que *rsp, void *pkt)
return;
}
 
+   if (sp->cmd_type != TYPE_SRB) {
+   req->outstanding_cmds[handle] = NULL;
+   ql_dbg(ql_dbg_io, vha, 0x3015,
+   "Unknown sp->cmd_type %x %p).\n",
+   sp->cmd_type, sp);
+   return;
+   }
+
if (unlikely((state_flags & BIT_1) && (sp->type == SRB_BIDI_CMD))) {
qla25xx_process_bidir_status_iocb(vha, pkt, req, handle);
return;
@@ -2632,8 +2640,9 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, 
sts_cont_entry_t *pkt)
  * qla2x00_error_entry() - Process an error entry.
  * @ha: SCSI driver HA context
  * @pkt: Entry pointer
+ * return : 1=allow further error analysis. 0=no additional error analysis.
  */
-static void
+static int
 qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t 
*pkt)
 {
srb_t *sp;
@@ -2654,18 +2663,35 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct 
rsp_que *rsp, sts_entry_t *pkt)
if (pkt->entry_status & RF_BUSY)
res = DID_BUS_BUSY << 16;
 
-   if (pkt->entry_type == NOTIFY_ACK_TYPE &&
-   pkt->handle == QLA_TGT_SKIP_HANDLE)
-   return;
+   if ((pkt->ha

[PATCH 04/15] qla2xxx: Fix mailbox failure while deleting Queue pairs

2017-06-07 Thread Himanshu Madhani
From: Sawan Chandak <sawan.chan...@cavium.com>

In target mode driver, queue pairs are created at the configuration
time, instead of load time, after chip reset. If a user tries to
load/unload driver after queue pairs are created, then there would
be mailbox failure while trying to delete queue pairs. This patch adds
a flag to check if queue pairs are created. Queue pairs will be
deleted only If they were created during target configuration.

Signed-off-by: Sawan Chandak <sawan.chan...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h  |  2 ++
 drivers/scsi/qla2xxx/qla_init.c | 10 --
 drivers/scsi/qla2xxx/qla_mid.c  |  4 
 drivers/scsi/qla2xxx/qla_os.c   |  1 +
 4 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 005ca2de3795..8b52f431a812 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3997,6 +3997,8 @@ typedef struct scsi_qla_host {
uint32_tfw_tgt_reported:1;
uint32_tbbcr_enable:1;
uint32_tqpairs_available:1;
+   uint32_tqpairs_req_created:1;
+   uint32_tqpairs_rsp_created:1;
} flags;
 
atomic_tloop_state;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index fa5e6ab8e4a7..dcc306121a3d 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7719,9 +7719,12 @@ struct qla_qpair *qla2xxx_create_qpair(struct 
scsi_qla_host *vha, int qos,
 
 int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair)
 {
-   int ret;
+   int ret = QLA_FUNCTION_FAILED;
struct qla_hw_data *ha = qpair->hw;
 
+   if (!vha->flags.qpairs_req_created && !vha->flags.qpairs_rsp_created)
+   goto fail;
+
qpair->delete_in_progress = 1;
while (atomic_read(>ref_count))
msleep(500);
@@ -7738,8 +7741,11 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, 
struct qla_qpair *qpair)
clear_bit(qpair->id, ha->qpair_qid_map);
ha->num_qpairs--;
list_del(>qp_list_elem);
-   if (list_empty(>qp_list))
+   if (list_empty(>qp_list)) {
vha->flags.qpairs_available = 0;
+   vha->flags.qpairs_req_created = 0;
+   vha->flags.qpairs_rsp_created = 0;
+   }
mempool_destroy(qpair->srb_mempool);
kfree(qpair);
mutex_unlock(>mq_lock);
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 4ad452a42dbe..f0605cd196fb 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -645,6 +645,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t 
options,
int ret = 0;
struct req_que *req = NULL;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
+   struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev);
uint16_t que_id = 0;
device_reg_t *reg;
uint32_t cnt;
@@ -741,6 +742,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t 
options,
mutex_unlock(>mq_lock);
goto que_failed;
}
+   vha->flags.qpairs_req_created = 1;
}
 
return req->id;
@@ -772,6 +774,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t 
options,
int ret = 0;
struct rsp_que *rsp = NULL;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
+   struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev);
uint16_t que_id = 0;
device_reg_t *reg;
 
@@ -855,6 +858,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t 
options,
mutex_unlock(>mq_lock);
goto que_failed;
}
+   vha->flags.qpairs_rsp_created = 1;
}
rsp->req = NULL;
 
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3963602aef35..13e4d2428a9a 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -384,6 +384,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, 
struct req_que *req,
ha->base_qpair->rsp = rsp;
ha->base_qpair->vha = vha;
ha->base_qpair->qp_lock_ptr = >hardware_lock;
+   /* init qpair to this cpu. Will adjust at run time. */
ha->base_qpair->msix = >msix_entries[QLA_MSIX_RSP_Q];
INIT_LIST_HEAD(>base_qpair->hints_list);
qla_cpu_update(rsp->qpair, smp_processor_id());
-- 
2.12.0



[PATCH 07/15] qla2xxx: Move fields from qla_hw_data to qla_qpair

2017-06-07 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

o Move chip_reset, enable_class_2 fields from qla_hw_data to qla_qpair
  to reduce cache thrash for target MQ.
o Optimizations to reduce unnecessary memory load for good path io.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_attr.c   |  2 +-
 drivers/scsi/qla2xxx/qla_def.h| 25 --
 drivers/scsi/qla2xxx/qla_init.c   | 14 ++--
 drivers/scsi/qla2xxx/qla_os.c |  2 +-
 drivers/scsi/qla2xxx/qla_target.c | 70 +++
 drivers/scsi/qla2xxx/qla_target.h |  3 +-
 6 files changed, 71 insertions(+), 45 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index f0f16d313faf..6dd984203666 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -2289,7 +2289,7 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha)
fc_host_dev_loss_tmo(vha->host) = ha->port_down_retry_count;
fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name);
fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name);
-   fc_host_supported_classes(vha->host) = ha->tgt.enable_class_2 ?
+   fc_host_supported_classes(vha->host) = ha->base_qpair->enable_class_2 ?
(FC_COS_CLASS2|FC_COS_CLASS3) : FC_COS_CLASS3;
fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports;
fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count;
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 0dec148a4580..dfa001357110 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3252,6 +3252,7 @@ struct qla_qpair {
 */
spinlock_t *qp_lock_ptr;
struct scsi_qla_host *vha;
+   u32 chip_reset;
 
/* distill these fields down to 'online=0/1'
 * ha->flags.eeh_busy
@@ -3263,6 +3264,8 @@ struct qla_qpair {
uint32_t difdix_supported:1;
uint32_t delete_in_progress:1;
uint32_t fw_started:1;
+   uint32_t enable_class_2:1;
+   uint32_t enable_explicit_conf:1;
 
uint16_t id;/* qp number used with FW */
uint16_t vp_idx;/* vport ID */
@@ -3296,8 +3299,6 @@ struct scsi_qlt_host {
 
 struct qlt_hw_data {
/* Protected by hw lock */
-   uint32_t enable_class_2:1;
-   uint32_t enable_explicit_conf:1;
uint32_t node_name_set:1;
 
dma_addr_t atio_dma;/* Physical address. */
@@ -3954,7 +3955,6 @@ struct qla_hw_data {
struct work_struct board_disable;
 
struct mr_data_fx00 mr;
-   uint32_t chip_reset;
 
struct qlt_hw_data tgt;
int allow_cna_fw_dump;
@@ -4247,6 +4247,25 @@ struct qla2_sgx {
 #define QLA_QPAIR_MARK_NOT_BUSY(__qpair)   \
atomic_dec(&__qpair->ref_count);\
 
+
+#define QLA_ENA_CONF(_ha) {\
+int i;\
+_ha->base_qpair->enable_explicit_conf = 1; \
+for (i = 0; i < _ha->max_qpairs; i++) {\
+   if (_ha->queue_pair_map[i]) \
+   _ha->queue_pair_map[i]->enable_explicit_conf = 1; \
+}  \
+}
+
+#define QLA_DIS_CONF(_ha) {\
+int i;\
+_ha->base_qpair->enable_explicit_conf = 0; \
+for (i = 0; i < _ha->max_qpairs; i++) {\
+   if (_ha->queue_pair_map[i]) \
+   _ha->queue_pair_map[i]->enable_explicit_conf = 0; \
+}  \
+}
+
 /*
  * qla2x00 local function return status codes
  */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index e6a1f9ca0e95..360abede3f6b 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1322,7 +1322,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host 
*vha, struct event_arg *ea)
ql_dbg(ql_dbg_disc, vha, 0x20ea,
"%s %d %8phC post gpdb\n",
__func__, __LINE__, ea->fcport->port_name);
-   ea->fcport->chip_reset = vha->hw->chip_reset;
+   ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
ea->fcport->logout_on_delete = 1;
qla24xx_post_gpdb_work(vha, ea->fcport, 0);
break;
@@ -5524,6 +5524,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
struct scsi_qla_host *vp;
unsigned long flags;
fc_port_t *fcport;
+   u16 i;
 
/* For ISP82XX, driver waits for completion of the commands.
 * online flag should be set.
@@ -5549,7 +5550,12 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
ha->current_topology = 0;
ha->flags.fw_started = 0;
ha->flags.fw_init_done = 0;
-   

[PATCH 03/15] qla2xxx: Enable Target Multi Queue

2017-06-07 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Enable Multi Queue for Target mode. At Initiator LUN scan time,
each LUN is assign to a QPair. Each QPair is assigned to a
certain CPU. When new cmd arrives from the wire, the lunid
is used to search for qpair. The qpair's assigned cpuid will
be used to queue up the work element.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h|   3 +-
 drivers/scsi/qla2xxx/qla_init.c   |   3 +
 drivers/scsi/qla2xxx/qla_inline.h |  28 +++
 drivers/scsi/qla2xxx/qla_isr.c|  21 +++--
 drivers/scsi/qla2xxx/qla_os.c |  56 +-
 drivers/scsi/qla2xxx/qla_target.c | 157 --
 drivers/scsi/qla2xxx/qla_target.h |  10 ++-
 7 files changed, 240 insertions(+), 38 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 64109134e276..005ca2de3795 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3245,7 +3245,7 @@ struct req_que {
 struct qla_qpair {
spinlock_t qp_lock;
atomic_t ref_count;
-
+   uint32_t lun_cnt;
/*
 * For qpair 0, qp_lock_ptr will point at hardware_lock due to
 * legacy code. For other Qpair(s), it will point at qp_lock.
@@ -3275,6 +3275,7 @@ struct qla_qpair {
struct qla_hw_data *hw;
struct work_struct q_work;
struct list_head qp_list_elem; /* vha->qp_list */
+   struct list_head hints_list;
uint16_t cpuid;
 };
 
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 7d0847b3d190..fa5e6ab8e4a7 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7623,6 +7623,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct 
scsi_qla_host *vha, int qos,
ha->queue_pair_map[qpair_id] = qpair;
qpair->id = qpair_id;
qpair->vp_idx = vp_idx;
+   INIT_LIST_HEAD(>hints_list);
 
for (i = 0; i < ha->msix_count; i++) {
msix = >msix_entries[i];
@@ -7666,6 +7667,8 @@ struct qla_qpair *qla2xxx_create_qpair(struct 
scsi_qla_host *vha, int qos,
qpair->req = ha->req_q_map[req_id];
qpair->rsp->req = qpair->req;
qpair->rsp->qpair = qpair;
+   /* init qpair to this cpu. Will adjust at run time. */
+   qla_cpu_update(qpair, smp_processor_id());
 
if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
if (ha->fw_attributes & BIT_4)
diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index 99028d48c664..bd8cb796f64e 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -324,3 +324,31 @@ qla_is_exch_offld_enabled(struct scsi_qla_host *vha)
else
return false;
 }
+
+static inline void
+qla_cpu_update(struct qla_qpair *qpair, uint16_t cpuid)
+{
+   qpair->cpuid = cpuid;
+
+   if (!list_empty(>hints_list)) {
+   struct qla_qpair_hint *h;
+
+   list_for_each_entry(h, >hints_list, hint_elem)
+   h->cpuid = qpair->cpuid;
+   }
+}
+
+static inline struct qla_qpair_hint *
+qla_qpair_to_hint(struct qla_tgt *tgt, struct qla_qpair *qpair)
+{
+   struct qla_qpair_hint *h;
+   u16 i;
+
+   for (i = 0; i < tgt->ha->max_qpairs + 1; i++) {
+   h = >qphints[i];
+   if (h->qpair == qpair)
+   return h;
+   }
+
+   return NULL;
+}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 1535a29a9d9f..9eb946cc8297 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -9,6 +9,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -2761,6 +2762,9 @@ void qla24xx_process_response_queue(struct scsi_qla_host 
*vha,
if (!ha->flags.fw_started)
return;
 
+   if (rsp->qpair->cpuid != smp_processor_id())
+   qla_cpu_update(rsp->qpair, smp_processor_id());
+
while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
 
@@ -3196,10 +3200,10 @@ struct qla_init_msix_entry {
 };
 
 static const struct qla_init_msix_entry msix_entries[] = {
-   { "qla2xxx (default)", qla24xx_msix_default },
-   { "qla2xxx (rsp_q)", qla24xx_msix_rsp_q },
-   { "qla2xxx (atio_q)", qla83xx_msix_atio_q },
-   { "qla2xxx (qpair_multiq)", qla2xxx_msix_rsp_q },
+   { "default", qla24xx_msix_default },
+   { "rsp_q", qla24xx_msix_rsp_q },
+   { "atio_q", qla83xx_msix_atio_q },
+   {

[PATCH 14/15] qla2xxx: Include Exchange offload/Extended Login into FW dump

2017-06-07 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Add missing memory dump of Exchange Offload and Extended
login into FW dump.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c  | 49 +
 drivers/scsi/qla2xxx/qla_dbg.h  | 11 +
 drivers/scsi/qla2xxx/qla_init.c |  7 ++
 drivers/scsi/qla2xxx/qla_os.c   |  3 ---
 4 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index c0c90dcc7c7b..f91ee717202d 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -498,6 +498,50 @@ qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, 
uint32_t **last_chain)
 }
 
 static inline void *
+qla25xx_copy_exlogin(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
+{
+   struct qla2xxx_offld_chain *c = ptr;
+
+   if (!ha->exlogin_buf)
+   return ptr;
+
+   *last_chain = >type;
+
+   c->type = cpu_to_be32(DUMP_CHAIN_EXLOGIN);
+   c->chain_size = cpu_to_be32(sizeof(struct qla2xxx_offld_chain) +
+   ha->exlogin_size);
+   c->size = cpu_to_be32(ha->exlogin_size);
+   c->addr = cpu_to_be64(ha->exlogin_buf_dma);
+
+   ptr += sizeof(struct qla2xxx_offld_chain);
+   memcpy(ptr, ha->exlogin_buf, ha->exlogin_size);
+
+   return (char *)ptr + cpu_to_be32(c->size);
+}
+
+static inline void *
+qla81xx_copy_exchoffld(struct qla_hw_data *ha, void *ptr, uint32_t 
**last_chain)
+{
+   struct qla2xxx_offld_chain *c = ptr;
+
+   if (!ha->exchoffld_buf)
+   return ptr;
+
+   *last_chain = >type;
+
+   c->type = cpu_to_be32(DUMP_CHAIN_EXCHG);
+   c->chain_size = cpu_to_be32(sizeof(struct qla2xxx_offld_chain) +
+   ha->exchoffld_size);
+   c->size = cpu_to_be32(ha->exchoffld_size);
+   c->addr = cpu_to_be64(ha->exchoffld_buf_dma);
+
+   ptr += sizeof(struct qla2xxx_offld_chain);
+   memcpy(ptr, ha->exchoffld_buf, ha->exchoffld_size);
+
+   return (char *)ptr + cpu_to_be32(c->size);
+}
+
+static inline void *
 qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr,
uint32_t **last_chain)
 {
@@ -1606,6 +1650,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, _chain);
nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, _chain);
nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, _chain);
+   nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, _chain);
if (last_chain) {
ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
*last_chain |= htonl(DUMP_CHAIN_LAST);
@@ -1932,6 +1977,8 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, _chain);
nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, _chain);
nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, _chain);
+   nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, _chain);
+   nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, _chain);
if (last_chain) {
ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
*last_chain |= htonl(DUMP_CHAIN_LAST);
@@ -2443,6 +2490,8 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, _chain);
nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, _chain);
nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, _chain);
+   nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, _chain);
+   nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, _chain);
if (last_chain) {
ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
*last_chain |= htonl(DUMP_CHAIN_LAST);
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index f60138f66dce..8877aa97d829 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -232,6 +232,15 @@ struct qla2xxx_fce_chain {
uint32_t eregs[8];
 };
 
+/* used by exchange off load and extended login offload */
+struct qla2xxx_offld_chain {
+   uint32_t type;
+   uint32_t chain_size;
+
+   uint32_t size;
+   u64  addr;
+};
+
 struct qla2xxx_mq_chain {
uint32_t type;
uint32_t chain_size;
@@ -258,6 +267,8 @@ struct qla2xxx_mqueue_chain {
 #define DUMP_CHAIN_FCE 0x7AF0
 #define DUMP_CHAIN_MQ  0x7AF1
 #define DUMP_CHAIN_QUEUE   0x7AF2
+#define DUMP_CHAIN_EXLOGIN 0x7AF3
+#define DUMP_CHAIN_EXCHG   0x7AF4
 #define DUMP_CHAIN_LAST0x8000
 
 struct qla2xxx_fw_dump {
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 48c0a58330d4..72d9ca138ffd 100644
--- a/driver

[PATCH 12/15] qla2xxx: Remove datasegs_per_cmd and datasegs_per_cont field

2017-06-07 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

These fields only hold one set of value. Replace it with macros.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 12 +---
 drivers/scsi/qla2xxx/qla_target.h |  2 +-
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 411c1799c6e3..48d82c67e223 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2228,10 +2228,10 @@ static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm)
 * If greater than four sg entries then we need to allocate
 * the continuation entries
 */
-   if (prm->seg_cnt > prm->tgt->datasegs_per_cmd)
+   if (prm->seg_cnt > QLA_TGT_DATASEGS_PER_CMD_24XX)
prm->req_cnt += DIV_ROUND_UP(prm->seg_cnt -
-   prm->tgt->datasegs_per_cmd,
-   prm->tgt->datasegs_per_cont);
+   QLA_TGT_DATASEGS_PER_CMD_24XX,
+   QLA_TGT_DATASEGS_PER_CONT_24XX);
} else {
/* DIF */
if ((cmd->se_cmd.prot_op == TARGET_PROT_DIN_INSERT) ||
@@ -2448,7 +2448,7 @@ static void qlt_load_cont_data_segments(struct 
qla_tgt_prm *prm)
 
/* Load continuation entry data segments */
for (cnt = 0;
-   cnt < prm->tgt->datasegs_per_cont && prm->seg_cnt;
+   cnt < QLA_TGT_DATASEGS_PER_CONT_24XX && prm->seg_cnt;
cnt++, prm->seg_cnt--) {
*dword_ptr++ =
cpu_to_le32(pci_dma_lo32
@@ -2492,7 +2492,7 @@ static void qlt_load_data_segments(struct qla_tgt_prm 
*prm)
 
/* Load command entry data segments */
for (cnt = 0;
-   (cnt < prm->tgt->datasegs_per_cmd) && prm->seg_cnt;
+   (cnt < QLA_TGT_DATASEGS_PER_CMD_24XX) && prm->seg_cnt;
cnt++, prm->seg_cnt--) {
*dword_ptr++ =
cpu_to_le32(pci_dma_lo32(sg_dma_address(prm->sg)));
@@ -6170,8 +6170,6 @@ int qlt_add_target(struct qla_hw_data *ha, struct 
scsi_qla_host *base_vha)
base_vha->vp_idx);
/* 3 is reserved */
tgt->sg_tablesize = QLA_TGT_MAX_SG_24XX(base_vha->req->length - 3);
-   tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX;
-   tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX;
 
mutex_lock(_tgt_mutex);
list_add_tail(>tgt_list_entry, _tgt_glist);
diff --git a/drivers/scsi/qla2xxx/qla_target.h 
b/drivers/scsi/qla2xxx/qla_target.h
index 902685f85506..7fe02d036bdf 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -806,7 +806,7 @@ struct qla_tgt {
 */
int atio_irq_cmd_count;
 
-   int datasegs_per_cmd, datasegs_per_cont, sg_tablesize;
+   int sg_tablesize;
 
/* Target's flags, serialized by pha->hardware_lock */
unsigned int link_reinit_iocb_pending:1;
-- 
2.12.0



[PATCH 06/15] qla2xxx: Add fw_started flags to qpair

2017-06-07 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Add fw_started flag to qpair to reduce access to
qla_hw_data structure by each qpair.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h| 21 +
 drivers/scsi/qla2xxx/qla_init.c   |  4 ++--
 drivers/scsi/qla2xxx/qla_isr.c|  4 ++--
 drivers/scsi/qla2xxx/qla_target.c |  6 ++
 4 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 18b37c864250..0dec148a4580 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3262,6 +3262,7 @@ struct qla_qpair {
/* move vha->flags.difdix_supported here */
uint32_t difdix_supported:1;
uint32_t delete_in_progress:1;
+   uint32_t fw_started:1;
 
uint16_t id;/* qp number used with FW */
uint16_t vp_idx;/* vport ID */
@@ -4183,6 +4184,26 @@ struct qla2_sgx {
srb_t   *sp;
 };
 
+#define QLA_FW_STARTED(_ha) {  \
+   int i;  \
+   _ha->flags.fw_started = 1;  \
+   _ha->base_qpair->fw_started = 1;\
+   for (i = 0; i < _ha->max_qpairs; i++) { \
+   if (_ha->queue_pair_map[i]) \
+   _ha->queue_pair_map[i]->fw_started = 1; \
+   }   \
+}
+
+#define QLA_FW_STOPPED(_ha) {  \
+   int i;  \
+   _ha->flags.fw_started = 0;  \
+   _ha->base_qpair->fw_started = 0;\
+   for (i = 0; i < _ha->max_qpairs; i++) { \
+   if (_ha->queue_pair_map[i]) \
+   _ha->queue_pair_map[i]->fw_started = 0; \
+   }   \
+}
+
 /*
  * Macros to help code, maintain, etc.
  */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index dcc306121a3d..e6a1f9ca0e95 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3207,7 +3207,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
} else {
ql_dbg(ql_dbg_init, vha, 0x00d3,
"Init Firmware -- success.\n");
-   ha->flags.fw_started = 1;
+   QLA_FW_STARTED(ha);
}
 
return (rval);
@@ -6841,7 +6841,7 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha)
ret = qla2x00_stop_firmware(vha);
}
 
-   ha->flags.fw_started = 0;
+   QLA_FW_STOPPED(ha);
ha->flags.fw_init_done = 0;
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 3c9f9aa7f2c2..7ebd92ee94c3 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -710,7 +710,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que 
*rsp, uint16_t *mb)
 
ha->isp_ops->fw_dump(vha, 1);
ha->flags.fw_init_done = 0;
-   ha->flags.fw_started = 0;
+   QLA_FW_STOPPED(ha);
 
if (IS_FWI2_CAPABLE(ha)) {
if (mb[1] == 0 && mb[2] == 0) {
@@ -2759,7 +2759,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host 
*vha,
struct sts_entry_24xx *pkt;
struct qla_hw_data *ha = vha->hw;
 
-   if (!ha->flags.fw_started)
+   if (!rsp->qpair->fw_started)
return;
 
if (rsp->qpair->cpuid != smp_processor_id())
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index cbe6ff9f663e..8e855093740c 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -3047,7 +3047,6 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int 
xmit_type,
uint8_t scsi_status)
 {
struct scsi_qla_host *vha = cmd->vha;
-   struct qla_hw_data *ha = vha->hw;
struct qla_qpair *qpair = cmd->qpair;
struct ctio7_to_24xx *pkt;
struct qla_tgt_prm prm;
@@ -3086,7 +3085,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int 
xmit_type,
else
vha->tgt_counters.core_qla_que_buf++;
 
-   if (!ha->flags.fw_started || cmd->reset_count != ha->chip_reset) {
+   if (!qpair->fw_started || cmd->reset_count != qpair->chip_reset) {
/*
 * Either the port is not online or this request was from
 * previous life, just abort the processing.
@@ -3206,7 +3205,6 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
 {
struct ctio7_to_24xx *pkt;
struct scsi_qla_host *vha = cmd->vha;
-   struct qla_hw_data *ha = vha->hw;
struct qla_tgt *tgt = cmd->tgt;
struct qla_tgt_prm prm;
unsigned long flags = 0;
@@ -3223,7

[PATCH 05/15] qla2xxx: Add debug knob for user control workload

2017-06-07 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

For Target mode, user can control the work load by placing qla2xxx's
irq vector on certain CPU via the smp_affinity settings. This patch
allows user to control the number of QPair's irq to be active. The
irqs are allocated at driver load time until unload. The work itself
is placed on the QPair based on user setting.

New module parameter ql2xuctrlirq is added for allowing user to
control IRQ affinity.

Usage:
  modprobe qla2xxx qlini_mode=disabled ql2xuctrlirq=1
  mount -t debugfs none /sys/kernel/debug
  echo 2 > /sys/kernel/debug/qla2xxx/qla2xxx_[host num]/naqp
  echo [cpu id] > /proc/irq/[irq id]/smp_affinity_list

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h|  7 ++-
 drivers/scsi/qla2xxx/qla_dfs.c| 89 +++
 drivers/scsi/qla2xxx/qla_gbl.h|  2 +
 drivers/scsi/qla2xxx/qla_isr.c| 11 +++--
 drivers/scsi/qla2xxx/qla_target.c | 32 ++
 5 files changed, 137 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 8b52f431a812..18b37c864250 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3322,6 +3322,7 @@ struct qlt_hw_data {
 
struct dentry *dfs_tgt_sess;
struct dentry *dfs_tgt_port_database;
+   struct dentry *dfs_naqp;
 
struct list_head q_full_list;
uint32_t num_pend_cmds;
@@ -3330,7 +3331,8 @@ struct qlt_hw_data {
spinlock_t q_full_lock;
uint32_t leak_exchg_thresh_hold;
spinlock_t sess_lock;
-   int rspq_vector_cpuid;
+   int num_act_qpairs;
+#define DEFAULT_NAQP 2
spinlock_t atio_lock cacheline_aligned;
struct btree_head32 host_map;
 };
@@ -4278,6 +4280,9 @@ enum nexus_wait_type {
WAIT_LUN,
 };
 
+#define USER_CTRL_IRQ(_ha) (ql2xuctrlirq && QLA_TGT_MODE_ENABLED() && \
+   (IS_QLA27XX(_ha) || IS_QLA83XX(_ha)))
+
 #include "qla_target.h"
 #include "qla_gbl.h"
 #include "qla_dbg.h"
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 391c50be2297..63d7374dce77 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -314,6 +314,81 @@ static const struct file_operations dfs_fce_ops = {
.release= qla2x00_dfs_fce_release,
 };
 
+static int
+qla_dfs_naqp_show(struct seq_file *s, void *unused)
+{
+   struct scsi_qla_host *vha = s->private;
+   struct qla_hw_data *ha = vha->hw;
+
+   seq_printf(s, "%d\n", ha->tgt.num_act_qpairs);
+   return 0;
+}
+
+static int
+qla_dfs_naqp_open(struct inode *inode, struct file *file)
+{
+   struct scsi_qla_host *vha = inode->i_private;
+
+   return single_open(file, qla_dfs_naqp_show, vha);
+}
+
+static ssize_t
+qla_dfs_naqp_write(struct file *file, const char __user *buffer,
+size_t count, loff_t *pos)
+{
+   struct seq_file *s = file->private_data;
+   struct scsi_qla_host *vha = s->private;
+   struct qla_hw_data *ha = vha->hw;
+   char *buf;
+   int rc = 0;
+   unsigned long num_act_qp;
+
+   if (!(IS_QLA27XX(ha) || IS_QLA83XX(ha))) {
+   pr_err("host%ld: this adapter does not support Multi Q.",
+   vha->host_no);
+   return -EINVAL;
+   }
+
+   if (!vha->flags.qpairs_available) {
+   pr_err("host%ld: Driver is not setup with Multi Q.",
+   vha->host_no);
+   return -EINVAL;
+   }
+   buf = memdup_user_nul(buffer, count);
+   if (IS_ERR(buf)) {
+   pr_err("host%ld: fail to copy user buffer.",
+   vha->host_no);
+   return PTR_ERR(buf);
+   }
+
+   num_act_qp = simple_strtoul(buf, NULL, 0);
+
+   if (num_act_qp >= vha->hw->max_qpairs) {
+   pr_err("User set invalid number of qpairs %lu. Max = %d",
+   num_act_qp, vha->hw->max_qpairs);
+   rc = -EINVAL;
+   goto out_free;
+   }
+
+   if (num_act_qp != ha->tgt.num_act_qpairs) {
+   ha->tgt.num_act_qpairs = num_act_qp;
+   qlt_clr_qp_table(vha);
+   }
+   rc = count;
+out_free:
+   kfree(buf);
+   return rc;
+}
+
+static const struct file_operations dfs_naqp_ops = {
+   .open   = qla_dfs_naqp_open,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release,
+   .write  = qla_dfs_naqp_write,
+};
+
+
 int
 qla2x00_dfs_setup(scsi_qla_host_t *vha)
 {
@@ -391,6 +466,15 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha)
goto out;
}
 
+   if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) {
+   

[PATCH 11/15] qla2xxx: Remove unused tgt_enable_64bit_addr flag

2017-06-07 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

By default this flag is forced to true. Remove this flag and
unneccessary check for this flag.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 44 ---
 drivers/scsi/qla2xxx/qla_target.h |  1 -
 2 files changed, 13 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 84be2b48246f..411c1799c6e3 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2420,12 +2420,10 @@ static int qlt_24xx_build_ctio_pkt(struct qla_qpair 
*qpair,
  * ha->hardware_lock supposed to be held on entry. We have already made sure
  * that there is sufficient amount of request entries to not drop it.
  */
-static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm,
-   struct scsi_qla_host *vha)
+static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm)
 {
int cnt;
uint32_t *dword_ptr;
-   int enable_64bit_addressing = prm->tgt->tgt_enable_64bit_addr;
 
/* Build continuation packets */
while (prm->seg_cnt > 0) {
@@ -2445,16 +2443,8 @@ static void qlt_load_cont_data_segments(struct 
qla_tgt_prm *prm,
cont_pkt64->entry_count = 1;
cont_pkt64->sys_define = 0;
 
-   if (enable_64bit_addressing) {
-   cont_pkt64->entry_type = CONTINUE_A64_TYPE;
-   dword_ptr =
-   (uint32_t *)_pkt64->dseg_0_address;
-   } else {
-   cont_pkt64->entry_type = CONTINUE_TYPE;
-   dword_ptr =
-   (uint32_t *)&((cont_entry_t *)
-   cont_pkt64)->dseg_0_address;
-   }
+   cont_pkt64->entry_type = CONTINUE_A64_TYPE;
+   dword_ptr = (uint32_t *)_pkt64->dseg_0_address;
 
/* Load continuation entry data segments */
for (cnt = 0;
@@ -2463,12 +2453,8 @@ static void qlt_load_cont_data_segments(struct 
qla_tgt_prm *prm,
*dword_ptr++ =
cpu_to_le32(pci_dma_lo32
(sg_dma_address(prm->sg)));
-   if (enable_64bit_addressing) {
-   *dword_ptr++ =
-   cpu_to_le32(pci_dma_hi32
-   (sg_dma_address
-   (prm->sg)));
-   }
+   *dword_ptr++ = cpu_to_le32(pci_dma_hi32
+   (sg_dma_address(prm->sg)));
*dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg));
 
prm->sg = sg_next(prm->sg);
@@ -2480,12 +2466,10 @@ static void qlt_load_cont_data_segments(struct 
qla_tgt_prm *prm,
  * ha->hardware_lock supposed to be held on entry. We have already made sure
  * that there is sufficient amount of request entries to not drop it.
  */
-static void qlt_load_data_segments(struct qla_tgt_prm *prm,
-   struct scsi_qla_host *vha)
+static void qlt_load_data_segments(struct qla_tgt_prm *prm)
 {
int cnt;
uint32_t *dword_ptr;
-   int enable_64bit_addressing = prm->tgt->tgt_enable_64bit_addr;
struct ctio7_to_24xx *pkt24 = (struct ctio7_to_24xx *)prm->pkt;
 
pkt24->u.status0.transfer_length = cpu_to_le32(prm->cmd->bufflen);
@@ -2512,17 +2496,16 @@ static void qlt_load_data_segments(struct qla_tgt_prm 
*prm,
cnt++, prm->seg_cnt--) {
*dword_ptr++ =
cpu_to_le32(pci_dma_lo32(sg_dma_address(prm->sg)));
-   if (enable_64bit_addressing) {
-   *dword_ptr++ =
-   cpu_to_le32(pci_dma_hi32(
-   sg_dma_address(prm->sg)));
-   }
+
+   *dword_ptr++ = cpu_to_le32(pci_dma_hi32(
+   sg_dma_address(prm->sg)));
+
*dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg));
 
prm->sg = sg_next(prm->sg);
}
 
-   qlt_load_cont_data_segments(prm, vha);
+   qlt_load_cont_data_segments(prm);
 }
 
 static inline int qlt_has_data(struct qla_tgt_cmd *cmd)
@@ -3136,7 +3119,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int 
xmit_type,
CTIO7_FLAGS_STATUS_MODE_0);
 
if (cmd->se_cmd.prot_op == TARGET_PROT_NORMAL)
-   qlt_load_data_segments(, vha);
+   qlt_load_data_segments();
 
if (prm.add_status_pkt == 0) {
if (xmit_type & QLA_TGT_XMIT_STATUS) {
@@ -3272,7 +3255,7 @@ int qlt_rdy_

[PATCH 15/15] qla2xxx: Update driver version to 9.01.00.00-k

2017-06-07 Thread Himanshu Madhani
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
Signed-off-by: Giridhar Malavali <giridhar.malav...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_version.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_version.h 
b/drivers/scsi/qla2xxx/qla_version.h
index 45bc84e8e3bf..dcbb9bb05e99 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,9 +7,9 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION  "9.00.00.00-k"
+#define QLA2XXX_VERSION  "9.01.00.00-k"
 
 #define QLA_DRIVER_MAJOR_VER   9
-#define QLA_DRIVER_MINOR_VER   0
+#define QLA_DRIVER_MINOR_VER   1
 #define QLA_DRIVER_PATCH_VER   0
 #define QLA_DRIVER_BETA_VER0
-- 
2.12.0



[PATCH 10/15] qla2xxx: Add debug logging routine for qpair

2017-06-07 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

For target main path io routines that uses qpair, create new
logging and debugging routines to use qpair instead of reaching
for scsi_qla_host.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c| 101 ++
 drivers/scsi/qla2xxx/qla_dbg.h|   6 +++
 drivers/scsi/qla2xxx/qla_target.c |  28 +--
 drivers/scsi/qla2xxx/qla_target.h |   1 +
 4 files changed, 122 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 11e097e123bd..c0c90dcc7c7b 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -2713,3 +2713,104 @@ ql_dump_buffer(uint32_t level, scsi_qla_host_t *vha, 
int32_t id,
   buf + cnt, min(16U, size - cnt), false);
}
 }
+
+/*
+ * This function is for formatting and logging log messages.
+ * It is to be used when vha is available. It formats the message
+ * and logs it to the messages file. All the messages will be logged
+ * irrespective of value of ql2xextended_error_logging.
+ * parameters:
+ * level: The level of the log messages to be printed in the
+ *messages file.
+ * vha:   Pointer to the scsi_qla_host_t
+ * id:This is a unique id for the level. It identifies the
+ *part of the code from where the message originated.
+ * msg:   The message to be displayed.
+ */
+void
+ql_log_qp(uint32_t level, struct qla_qpair *qpair, int32_t id,
+const char *fmt, ...)
+{
+   va_list va;
+   struct va_format vaf;
+   char pbuf[128];
+
+   if (level > ql_errlev)
+   return;
+
+   if (qpair != NULL) {
+   const struct pci_dev *pdev = qpair->pdev;
+   /*  : Message */
+   snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: ",
+   QL_MSGHDR, dev_name(&(pdev->dev)), id);
+   } else {
+   snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ",
+   QL_MSGHDR, ":00:00.0", id);
+   }
+   pbuf[sizeof(pbuf) - 1] = 0;
+
+   va_start(va, fmt);
+
+   vaf.fmt = fmt;
+   vaf.va = 
+
+   switch (level) {
+   case ql_log_fatal: /* FATAL LOG */
+   pr_crit("%s%pV", pbuf, );
+   break;
+   case ql_log_warn:
+   pr_err("%s%pV", pbuf, );
+   break;
+   case ql_log_info:
+   pr_warn("%s%pV", pbuf, );
+   break;
+   default:
+   pr_info("%s%pV", pbuf, );
+   break;
+   }
+
+   va_end(va);
+}
+
+/*
+ * This function is for formatting and logging debug information.
+ * It is to be used when vha is available. It formats the message
+ * and logs it to the messages file.
+ * parameters:
+ * level: The level of the debug messages to be printed.
+ *If ql2xextended_error_logging value is correctly set,
+ *this message will appear in the messages file.
+ * vha:   Pointer to the scsi_qla_host_t.
+ * id:This is a unique identifier for the level. It identifies the
+ *part of the code from where the message originated.
+ * msg:   The message to be displayed.
+ */
+void
+ql_dbg_qp(uint32_t level, struct qla_qpair *qpair, int32_t id,
+const char *fmt, ...)
+{
+   va_list va;
+   struct va_format vaf;
+
+   if (!ql_mask_match(level))
+   return;
+
+   va_start(va, fmt);
+
+   vaf.fmt = fmt;
+   vaf.va = 
+
+   if (qpair != NULL) {
+   const struct pci_dev *pdev = qpair->pdev;
+   /*   : Message */
+   pr_warn("%s [%s]-%04x: %pV",
+   QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset,
+   );
+   } else {
+   pr_warn("%s [%s]-%04x: : %pV",
+   QL_MSGHDR, ":00:00.0", id + ql_dbg_offset, );
+   }
+
+   va_end(va);
+
+}
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index c6bffe929fe7..f60138f66dce 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -313,12 +313,18 @@ void __attribute__((format (printf, 4, 5)))
 ql_dbg(uint32_t, scsi_qla_host_t *vha, int32_t, const char *fmt, ...);
 void __attribute__((format (printf, 4, 5)))
 ql_dbg_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...);
+void __attribute__((format (printf, 4, 5)))
+ql_dbg_qp(uint32_t, struct qla_qpair *, int32_t, const char *fmt, ...);
+
 
 void __attribute__((format (printf, 4, 5)))
 ql_log(uint32_t, scsi_qla_host_t *vha, int32_t, const char *fmt, ...);
 void __attribute__((format (printf, 4, 5)))
 ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...);
 
+void __attribute__((format 

[PATCH 09/15] qla2xxx: Add function call to qpair for door bell

2017-06-07 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Add call back to door bell for qpair. This help reduce access
to qla_hw_data structure.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h|  3 ++
 drivers/scsi/qla2xxx/qla_init.c   |  3 ++
 drivers/scsi/qla2xxx/qla_inline.h | 15 +
 drivers/scsi/qla2xxx/qla_os.c | 35 ---
 drivers/scsi/qla2xxx/qla_target.c | 71 +++
 drivers/scsi/qla2xxx/qla_target.h |  2 +-
 6 files changed, 94 insertions(+), 35 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index b3ba32773db4..17b13dd92511 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3272,6 +3272,9 @@ struct qla_qpair {
uint16_t vp_idx;/* vport ID */
mempool_t *srb_mempool;
 
+   struct pci_dev  *pdev;
+   void (*reqq_start_iocbs)(struct qla_qpair *);
+
/* to do: New driver: move queues to here instead of pointers */
struct req_que *req;
struct rsp_que *rsp;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f586f4f7dc57..48c0a58330d4 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7653,6 +7653,9 @@ struct qla_qpair *qla2xxx_create_qpair(struct 
scsi_qla_host *vha, int qos,
 
qpair->msix->in_use = 1;
list_add_tail(>qp_list_elem, >qp_list);
+   qpair->pdev = ha->pdev;
+   if (IS_QLA27XX(ha) || IS_QLA83XX(ha))
+   qpair->reqq_start_iocbs = qla_83xx_start_iocbs;
 
mutex_unlock(>mq_lock);
 
diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index bd8cb796f64e..9a2c86eacf44 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -352,3 +352,18 @@ qla_qpair_to_hint(struct qla_tgt *tgt, struct qla_qpair 
*qpair)
 
return NULL;
 }
+
+static inline void
+qla_83xx_start_iocbs(struct qla_qpair *qpair)
+{
+   struct req_que *req = qpair->req;
+
+   req->ring_index++;
+   if (req->ring_index == req->length) {
+   req->ring_index = 0;
+   req->ring_ptr = req->ring;
+   } else
+   req->ring_ptr++;
+
+   WRT_REG_DWORD(req->req_q_in, req->ring_index);
+}
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 1d66954b7e5a..88e115fcea60 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -351,6 +351,28 @@ int qla2xxx_mqueuecommand(struct Scsi_Host *host, struct 
scsi_cmnd *cmd,
struct qla_qpair *qpair);
 
 /* -- 
*/
+static void qla_init_base_qpair(struct scsi_qla_host *vha, struct req_que *req,
+struct rsp_que *rsp)
+{
+   struct qla_hw_data *ha = vha->hw;
+   rsp->qpair = ha->base_qpair;
+   rsp->req = req;
+   ha->base_qpair->req = req;
+   ha->base_qpair->rsp = rsp;
+   ha->base_qpair->vha = vha;
+   ha->base_qpair->qp_lock_ptr = >hardware_lock;
+   ha->base_qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0;
+   ha->base_qpair->msix = >msix_entries[QLA_MSIX_RSP_Q];
+   INIT_LIST_HEAD(>base_qpair->hints_list);
+   ha->base_qpair->enable_class_2 = ql2xenableclass2;
+   /* init qpair to this cpu. Will adjust at run time. */
+   qla_cpu_update(rsp->qpair, smp_processor_id());
+   ha->base_qpair->pdev = ha->pdev;
+
+   if (IS_QLA27XX(ha) || IS_QLA83XX(ha))
+   ha->base_qpair->reqq_start_iocbs = qla_83xx_start_iocbs;
+}
+
 static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req,
struct rsp_que *rsp)
 {
@@ -378,18 +400,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, 
struct req_que *req,
goto fail_base_qpair;
}
 
-   rsp->qpair = ha->base_qpair;
-   rsp->req = req;
-   ha->base_qpair->req = req;
-   ha->base_qpair->rsp = rsp;
-   ha->base_qpair->vha = vha;
-   ha->base_qpair->qp_lock_ptr = >hardware_lock;
-   ha->base_qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0;
-   /* init qpair to this cpu. Will adjust at run time. */
-   ha->base_qpair->msix = >msix_entries[QLA_MSIX_RSP_Q];
-   INIT_LIST_HEAD(>base_qpair->hints_list);
-   ha->base_qpair->enable_class_2 = ql2xenableclass2;
-   qla_cpu_update(rsp->qpair, smp_processor_id());
+   qla_init_base_qpair(vha, req, rsp);
 
if (ql2xmqsupport && ha->max_qpairs) {
ha->queue_pair_map =

[PATCH 13/15] qla2xxx: Move target stat counters from vha to qpair.

2017-06-07 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h | 27 +++--
 drivers/scsi/qla2xxx/qla_dfs.c | 48 +++---
 drivers/scsi/qla2xxx/qla_iocb.c|  2 +-
 drivers/scsi/qla2xxx/qla_target.c  | 13 +--
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  8 +++
 5 files changed, 63 insertions(+), 35 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 17b13dd92511..e1af9db3691d 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3183,6 +3183,18 @@ struct qla_tc_param {
 #define QLA_MAX_VPORTS_QLA24XX 128
 #define QLA_MAX_VPORTS_QLA25XX 256
 
+struct qla_tgt_counters {
+   uint64_t qla_core_sbt_cmd;
+   uint64_t core_qla_que_buf;
+   uint64_t qla_core_ret_ctio;
+   uint64_t core_qla_snd_status;
+   uint64_t qla_core_ret_sta_ctio;
+   uint64_t core_qla_free_cmd;
+   uint64_t num_q_full_sent;
+   uint64_t num_alloc_iocb_failed;
+   uint64_t num_term_xchg_sent;
+};
+
 struct qla_qpair;
 
 /* Response queue data structure */
@@ -3285,6 +3297,7 @@ struct qla_qpair {
struct list_head qp_list_elem; /* vha->qp_list */
struct list_head hints_list;
uint16_t cpuid;
+   struct qla_tgt_counters tgt_counters;
 };
 
 /* Place holder for FW buffer parameters */
@@ -3964,18 +3977,6 @@ struct qla_hw_data {
int allow_cna_fw_dump;
 };
 
-struct qla_tgt_counters {
-   uint64_t qla_core_sbt_cmd;
-   uint64_t core_qla_que_buf;
-   uint64_t qla_core_ret_ctio;
-   uint64_t core_qla_snd_status;
-   uint64_t qla_core_ret_sta_ctio;
-   uint64_t core_qla_free_cmd;
-   uint64_t num_q_full_sent;
-   uint64_t num_alloc_iocb_failed;
-   uint64_t num_term_xchg_sent;
-};
-
 /*
  * Qlogic scsi host structure
  */
@@ -4140,10 +4141,8 @@ typedef struct scsi_qla_host {
struct fc_host_statistics fc_host_stat;
struct qla_statistics qla_stats;
struct bidi_statistics bidi_stats;
-
atomic_tvref_count;
struct qla8044_reset_template reset_tmplt;
-   struct qla_tgt_counters tgt_counters;
uint16_tbbcr;
struct name_list_extended gnl;
/* Count of active session/fcport */
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 63d7374dce77..d231e7156134 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -164,26 +164,56 @@ static int
 qla_dfs_tgt_counters_show(struct seq_file *s, void *unused)
 {
struct scsi_qla_host *vha = s->private;
+   struct qla_qpair *qpair = vha->hw->base_qpair;
+   uint64_t qla_core_sbt_cmd, core_qla_que_buf, qla_core_ret_ctio,
+   core_qla_snd_status, qla_core_ret_sta_ctio, core_qla_free_cmd,
+   num_q_full_sent, num_alloc_iocb_failed, num_term_xchg_sent;
+   u16 i;
+
+   qla_core_sbt_cmd = qpair->tgt_counters.qla_core_sbt_cmd;
+   core_qla_que_buf = qpair->tgt_counters.core_qla_que_buf;
+   qla_core_ret_ctio = qpair->tgt_counters.qla_core_ret_ctio;
+   core_qla_snd_status = qpair->tgt_counters.core_qla_snd_status;
+   qla_core_ret_sta_ctio = qpair->tgt_counters.qla_core_ret_sta_ctio;
+   core_qla_free_cmd = qpair->tgt_counters.core_qla_free_cmd;
+   num_q_full_sent = qpair->tgt_counters.num_q_full_sent;
+   num_alloc_iocb_failed = qpair->tgt_counters.num_alloc_iocb_failed;
+   num_term_xchg_sent = qpair->tgt_counters.num_term_xchg_sent;
+
+   for (i = 0; i < vha->hw->max_qpairs; i++) {
+   qpair = vha->hw->queue_pair_map[i];
+   qla_core_sbt_cmd += qpair->tgt_counters.qla_core_sbt_cmd;
+   core_qla_que_buf += qpair->tgt_counters.core_qla_que_buf;
+   qla_core_ret_ctio += qpair->tgt_counters.qla_core_ret_ctio;
+   core_qla_snd_status += qpair->tgt_counters.core_qla_snd_status;
+   qla_core_ret_sta_ctio +=
+   qpair->tgt_counters.qla_core_ret_sta_ctio;
+   core_qla_free_cmd += qpair->tgt_counters.core_qla_free_cmd;
+   num_q_full_sent += qpair->tgt_counters.num_q_full_sent;
+   num_alloc_iocb_failed +=
+   qpair->tgt_counters.num_alloc_iocb_failed;
+   num_term_xchg_sent += qpair->tgt_counters.num_term_xchg_sent;
+   }
 
seq_puts(s, "Target Counters\n");
seq_printf(s, "qla_core_sbt_cmd = %lld\n",
-   vha->tgt_counters.qla_core_sbt_cmd);
+   qla_core_sbt_cmd);
seq_printf(s, "qla_core_ret_sta_ctio = %lld\n",
-   vha->tgt_counters.qla_core_ret_sta_ctio);
+   qla_core_ret_sta_ctio);

[PATCH 3/6] qla2xxx: Add FC-NVMe F/W initialization and transport registration

2017-06-16 Thread Himanshu Madhani
From: Duane Grigsby <duane.grig...@cavium.com>

This code provides the interfaces to register remote and local ports
of FC4 type 0x28 with the FC-NVMe transport and transports the
requests (FC-NVMe FC link services and FC-NVMe commands IUs) to the
fabric. It also provides the support for allocating h/w queues and
aborting FC-NVMe FC requests.

Signed-off-by: Darren Trapp <darren.tr...@cavium.com>
Signed-off-by: Duane Grigsby <duane.grig...@cavium.com>
Signed-off-by: Anil Gurumurthy <anil.gurumur...@cavium.com>
Signed-off-by: Giridhar Malavali <giridhar.malav...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/Makefile   |   2 +-
 drivers/scsi/qla2xxx/qla_dbg.c  |   2 +-
 drivers/scsi/qla2xxx/qla_def.h  |   3 +
 drivers/scsi/qla2xxx/qla_gbl.h  |  27 ++
 drivers/scsi/qla2xxx/qla_init.c |   8 +
 drivers/scsi/qla2xxx/qla_iocb.c |  36 ++
 drivers/scsi/qla2xxx/qla_isr.c  |  19 +
 drivers/scsi/qla2xxx/qla_mbx.c  |  22 ++
 drivers/scsi/qla2xxx/qla_nvme.c | 797 
 drivers/scsi/qla2xxx/qla_nvme.h | 132 +++
 drivers/scsi/qla2xxx/qla_os.c   |  40 +-
 11 files changed, 1079 insertions(+), 9 deletions(-)
 create mode 100644 drivers/scsi/qla2xxx/qla_nvme.c
 create mode 100644 drivers/scsi/qla2xxx/qla_nvme.h

diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile
index 44def6bb4bb0..0b767a0bb308 100644
--- a/drivers/scsi/qla2xxx/Makefile
+++ b/drivers/scsi/qla2xxx/Makefile
@@ -1,6 +1,6 @@
 qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \
-   qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o
+   qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o qla_nvme.o
 
 obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
 obj-$(CONFIG_TCM_QLA2XXX) += tcm_qla2xxx.o
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index cf4f47603a91..d840529fc023 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -15,7 +15,7 @@
  * |  || 0x015b-0x0160 |
  * |  || 0x016e
|
  * | Mailbox commands |   0x1199   | 0x1193
|
- * | Device Discovery |   0x2131   | 0x210e-0x2116  |
+ * | Device Discovery |   0x2134   | 0x210e-0x2116  |
  * | || 0x211a |
  * |  || 0x211c-0x2128  |
  * |  || 0x212a-0x2130  |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 693c42392886..c1edfa55b071 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -37,6 +37,7 @@
 #include "qla_bsg.h"
 #include "qla_nx.h"
 #include "qla_nx2.h"
+#include "qla_nvme.h"
 #define QLA2XXX_DRIVER_NAME"qla2xxx"
 #define QLA2XXX_APIDEV "ql2xapidev"
 #define QLA2XXX_MANUFACTURER   "QLogic Corporation"
@@ -423,6 +424,7 @@ struct srb_iocb {
int rsp_len;
dma_addr_t cmd_dma;
dma_addr_t rsp_dma;
+   enum nvmefc_fcp_datadir dir;
uint32_t dl;
uint32_t timeout_sec;
} nvme;
@@ -452,6 +454,7 @@ struct srb_iocb {
 #define SRB_NACK_PRLI  17
 #define SRB_NACK_LOGO  18
 #define SRB_NVME_CMD   19
+#define SRB_NVME_LS20
 #define SRB_PRLI_CMD   21
 
 enum {
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 6fbee11c1a18..fc2c03bda731 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -10,6 +10,32 @@
 #include 
 
 /*
+ * Global functions prototype in qla_nvme.c source file.
+ */
+extern void qla_nvme_register_hba(scsi_qla_host_t *);
+extern int  qla_nvme_register_remote(scsi_qla_host_t *, fc_port_t *);
+extern void qla_nvme_delete(scsi_qla_host_t *);
+extern void qla_nvme_abort(struct qla_hw_data *, srb_t *sp);
+extern void qla_nvme_unregister_remote_port(struct work_struct *);
+extern int qla_nvme_wait_on_rport_del(fc_port_t *);
+extern void qla_nvme_abort_all(fc_port_t *);
+extern int qla_nvme_post_cmd(struct nvme_fc_local_port *,
+struct nvme_fc_remote_port *, void *, struct nvmefc_fcp_req *);
+extern int qla_nvme_alloc_queue(struct nvme_fc_local_port *, unsigned int,
+u16, void **);
+extern int qla_nvme_hba_scan(scsi_qla_host_t *);
+extern void qla_nvme_ls_abort(struct nvme_fc_local_port *,
+struct nvme_fc_remote_port *, struct nvmefc_ls_req *);
+extern int qla_nvme_ls_req(struct nvme_fc_local_port *,
+struct nvme_fc_remote_port *, struct nvmefc_ls_req *);
+extern void ql

[PATCH 4/6] qla2xxx: Send FC4 type NVMe to the management server

2017-06-16 Thread Himanshu Madhani
From: Duane Grigsby <duane.grig...@cavium.com>

This patch adds switch command support for FC-4 type of FC-NVMe (0x28)
for resgistering HBA port to the management server. RFT_ID command is
used to register FC-4 type of 0x28 and RFF_ID is used to register
FC-4 features bits for FC-NVMe port.

Signed-off-by: Darren Trapp <darren.tr...@cavium.com>
Signed-off-by: Duane Grigsby <duane.grig...@cavium.com>
Signed-off-by: Anil Gurumurthy <anil.gurumur...@cavium.com>
Signed-off-by: Giridhar Malavali <giridhar.malav...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h  |   1 +
 drivers/scsi/qla2xxx/qla_gbl.h  |   6 +-
 drivers/scsi/qla2xxx/qla_gs.c   | 118 +++-
 drivers/scsi/qla2xxx/qla_init.c |  11 +++-
 4 files changed, 131 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index c1edfa55b071..c68c1cb1aadf 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2866,6 +2866,7 @@ struct ct_sns_rsp {
} gpsc;
 
 #define GFF_FCP_SCSI_OFFSET7
+#define GFF_NVME_OFFSET23 /* type = 28h */
struct {
uint8_t fc4_features[128];
} gff_id;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index fc2c03bda731..1a2b5b791e22 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -34,6 +34,7 @@ extern void qla_nvme_fcp_abort(struct nvme_fc_local_port *,
 struct nvme_fc_remote_port *, void *, struct nvmefc_fcp_req *);
 extern void qla24xx_nvme_ls4_iocb(scsi_qla_host_t *, struct pt_ls4_request *,
 struct req_que *);
+extern void qla24xx_async_gffid_sp_done(void *, int);
 
 /*
  * Global Function Prototypes in qla_init.c source file.
@@ -634,7 +635,7 @@ extern int qla2x00_gpn_id(scsi_qla_host_t *, sw_info_t *);
 extern int qla2x00_gnn_id(scsi_qla_host_t *, sw_info_t *);
 extern void qla2x00_gff_id(scsi_qla_host_t *, sw_info_t *);
 extern int qla2x00_rft_id(scsi_qla_host_t *);
-extern int qla2x00_rff_id(scsi_qla_host_t *);
+extern int qla2x00_rff_id(scsi_qla_host_t *, u8);
 extern int qla2x00_rnn_id(scsi_qla_host_t *);
 extern int qla2x00_rsnn_nn(scsi_qla_host_t *);
 extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
@@ -660,7 +661,8 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *, struct 
event_arg *);
 int qla24xx_post_gpsc_work(struct scsi_qla_host *, fc_port_t *);
 int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *);
 int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
-
+void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea);
+int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport);
 /*
  * Global Function Prototypes in qla_attr.c source file.
  */
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 540fec524ccb..c91478529b51 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -550,6 +550,8 @@ qla2x00_rft_id(scsi_qla_host_t *vha)
 
ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */
 
+   if (vha->flags.nvme_enabled)
+   ct_req->req.rft_id.fc4_types[6] = 1;/* NVMe type 28h */
/* Execute MS IOCB */
rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
sizeof(ms_iocb_entry_t));
@@ -575,7 +577,7 @@ qla2x00_rft_id(scsi_qla_host_t *vha)
  * Returns 0 on success.
  */
 int
-qla2x00_rff_id(scsi_qla_host_t *vha)
+qla2x00_rff_id(scsi_qla_host_t *vha, u8 type)
 {
int rval;
struct qla_hw_data *ha = vha->hw;
@@ -613,7 +615,7 @@ qla2x00_rff_id(scsi_qla_host_t *vha)
 
qlt_rff_id(vha, ct_req);
 
-   ct_req->req.rff_id.fc4_type = 0x08; /* SCSI - FCP */
+   ct_req->req.rff_id.fc4_type = type; /* SCSI - FCP */
 
/* Execute MS IOCB */
rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
@@ -2754,6 +2756,10 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
list[i].fc4_type = FC4_TYPE_FCP_SCSI;
else
list[i].fc4_type = FC4_TYPE_OTHER;
+
+   list[i].fc4f_nvme =
+   ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
+   list[i].fc4f_nvme &= 0xf;
}
 
/* Last device exit. */
@@ -3305,3 +3311,111 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t 
*id)
 done:
return rval;
 }
+
+void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea)
+{
+   fc_port_t *fcport = ea->fcport;
+
+   qla24xx_post_gnl_work(vha, fcport);
+}
+
+void qla24xx_async_gffid_sp_done(void *s, int res)
+{
+   struct srb *sp = s;
+   struct scsi_qla_host *vha = sp->

[PATCH 1/6] qla2xxx: Add FC-NVMe port discovery and PRLI handling

2017-06-16 Thread Himanshu Madhani
From: Duane Grigsby <duane.grig...@cavium.com>

Signed-off-by: Darren Trapp <darren.tr...@cavium.com>
Signed-off-by: Duane Grigsby <duane.grig...@cavium.com>
Signed-off-by: Anil Gurumurthy <anil.gurumur...@cavium.com>
Signed-off-by: Giridhar Malavali <giridhar.malav...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c|   9 +-
 drivers/scsi/qla2xxx/qla_def.h|  31 ++-
 drivers/scsi/qla2xxx/qla_fw.h |  13 ++-
 drivers/scsi/qla2xxx/qla_gbl.h|   1 +
 drivers/scsi/qla2xxx/qla_init.c   | 168 --
 drivers/scsi/qla2xxx/qla_iocb.c   |  21 +
 drivers/scsi/qla2xxx/qla_mbx.c|  33 +---
 drivers/scsi/qla2xxx/qla_os.c |   4 +
 drivers/scsi/qla2xxx/qla_target.c |   4 +-
 9 files changed, 257 insertions(+), 27 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index c0c90dcc7c7b..cf4f47603a91 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -15,9 +15,10 @@
  * |  || 0x015b-0x0160 |
  * |  || 0x016e
|
  * | Mailbox commands |   0x1199   | 0x1193
|
- * | Device Discovery |   0x2004   | 0x2016
|
- * |  || 0x2011-0x2012, |
- * |  || 0x2099-0x20a4  |
+ * | Device Discovery |   0x2131   | 0x210e-0x2116  |
+ * | || 0x211a |
+ * |  || 0x211c-0x2128  |
+ * |  || 0x212a-0x2130  |
  * | Queue Command and IO tracing |   0x3074   | 0x300b |
  * |  || 0x3027-0x3028  |
  * |  || 0x303d-0x3041  |
@@ -59,7 +60,7 @@
  * |  || 0xb13c-0xb140  |
  * |  || 0xb149
|
  * | MultiQ   |   0xc010   |   |
- * | Misc |   0xd301   | 0xd031-0xd0ff |
+ * | Misc |   0xd302   | 0xd031-0xd0ff |
  * |  || 0xd101-0xd1fe |
  * |  || 0xd214-0xd2fe |
  * | Target Mode |   0xe081   ||
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index e1af9db3691d..bd1b3fef95a4 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -343,6 +343,7 @@ struct srb_iocb {
 #define SRB_LOGIN_RETRIED  BIT_0
 #define SRB_LOGIN_COND_PLOGI   BIT_1
 #define SRB_LOGIN_SKIP_PRLIBIT_2
+#define SRB_LOGIN_NVME_PRLIBIT_3
uint16_t data[2];
u32 iop[2];
} logio;
@@ -436,6 +437,7 @@ struct srb_iocb {
 #define SRB_NACK_PLOGI 16
 #define SRB_NACK_PRLI  17
 #define SRB_NACK_LOGO  18
+#define SRB_PRLI_CMD   21
 
 enum {
TYPE_SRB,
@@ -1088,6 +1090,7 @@ struct mbx_cmd_32 {
 #defineMBX_1   BIT_1
 #defineMBX_0   BIT_0
 
+#define RNID_TYPE_PORT_LOGIN   0x7
 #define RNID_TYPE_SET_VERSION  0x9
 #define RNID_TYPE_ASIC_TEMP0xC
 
@@ -2152,10 +2155,12 @@ typedef struct {
uint8_t fabric_port_name[WWN_SIZE];
uint16_t fp_speed;
uint8_t fc4_type;
+   uint8_t fc4f_nvme;  /* nvme fc4 feature bits */
 } sw_info_t;
 
 /* FCP-4 types */
 #define FC4_TYPE_FCP_SCSI  0x08
+#define FC4_TYPE_NVME  0x28
 #define FC4_TYPE_OTHER 0x0
 #define FC4_TYPE_UNKNOWN   0xff
 
@@ -2180,7 +2185,8 @@ typedef enum {
FCT_SWITCH,
FCT_BROADCAST,
FCT_INITIATOR,
-   FCT_TARGET
+   FCT_TARGET,
+   FCT_NVME
 } fc_port_type_t;
 
 enum qla_sess_deletion {
@@ -2237,10 +2243,12 @@ enum fcport_mgt_event {
FCME_RSCN,
FCME_GIDPN_DONE,
FCME_PLOGI_DONE,/* Initiator side sent LLIOCB */
+   FCME_PRLI_DONE,
FCME_GNL_DONE,
FCME_GPSC_DONE,
FCME_GPDB_DONE,
FCME_GPNID_DONE,
+   FCME_GFFID_DONE,
FCME_DELETE_DONE,
 };
 
@@ -2274,6 +2282,16 @@ typedef struct fc_port {
unsigned int login_pause:1;
unsigned int login_succ:1;
 
+   struct work_struct nvme_del_work;
+   atomic_t nvme_ref_count;
+   uint32_t nvme_prli_service_param;
+#define NVME_PRLI_SP_CONF   BIT_7
+#define NVME_PRLI_SP_INITIATOR  BIT_5
+#define NVME_PRLI_SP_TARGET BIT_4
+#define NVME_PRLI_SP_DISCOVERY  BIT_3
+   uint8_t nvme_flag;
+#define NVME_FLAG_REGISTERED 4
+
struct fc_p

[PATCH 2/6] qla2xxx: Add FC-NVMe command handling

2017-06-16 Thread Himanshu Madhani
From: Duane Grigsby <duane.grig...@cavium.com>

Signed-off-by: Darren Trapp <darren.tr...@cavium.com>
Signed-off-by: Duane Grigsby <duane.grig...@cavium.com>
Signed-off-by: Anil Gurumurthy <anil.gurumur...@cavium.com>
Signed-off-by: Giridhar Malavali <giridhar.malav...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h | 17 +
 drivers/scsi/qla2xxx/qla_fw.h  | 28 --
 drivers/scsi/qla2xxx/qla_isr.c | 86 ++
 drivers/scsi/qla2xxx/qla_os.c  | 18 -
 4 files changed, 144 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index bd1b3fef95a4..693c42392886 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -412,6 +412,20 @@ struct srb_iocb {
struct {
struct imm_ntfy_from_isp *ntfy;
} nack;
+   struct {
+   __le16 comp_status;
+   uint16_t rsp_pyld_len;
+   uint8_t aen_op;
+   void *desc;
+
+   /* These are only used with ls4 requests */
+   int cmd_len;
+   int rsp_len;
+   dma_addr_t cmd_dma;
+   dma_addr_t rsp_dma;
+   uint32_t dl;
+   uint32_t timeout_sec;
+   } nvme;
} u;
 
struct timer_list timer;
@@ -437,6 +451,7 @@ struct srb_iocb {
 #define SRB_NACK_PLOGI 16
 #define SRB_NACK_PRLI  17
 #define SRB_NACK_LOGO  18
+#define SRB_NVME_CMD   19
 #define SRB_PRLI_CMD   21
 
 enum {
@@ -4111,6 +4126,8 @@ typedef struct scsi_qla_host {
struct  nvme_fc_local_port *nvme_local_port;
atomic_tnvme_ref_count;
struct list_head nvme_rport_list;
+   atomic_tnvme_active_aen_cnt;
+   uint16_tnvme_last_rptd_aen;
 
uint16_tfcoe_vlan_id;
uint16_tfcoe_fcf_idx;
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index dcae62d4cbeb..7d9a076c4667 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -603,9 +603,14 @@ struct sts_entry_24xx {
 
uint32_t residual_len;  /* FW calc residual transfer length. */
 
-   uint16_t reserved_1;
+   union {
+   uint16_t reserved_1;
+   uint16_t nvme_rsp_pyld_len;
+   };
+
uint16_t state_flags;   /* State flags. */
 #define SF_TRANSFERRED_DATABIT_11
+#define SF_NVME_ERSPBIT_6
 #define SF_FCP_RSP_DMA BIT_0
 
uint16_t retry_delay;
@@ -615,8 +620,25 @@ struct sts_entry_24xx {
uint32_t rsp_residual_count;/* FCP RSP residual count. */
 
uint32_t sense_len; /* FCP SENSE length. */
-   uint32_t rsp_data_len;  /* FCP response data length. */
-   uint8_t data[28];   /* FCP response/sense information. */
+
+   union {
+   struct {
+   uint32_t rsp_data_len;  /* FCP response data length  */
+   uint8_t data[28];   /* FCP rsp/sense information */
+   };
+   struct {
+   /* nvme ersp hdr */
+   __u8status_code;
+   __u8rsvd0;
+   __be16  iu_len;
+   __be32  rsn;
+   __be32  xfrd_len;
+   __be32  rsvd12;
+   uint8_t cqe[16];
+   };
+   uint8_t nvme_ersp_data[32];
+   };
+
/*
 * If DIF Error is set in comp_status, these additional fields are
 * defined:
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 40385bc1d1fa..0d60fd0da604 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1799,6 +1799,86 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct 
req_que *req, void *tsk)
sp->done(sp, 0);
 }
 
+static void
+qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
+{
+   const char func[] = "NVME-IOCB";
+   fc_port_t *fcport;
+   srb_t *sp;
+   struct srb_iocb *iocb;
+   struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk;
+   uint16_tstate_flags;
+   struct nvmefc_fcp_req *fd;
+   struct srb_iocb *nvme;
+
+   sp = qla2x00_get_sp_from_handle(vha, func, req, tsk);
+   if (!sp)
+   return;
+
+   iocb = >u.iocb_cmd;
+   fcport = sp->fcport;
+   iocb->u.nvme.comp_status = le16_to_cpu(sts->comp_status);
+   state_flags  = le16_to_cpu(sts->state_flags);
+   fd = iocb->u.nvme.desc;
+   nvme = >u.iocb_cmd;
+
+   if (unlikely(nvme-&

[PATCH 0/6] qla2xxx: Add NVMe FC Fabric support in driver

2017-06-16 Thread Himanshu Madhani
Hi Martin,

This patch series adds NVMe FC fabric support for qla2xxx initiator mode driver.

This series depends on the target multiqueue series that was sent out on June 
13,207. 
(https://www.spinics.net/lists/linux-scsi/msg109827.html)

There are couple of new files qla_nvme.c and qla_nvme.h created to add the 
changes needed
for registration to NVMe FC transport template as well as error handling logic.

Patch 1 adds NVMe bits to various driver resources to help with NVMe remote 
port discovery
and PRLI handling in the driver.

Patch 2 adds NVMe command handling in driver. 

Patch 3 has bulk of NVMe changes which handles NVMe support based on module 
paramter which
is used for firmware initialization and NVMe transport registration. All the 
logic to handle
NVMe command and error handling is also included in qla_nvme.c file.

Patch 4 and 5 are trivial changes for FDMI registration to send NVMe FC-4 type 
to switch
management server.

Please apply this series to for-next for inclusion in 4.13 merge window.

Note: Patch 2 does not compile due to change which are part of patch 3. 
  Please apply patch 1-6 to be able to get compilable driver. 

Thanks,
Himanshu 

Duane Grigsby (5):
  qla2xxx: Add FC-NVMe port discovery and PRLI handling
  qla2xxx: Add FC-NVMe command handling
  qla2xxx: Add FC-NVMe F/W initialization and transport registration
  qla2xxx: Send FC4 type NVMe to the management server
  qla2xxx: Use FC-NMVe FC4 type for FDMI registration

Himanshu Madhani (1):
  qla2xxx: Update Driver version to 10.00.00.00-k

 drivers/scsi/qla2xxx/Makefile  |   2 +-
 drivers/scsi/qla2xxx/qla_dbg.c |   9 +-
 drivers/scsi/qla2xxx/qla_def.h |  52 ++-
 drivers/scsi/qla2xxx/qla_fw.h  |  41 +-
 drivers/scsi/qla2xxx/qla_gbl.h |  34 +-
 drivers/scsi/qla2xxx/qla_gs.c  | 134 ++-
 drivers/scsi/qla2xxx/qla_init.c| 187 -
 drivers/scsi/qla2xxx/qla_iocb.c|  57 +++
 drivers/scsi/qla2xxx/qla_isr.c | 105 +
 drivers/scsi/qla2xxx/qla_mbx.c |  55 ++-
 drivers/scsi/qla2xxx/qla_nvme.c| 797 +
 drivers/scsi/qla2xxx/qla_nvme.h| 132 ++
 drivers/scsi/qla2xxx/qla_os.c  |  60 ++-
 drivers/scsi/qla2xxx/qla_target.c  |   4 +-
 drivers/scsi/qla2xxx/qla_version.h |   6 +-
 15 files changed, 1628 insertions(+), 47 deletions(-)
 create mode 100644 drivers/scsi/qla2xxx/qla_nvme.c
 create mode 100644 drivers/scsi/qla2xxx/qla_nvme.h

-- 
2.12.0



[PATCH 5/6] qla2xxx: Use FC-NMVe FC4 type for FDMI registration

2017-06-16 Thread Himanshu Madhani
From: Duane Grigsby <duane.grig...@cavium.com>

Signed-off-by: Duane Grigsby <duane.grig...@cavium.com>
Signed-off-by: Darren Trapp <darren.tr...@cavium.com>
Signed-off-by: Anil Gurumurthy <anil.gurumur...@cavium.com>
Signed-off-by: Giridhar Malavali <giridhar.malav...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_gs.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index c91478529b51..b323a7c71eda 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -2166,6 +2166,13 @@ qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha)
eiter->a.fc4_types[2],
eiter->a.fc4_types[1]);
 
+   if (vha->flags.nvme_enabled) {
+   eiter->a.fc4_types[6] = 1;  /* NVMe type 28h */
+   ql_dbg(ql_dbg_disc, vha, 0x211f,
+   "NVME FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n",
+   eiter->a.fc4_types[6]);
+   }
+
/* Supported speed. */
eiter = entries + size;
eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
@@ -2363,6 +2370,15 @@ qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha)
"Port Active FC4 Type = %02x %02x.\n",
eiter->a.port_fc4_type[2], eiter->a.port_fc4_type[1]);
 
+   if (vha->flags.nvme_enabled) {
+   eiter->a.port_fc4_type[4] = 0;
+   eiter->a.port_fc4_type[5] = 0;
+   eiter->a.port_fc4_type[6] = 1;  /* NVMe type 28h */
+   ql_dbg(ql_dbg_disc, vha, 0x2120,
+   "NVME Port Active FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n",
+   eiter->a.port_fc4_type[6]);
+   }
+
/* Port State */
eiter = entries + size;
eiter->type = cpu_to_be16(FDMI_PORT_STATE);
-- 
2.12.0



[PATCH 6/6] qla2xxx: Update Driver version to 10.00.00.00-k

2017-06-16 Thread Himanshu Madhani
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_version.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_version.h 
b/drivers/scsi/qla2xxx/qla_version.h
index dcbb9bb05e99..005a378f7fab 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,9 +7,9 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION  "9.01.00.00-k"
+#define QLA2XXX_VERSION  "10.00.00.00-k"
 
-#define QLA_DRIVER_MAJOR_VER   9
-#define QLA_DRIVER_MINOR_VER   1
+#define QLA_DRIVER_MAJOR_VER   10
+#define QLA_DRIVER_MINOR_VER   0
 #define QLA_DRIVER_PATCH_VER   0
 #define QLA_DRIVER_BETA_VER0
-- 
2.12.0



[PATCH v2 01/15] qla2xxx: Combine Active command arrays.

2017-06-13 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Merge active/outstanding cmd arrays from target side
and initiator side together in prepration for Target
Multi Queue support.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h|  15 +++-
 drivers/scsi/qla2xxx/qla_gbl.h|   2 -
 drivers/scsi/qla2xxx/qla_inline.h |   1 +
 drivers/scsi/qla2xxx/qla_isr.c|  48 +
 drivers/scsi/qla2xxx/qla_os.c |  75 ++--
 drivers/scsi/qla2xxx/qla_target.c | 144 --
 drivers/scsi/qla2xxx/qla_target.h |  23 --
 7 files changed, 164 insertions(+), 144 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index ddf93efe3986..1b5049b1ef4a 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -437,7 +437,18 @@ struct srb_iocb {
 #define SRB_NACK_PRLI  17
 #define SRB_NACK_LOGO  18
 
+enum {
+   TYPE_SRB,
+   TYPE_TGT_CMD,
+};
+
 typedef struct srb {
+   /*
+* Do not move cmd_type field, it needs to
+* line up with qla_tgt_cmd->cmd_type
+*/
+   uint8_t cmd_type;
+   uint8_t pad[3];
atomic_t ref_count;
struct fc_port *fcport;
struct scsi_qla_host *vha;
@@ -3287,9 +3298,6 @@ struct qlt_hw_data {
uint32_t __iomem *atio_q_out;
 
struct qla_tgt_func_tmpl *tgt_ops;
-   struct qla_tgt_cmd *cmds[DEFAULT_OUTSTANDING_COMMANDS];
-   uint16_t current_handle;
-
struct qla_tgt_vp_map *tgt_vp_map;
 
int saved_set;
@@ -4258,6 +4266,7 @@ enum nexus_wait_type {
WAIT_LUN,
 };
 
+#include "qla_target.h"
 #include "qla_gbl.h"
 #include "qla_dbg.h"
 #include "qla_inline.h"
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index f8540f5c9e5d..63355f40ff2f 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -834,8 +834,6 @@ extern irqreturn_t qla8044_intr_handler(int, void *);
 extern void qla82xx_mbx_completion(scsi_qla_host_t *, uint16_t);
 extern int qla8044_abort_isp(scsi_qla_host_t *);
 extern int qla8044_check_fw_alive(struct scsi_qla_host *);
-
-extern void qlt_host_reset_handler(struct qla_hw_data *ha);
 extern int qla_get_exlogin_status(scsi_qla_host_t *, uint16_t *,
uint16_t *);
 extern int qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr);
diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index 9996ec0daab1..99028d48c664 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -250,6 +250,7 @@ qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, 
gfp_t flag)
 
memset(sp, 0, sizeof(*sp));
sp->fcport = fcport;
+   sp->cmd_type = TYPE_SRB;
sp->iocbs = 1;
sp->vha = vha;
 done:
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 2984abcc29e7..8aaddb75f964 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -17,7 +17,7 @@
 static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
 static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *);
 static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *);
-static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
+static int qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
sts_entry_t *);
 
 /**
@@ -2280,6 +2280,14 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct 
rsp_que *rsp, void *pkt)
return;
}
 
+   if (sp->cmd_type != TYPE_SRB) {
+   req->outstanding_cmds[handle] = NULL;
+   ql_dbg(ql_dbg_io, vha, 0x3015,
+   "Unknown sp->cmd_type %x %p).\n",
+   sp->cmd_type, sp);
+   return;
+   }
+
if (unlikely((state_flags & BIT_1) && (sp->type == SRB_BIDI_CMD))) {
qla25xx_process_bidir_status_iocb(vha, pkt, req, handle);
return;
@@ -2632,8 +2640,9 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, 
sts_cont_entry_t *pkt)
  * qla2x00_error_entry() - Process an error entry.
  * @ha: SCSI driver HA context
  * @pkt: Entry pointer
+ * return : 1=allow further error analysis. 0=no additional error analysis.
  */
-static void
+static int
 qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t 
*pkt)
 {
srb_t *sp;
@@ -2654,18 +2663,35 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct 
rsp_que *rsp, sts_entry_t *pkt)
if (pkt->entry_status & RF_BUSY)
res = DID_BUS_BUSY << 16;
 
-   if (pkt->entry_type == NOTIFY_ACK_TYPE &&
-   pkt->handle == QLA_TGT_SKIP_HANDLE)
-   return;
+   if ((pkt->ha

[PATCH v2 00/15] qla2xxx: Add Target Multiqueue support

2017-06-13 Thread Himanshu Madhani
Hi Martin, Nic,

This patch series adds support for multiqueue for qla2xxx target mode driver.

This series depends on the seris applied to Martin's scsi/for-next branch
(https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git/log/?h=for-next)

I've also added followig patch ("qla2xxx: Include Exchange offload/Extended
Login into FW dump") which was dropped from earlier series for rework.

I am planning to send series for FC-NVME support as well which depends on this
series, so I would like this series to be applied to scsi tree instead of
target-pending for only this submission, as both series touches common code
in qla2xxx driver. 

Please apply this series to for-next for inclusion in 4.13 merge window.

Note: Comment from Bart for patch#1 will be addresed as new patch after our 
  FC-NVME series is posted. 

Changes from v1 --> v2

o Fixed 0-day kernel compile failure

Thanks,
Himanshu 

Himanshu Madhani (1):
  qla2xxx: Update driver version to 9.01.00.00-k

Quinn Tran (13):
  qla2xxx: Combine Active command arrays.
  qla2xxx: Preparation for Target MQ.
  qla2xxx: Enable Target Multi Queue
  qla2xxx: Add debug knob for user control workload
  qla2xxx: Add fw_started flags to qpair
  qla2xxx: move fields from qla_hw_data to qla_qpair
  qla2xxx: use shadow register for ISP27XX
  qla2xxx: Add function call to qpair for door bell
  qla2xxx: Add debug logging routine for qpair
  qla2xxx: Remove unused tgt_enable_64bit_addr flag
  qla2xxx: Remove datasegs_per_cmd and datasegs_per_cont field
  qla2xxx: Move target stat counters from vha to qpair.
  qla2xxx: Include Exchange offload/Extended Login into FW dump

Sawan Chandak (1):
  qla2xxx: Fix mailbox failure while deleting Queue pairs

 drivers/scsi/qla2xxx/qla_attr.c|4 +-
 drivers/scsi/qla2xxx/qla_dbg.c |  150 ++
 drivers/scsi/qla2xxx/qla_dbg.h |   17 +
 drivers/scsi/qla2xxx/qla_def.h |  119 -
 drivers/scsi/qla2xxx/qla_dfs.c |  137 -
 drivers/scsi/qla2xxx/qla_gbl.h |   19 +-
 drivers/scsi/qla2xxx/qla_init.c|   53 +-
 drivers/scsi/qla2xxx/qla_inline.h  |   44 ++
 drivers/scsi/qla2xxx/qla_iocb.c|   32 +-
 drivers/scsi/qla2xxx/qla_isr.c |   93 +++-
 drivers/scsi/qla2xxx/qla_mid.c |   44 +-
 drivers/scsi/qla2xxx/qla_os.c  |  156 --
 drivers/scsi/qla2xxx/qla_target.c  | 1028 +---
 drivers/scsi/qla2xxx/qla_target.h  |   50 +-
 drivers/scsi/qla2xxx/qla_version.h |4 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |8 +-
 16 files changed, 1348 insertions(+), 610 deletions(-)

-- 
2.12.0



[PATCH v2 09/15] qla2xxx: Add function call to qpair for door bell

2017-06-13 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Add call back to door bell for qpair. This help
reduce access to qla_hw_data structure, in order
to reduce cach thrash.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h|  3 ++
 drivers/scsi/qla2xxx/qla_init.c   |  3 ++
 drivers/scsi/qla2xxx/qla_inline.h | 15 +
 drivers/scsi/qla2xxx/qla_os.c | 35 ---
 drivers/scsi/qla2xxx/qla_target.c | 71 +++
 drivers/scsi/qla2xxx/qla_target.h |  2 +-
 6 files changed, 94 insertions(+), 35 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index b3ba32773db4..17b13dd92511 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3272,6 +3272,9 @@ struct qla_qpair {
uint16_t vp_idx;/* vport ID */
mempool_t *srb_mempool;
 
+   struct pci_dev  *pdev;
+   void (*reqq_start_iocbs)(struct qla_qpair *);
+
/* to do: New driver: move queues to here instead of pointers */
struct req_que *req;
struct rsp_que *rsp;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f586f4f7dc57..48c0a58330d4 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7653,6 +7653,9 @@ struct qla_qpair *qla2xxx_create_qpair(struct 
scsi_qla_host *vha, int qos,
 
qpair->msix->in_use = 1;
list_add_tail(>qp_list_elem, >qp_list);
+   qpair->pdev = ha->pdev;
+   if (IS_QLA27XX(ha) || IS_QLA83XX(ha))
+   qpair->reqq_start_iocbs = qla_83xx_start_iocbs;
 
mutex_unlock(>mq_lock);
 
diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index bd8cb796f64e..9a2c86eacf44 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -352,3 +352,18 @@ qla_qpair_to_hint(struct qla_tgt *tgt, struct qla_qpair 
*qpair)
 
return NULL;
 }
+
+static inline void
+qla_83xx_start_iocbs(struct qla_qpair *qpair)
+{
+   struct req_que *req = qpair->req;
+
+   req->ring_index++;
+   if (req->ring_index == req->length) {
+   req->ring_index = 0;
+   req->ring_ptr = req->ring;
+   } else
+   req->ring_ptr++;
+
+   WRT_REG_DWORD(req->req_q_in, req->ring_index);
+}
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 1d66954b7e5a..88e115fcea60 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -351,6 +351,28 @@ int qla2xxx_mqueuecommand(struct Scsi_Host *host, struct 
scsi_cmnd *cmd,
struct qla_qpair *qpair);
 
 /* -- 
*/
+static void qla_init_base_qpair(struct scsi_qla_host *vha, struct req_que *req,
+struct rsp_que *rsp)
+{
+   struct qla_hw_data *ha = vha->hw;
+   rsp->qpair = ha->base_qpair;
+   rsp->req = req;
+   ha->base_qpair->req = req;
+   ha->base_qpair->rsp = rsp;
+   ha->base_qpair->vha = vha;
+   ha->base_qpair->qp_lock_ptr = >hardware_lock;
+   ha->base_qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0;
+   ha->base_qpair->msix = >msix_entries[QLA_MSIX_RSP_Q];
+   INIT_LIST_HEAD(>base_qpair->hints_list);
+   ha->base_qpair->enable_class_2 = ql2xenableclass2;
+   /* init qpair to this cpu. Will adjust at run time. */
+   qla_cpu_update(rsp->qpair, smp_processor_id());
+   ha->base_qpair->pdev = ha->pdev;
+
+   if (IS_QLA27XX(ha) || IS_QLA83XX(ha))
+   ha->base_qpair->reqq_start_iocbs = qla_83xx_start_iocbs;
+}
+
 static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req,
struct rsp_que *rsp)
 {
@@ -378,18 +400,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, 
struct req_que *req,
goto fail_base_qpair;
}
 
-   rsp->qpair = ha->base_qpair;
-   rsp->req = req;
-   ha->base_qpair->req = req;
-   ha->base_qpair->rsp = rsp;
-   ha->base_qpair->vha = vha;
-   ha->base_qpair->qp_lock_ptr = >hardware_lock;
-   ha->base_qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0;
-   /* init qpair to this cpu. Will adjust at run time. */
-   ha->base_qpair->msix = >msix_entries[QLA_MSIX_RSP_Q];
-   INIT_LIST_HEAD(>base_qpair->hints_list);
-   ha->base_qpair->enable_class_2 = ql2xenableclass2;
-   qla_cpu_update(rsp->qpair, smp_processor_id());
+   qla_init_base_qpair(vha, req, rsp);
 
if (ql2xmqsupport && ha->max_qpairs) {
   

[PATCH v2 02/15] qla2xxx: Preparation for Target MQ.

2017-06-13 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

In Current code, Req Q 0, RespQ 0 & hardware_lock
are the main resources for sending and process completion
of Target IO. These resources are now referenced
behind a new qpair/"struct qla_qpair base_qpair".
Main path IO handle will access those resources via the
qpair pointer in preparation for Target MQ.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_attr.c   |   2 +-
 drivers/scsi/qla2xxx/qla_def.h|  17 +-
 drivers/scsi/qla2xxx/qla_gbl.h|  15 +-
 drivers/scsi/qla2xxx/qla_init.c   |  11 +-
 drivers/scsi/qla2xxx/qla_iocb.c   |  30 ++-
 drivers/scsi/qla2xxx/qla_isr.c|  11 +-
 drivers/scsi/qla2xxx/qla_mid.c|  40 +--
 drivers/scsi/qla2xxx/qla_os.c |  23 +-
 drivers/scsi/qla2xxx/qla_target.c | 518 --
 drivers/scsi/qla2xxx/qla_target.h |  10 +-
 10 files changed, 380 insertions(+), 297 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index a93eb42718e5..f0f16d313faf 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -2096,7 +2096,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool 
disable)
}
 
if (qos) {
-   qpair = qla2xxx_create_qpair(vha, qos, vha->vp_idx);
+   qpair = qla2xxx_create_qpair(vha, qos, vha->vp_idx, true);
if (!qpair)
ql_log(ql_log_warn, vha, 0x7084,
"Can't create qpair for VP[%d]\n",
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 1b5049b1ef4a..64109134e276 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3182,6 +3182,9 @@ struct qla_tc_param {
 #define QLA_PRECONFIG_VPORTS 32
 #define QLA_MAX_VPORTS_QLA24XX 128
 #define QLA_MAX_VPORTS_QLA25XX 256
+
+struct qla_qpair;
+
 /* Response queue data structure */
 struct rsp_que {
dma_addr_t  dma;
@@ -3201,6 +3204,7 @@ struct rsp_que {
struct qla_msix_entry *msix;
struct req_que *req;
srb_t *status_srb; /* status continuation entry */
+   struct qla_qpair *qpair;
 
dma_addr_t  dma_fx00;
response_t *ring_fx00;
@@ -3241,6 +3245,14 @@ struct req_que {
 struct qla_qpair {
spinlock_t qp_lock;
atomic_t ref_count;
+
+   /*
+* For qpair 0, qp_lock_ptr will point at hardware_lock due to
+* legacy code. For other Qpair(s), it will point at qp_lock.
+*/
+   spinlock_t *qp_lock_ptr;
+   struct scsi_qla_host *vha;
+
/* distill these fields down to 'online=0/1'
 * ha->flags.eeh_busy
 * ha->flags.pci_channel_io_perm_failure
@@ -3252,10 +3264,7 @@ struct qla_qpair {
uint32_t delete_in_progress:1;
 
uint16_t id;/* qp number used with FW */
-   uint16_t num_active_cmd;/* cmds down at firmware */
-   cpumask_t cpu_mask; /* CPU mask for cpu affinity operation */
uint16_t vp_idx;/* vport ID */
-
mempool_t *srb_mempool;
 
/* to do: New driver: move queues to here instead of pointers */
@@ -3266,7 +3275,7 @@ struct qla_qpair {
struct qla_hw_data *hw;
struct work_struct q_work;
struct list_head qp_list_elem; /* vha->qp_list */
-   struct scsi_qla_host *vha;
+   uint16_t cpuid;
 };
 
 /* Place holder for FW buffer parameters */
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 63355f40ff2f..f5493eda0110 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -77,8 +77,7 @@ struct qla_work_evt *qla2x00_alloc_work(struct scsi_qla_host 
*,
 enum qla_work_type);
 extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *);
 int qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e);
-extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *);
-extern void *qla2x00_alloc_iocbs_ready(struct scsi_qla_host *, srb_t *);
+extern void *qla2x00_alloc_iocbs_ready(struct qla_qpair *, srb_t *);
 extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *);
 
 extern fc_port_t *
@@ -96,7 +95,7 @@ qla2x00_alloc_outstanding_cmds(struct qla_hw_data *, struct 
req_que *);
 extern int qla2x00_init_rings(scsi_qla_host_t *);
 extern uint8_t qla27xx_find_valid_image(struct scsi_qla_host *);
 extern struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *,
-   int, int);
+   int, int, bool);
 extern int qla2xxx_delete_qpair(struct scsi_qla_host *, struct qla_qpair *);
 void qla2x00_fcport_event_handler(scsi_qla_host_t *, struct event_arg *);
 int qla24xx_async_gpdb(struct scsi_qla_host *, fc_port_t *, u8);
@@ -255,7 +254,8 @@ extern int qla2x00_start_bidir(srb_t *, struct 
scsi_qla_host *, uint32_t);
 extern int 

[PATCH v2 12/15] qla2xxx: Remove datasegs_per_cmd and datasegs_per_cont field

2017-06-13 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

These fields only hold one set of value. Replace it with
macros to reduce cache thrash.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 12 +---
 drivers/scsi/qla2xxx/qla_target.h |  2 +-
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 411c1799c6e3..48d82c67e223 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2228,10 +2228,10 @@ static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm)
 * If greater than four sg entries then we need to allocate
 * the continuation entries
 */
-   if (prm->seg_cnt > prm->tgt->datasegs_per_cmd)
+   if (prm->seg_cnt > QLA_TGT_DATASEGS_PER_CMD_24XX)
prm->req_cnt += DIV_ROUND_UP(prm->seg_cnt -
-   prm->tgt->datasegs_per_cmd,
-   prm->tgt->datasegs_per_cont);
+   QLA_TGT_DATASEGS_PER_CMD_24XX,
+   QLA_TGT_DATASEGS_PER_CONT_24XX);
} else {
/* DIF */
if ((cmd->se_cmd.prot_op == TARGET_PROT_DIN_INSERT) ||
@@ -2448,7 +2448,7 @@ static void qlt_load_cont_data_segments(struct 
qla_tgt_prm *prm)
 
/* Load continuation entry data segments */
for (cnt = 0;
-   cnt < prm->tgt->datasegs_per_cont && prm->seg_cnt;
+   cnt < QLA_TGT_DATASEGS_PER_CONT_24XX && prm->seg_cnt;
cnt++, prm->seg_cnt--) {
*dword_ptr++ =
cpu_to_le32(pci_dma_lo32
@@ -2492,7 +2492,7 @@ static void qlt_load_data_segments(struct qla_tgt_prm 
*prm)
 
/* Load command entry data segments */
for (cnt = 0;
-   (cnt < prm->tgt->datasegs_per_cmd) && prm->seg_cnt;
+   (cnt < QLA_TGT_DATASEGS_PER_CMD_24XX) && prm->seg_cnt;
cnt++, prm->seg_cnt--) {
*dword_ptr++ =
cpu_to_le32(pci_dma_lo32(sg_dma_address(prm->sg)));
@@ -6170,8 +6170,6 @@ int qlt_add_target(struct qla_hw_data *ha, struct 
scsi_qla_host *base_vha)
base_vha->vp_idx);
/* 3 is reserved */
tgt->sg_tablesize = QLA_TGT_MAX_SG_24XX(base_vha->req->length - 3);
-   tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX;
-   tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX;
 
mutex_lock(_tgt_mutex);
list_add_tail(>tgt_list_entry, _tgt_glist);
diff --git a/drivers/scsi/qla2xxx/qla_target.h 
b/drivers/scsi/qla2xxx/qla_target.h
index 902685f85506..7fe02d036bdf 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -806,7 +806,7 @@ struct qla_tgt {
 */
int atio_irq_cmd_count;
 
-   int datasegs_per_cmd, datasegs_per_cont, sg_tablesize;
+   int sg_tablesize;
 
/* Target's flags, serialized by pha->hardware_lock */
unsigned int link_reinit_iocb_pending:1;
-- 
2.12.0



[PATCH v2 11/15] qla2xxx: Remove unused tgt_enable_64bit_addr flag

2017-06-13 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

By default this flag is forced to true.  Remove this
flag and unneccessary check for this flag.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 44 ---
 drivers/scsi/qla2xxx/qla_target.h |  1 -
 2 files changed, 13 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 84be2b48246f..411c1799c6e3 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2420,12 +2420,10 @@ static int qlt_24xx_build_ctio_pkt(struct qla_qpair 
*qpair,
  * ha->hardware_lock supposed to be held on entry. We have already made sure
  * that there is sufficient amount of request entries to not drop it.
  */
-static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm,
-   struct scsi_qla_host *vha)
+static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm)
 {
int cnt;
uint32_t *dword_ptr;
-   int enable_64bit_addressing = prm->tgt->tgt_enable_64bit_addr;
 
/* Build continuation packets */
while (prm->seg_cnt > 0) {
@@ -2445,16 +2443,8 @@ static void qlt_load_cont_data_segments(struct 
qla_tgt_prm *prm,
cont_pkt64->entry_count = 1;
cont_pkt64->sys_define = 0;
 
-   if (enable_64bit_addressing) {
-   cont_pkt64->entry_type = CONTINUE_A64_TYPE;
-   dword_ptr =
-   (uint32_t *)_pkt64->dseg_0_address;
-   } else {
-   cont_pkt64->entry_type = CONTINUE_TYPE;
-   dword_ptr =
-   (uint32_t *)&((cont_entry_t *)
-   cont_pkt64)->dseg_0_address;
-   }
+   cont_pkt64->entry_type = CONTINUE_A64_TYPE;
+   dword_ptr = (uint32_t *)_pkt64->dseg_0_address;
 
/* Load continuation entry data segments */
for (cnt = 0;
@@ -2463,12 +2453,8 @@ static void qlt_load_cont_data_segments(struct 
qla_tgt_prm *prm,
*dword_ptr++ =
cpu_to_le32(pci_dma_lo32
(sg_dma_address(prm->sg)));
-   if (enable_64bit_addressing) {
-   *dword_ptr++ =
-   cpu_to_le32(pci_dma_hi32
-   (sg_dma_address
-   (prm->sg)));
-   }
+   *dword_ptr++ = cpu_to_le32(pci_dma_hi32
+   (sg_dma_address(prm->sg)));
*dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg));
 
prm->sg = sg_next(prm->sg);
@@ -2480,12 +2466,10 @@ static void qlt_load_cont_data_segments(struct 
qla_tgt_prm *prm,
  * ha->hardware_lock supposed to be held on entry. We have already made sure
  * that there is sufficient amount of request entries to not drop it.
  */
-static void qlt_load_data_segments(struct qla_tgt_prm *prm,
-   struct scsi_qla_host *vha)
+static void qlt_load_data_segments(struct qla_tgt_prm *prm)
 {
int cnt;
uint32_t *dword_ptr;
-   int enable_64bit_addressing = prm->tgt->tgt_enable_64bit_addr;
struct ctio7_to_24xx *pkt24 = (struct ctio7_to_24xx *)prm->pkt;
 
pkt24->u.status0.transfer_length = cpu_to_le32(prm->cmd->bufflen);
@@ -2512,17 +2496,16 @@ static void qlt_load_data_segments(struct qla_tgt_prm 
*prm,
cnt++, prm->seg_cnt--) {
*dword_ptr++ =
cpu_to_le32(pci_dma_lo32(sg_dma_address(prm->sg)));
-   if (enable_64bit_addressing) {
-   *dword_ptr++ =
-   cpu_to_le32(pci_dma_hi32(
-   sg_dma_address(prm->sg)));
-   }
+
+   *dword_ptr++ = cpu_to_le32(pci_dma_hi32(
+   sg_dma_address(prm->sg)));
+
*dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg));
 
prm->sg = sg_next(prm->sg);
}
 
-   qlt_load_cont_data_segments(prm, vha);
+   qlt_load_cont_data_segments(prm);
 }
 
 static inline int qlt_has_data(struct qla_tgt_cmd *cmd)
@@ -3136,7 +3119,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int 
xmit_type,
CTIO7_FLAGS_STATUS_MODE_0);
 
if (cmd->se_cmd.prot_op == TARGET_PROT_NORMAL)
-   qlt_load_data_segments(, vha);
+   qlt_load_data_segments();
 
if (prm.add_status_pkt == 0) {
if (xmit_type & QLA_TGT_XMIT_STATUS) {
@@ -3272,7 +3255,7 @@ int qlt_rdy_

[PATCH v2 07/15] qla2xxx: move fields from qla_hw_data to qla_qpair

2017-06-13 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

- Move chip_reset, enable_class_2 fields from qla_hw_data to qla_qpair
 to reduce cache thrash for target MQ.
- Optimizations to reduce unnecessary memory load for good path io.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_attr.c   |  2 +-
 drivers/scsi/qla2xxx/qla_def.h| 25 +++--
 drivers/scsi/qla2xxx/qla_init.c   | 14 ++--
 drivers/scsi/qla2xxx/qla_os.c |  2 +-
 drivers/scsi/qla2xxx/qla_target.c | 75 +++
 drivers/scsi/qla2xxx/qla_target.h |  3 +-
 6 files changed, 73 insertions(+), 48 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index f0f16d313faf..6dd984203666 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -2289,7 +2289,7 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha)
fc_host_dev_loss_tmo(vha->host) = ha->port_down_retry_count;
fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name);
fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name);
-   fc_host_supported_classes(vha->host) = ha->tgt.enable_class_2 ?
+   fc_host_supported_classes(vha->host) = ha->base_qpair->enable_class_2 ?
(FC_COS_CLASS2|FC_COS_CLASS3) : FC_COS_CLASS3;
fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports;
fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count;
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 0dec148a4580..dfa001357110 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3252,6 +3252,7 @@ struct qla_qpair {
 */
spinlock_t *qp_lock_ptr;
struct scsi_qla_host *vha;
+   u32 chip_reset;
 
/* distill these fields down to 'online=0/1'
 * ha->flags.eeh_busy
@@ -3263,6 +3264,8 @@ struct qla_qpair {
uint32_t difdix_supported:1;
uint32_t delete_in_progress:1;
uint32_t fw_started:1;
+   uint32_t enable_class_2:1;
+   uint32_t enable_explicit_conf:1;
 
uint16_t id;/* qp number used with FW */
uint16_t vp_idx;/* vport ID */
@@ -3296,8 +3299,6 @@ struct scsi_qlt_host {
 
 struct qlt_hw_data {
/* Protected by hw lock */
-   uint32_t enable_class_2:1;
-   uint32_t enable_explicit_conf:1;
uint32_t node_name_set:1;
 
dma_addr_t atio_dma;/* Physical address. */
@@ -3954,7 +3955,6 @@ struct qla_hw_data {
struct work_struct board_disable;
 
struct mr_data_fx00 mr;
-   uint32_t chip_reset;
 
struct qlt_hw_data tgt;
int allow_cna_fw_dump;
@@ -4247,6 +4247,25 @@ struct qla2_sgx {
 #define QLA_QPAIR_MARK_NOT_BUSY(__qpair)   \
atomic_dec(&__qpair->ref_count);\
 
+
+#define QLA_ENA_CONF(_ha) {\
+int i;\
+_ha->base_qpair->enable_explicit_conf = 1; \
+for (i = 0; i < _ha->max_qpairs; i++) {\
+   if (_ha->queue_pair_map[i]) \
+   _ha->queue_pair_map[i]->enable_explicit_conf = 1; \
+}  \
+}
+
+#define QLA_DIS_CONF(_ha) {\
+int i;\
+_ha->base_qpair->enable_explicit_conf = 0; \
+for (i = 0; i < _ha->max_qpairs; i++) {\
+   if (_ha->queue_pair_map[i]) \
+   _ha->queue_pair_map[i]->enable_explicit_conf = 0; \
+}  \
+}
+
 /*
  * qla2x00 local function return status codes
  */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index e6a1f9ca0e95..360abede3f6b 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1322,7 +1322,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host 
*vha, struct event_arg *ea)
ql_dbg(ql_dbg_disc, vha, 0x20ea,
"%s %d %8phC post gpdb\n",
__func__, __LINE__, ea->fcport->port_name);
-   ea->fcport->chip_reset = vha->hw->chip_reset;
+   ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
ea->fcport->logout_on_delete = 1;
qla24xx_post_gpdb_work(vha, ea->fcport, 0);
break;
@@ -5524,6 +5524,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
struct scsi_qla_host *vp;
unsigned long flags;
fc_port_t *fcport;
+   u16 i;
 
/* For ISP82XX, driver waits for completion of the commands.
 * online flag should be set.
@@ -5549,7 +5550,12 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
ha->current_topology = 0;
ha->flags.fw_started = 0;
ha->flags.fw_init_done = 0;
-   

[PATCH v2 03/15] qla2xxx: Enable Target Multi Queue

2017-06-13 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Enable Multi Queue for Target mode. At Initiator LUN scan time,
each LUN is assign to a QPair. Each QPair is affinitize
to certain CPU. When new cmd arrives from the wire,
the lunid is used to search for qpair. The qpair's affinitized
cpuid will be used to queue up the work element.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h|   3 +-
 drivers/scsi/qla2xxx/qla_init.c   |   3 +
 drivers/scsi/qla2xxx/qla_inline.h |  28 +++
 drivers/scsi/qla2xxx/qla_isr.c|  21 +++--
 drivers/scsi/qla2xxx/qla_os.c |  56 +-
 drivers/scsi/qla2xxx/qla_target.c | 157 --
 drivers/scsi/qla2xxx/qla_target.h |  10 ++-
 7 files changed, 240 insertions(+), 38 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 64109134e276..005ca2de3795 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3245,7 +3245,7 @@ struct req_que {
 struct qla_qpair {
spinlock_t qp_lock;
atomic_t ref_count;
-
+   uint32_t lun_cnt;
/*
 * For qpair 0, qp_lock_ptr will point at hardware_lock due to
 * legacy code. For other Qpair(s), it will point at qp_lock.
@@ -3275,6 +3275,7 @@ struct qla_qpair {
struct qla_hw_data *hw;
struct work_struct q_work;
struct list_head qp_list_elem; /* vha->qp_list */
+   struct list_head hints_list;
uint16_t cpuid;
 };
 
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 7d0847b3d190..fa5e6ab8e4a7 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7623,6 +7623,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct 
scsi_qla_host *vha, int qos,
ha->queue_pair_map[qpair_id] = qpair;
qpair->id = qpair_id;
qpair->vp_idx = vp_idx;
+   INIT_LIST_HEAD(>hints_list);
 
for (i = 0; i < ha->msix_count; i++) {
msix = >msix_entries[i];
@@ -7666,6 +7667,8 @@ struct qla_qpair *qla2xxx_create_qpair(struct 
scsi_qla_host *vha, int qos,
qpair->req = ha->req_q_map[req_id];
qpair->rsp->req = qpair->req;
qpair->rsp->qpair = qpair;
+   /* init qpair to this cpu. Will adjust at run time. */
+   qla_cpu_update(qpair, smp_processor_id());
 
if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
if (ha->fw_attributes & BIT_4)
diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index 99028d48c664..bd8cb796f64e 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -324,3 +324,31 @@ qla_is_exch_offld_enabled(struct scsi_qla_host *vha)
else
return false;
 }
+
+static inline void
+qla_cpu_update(struct qla_qpair *qpair, uint16_t cpuid)
+{
+   qpair->cpuid = cpuid;
+
+   if (!list_empty(>hints_list)) {
+   struct qla_qpair_hint *h;
+
+   list_for_each_entry(h, >hints_list, hint_elem)
+   h->cpuid = qpair->cpuid;
+   }
+}
+
+static inline struct qla_qpair_hint *
+qla_qpair_to_hint(struct qla_tgt *tgt, struct qla_qpair *qpair)
+{
+   struct qla_qpair_hint *h;
+   u16 i;
+
+   for (i = 0; i < tgt->ha->max_qpairs + 1; i++) {
+   h = >qphints[i];
+   if (h->qpair == qpair)
+   return h;
+   }
+
+   return NULL;
+}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 1535a29a9d9f..9eb946cc8297 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -9,6 +9,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -2761,6 +2762,9 @@ void qla24xx_process_response_queue(struct scsi_qla_host 
*vha,
if (!ha->flags.fw_started)
return;
 
+   if (rsp->qpair->cpuid != smp_processor_id())
+   qla_cpu_update(rsp->qpair, smp_processor_id());
+
while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
 
@@ -3196,10 +3200,10 @@ struct qla_init_msix_entry {
 };
 
 static const struct qla_init_msix_entry msix_entries[] = {
-   { "qla2xxx (default)", qla24xx_msix_default },
-   { "qla2xxx (rsp_q)", qla24xx_msix_rsp_q },
-   { "qla2xxx (atio_q)", qla83xx_msix_atio_q },
-   { "qla2xxx (qpair_multiq)", qla2xxx_msix_rsp_q },
+   { "default", qla24xx_msix_default },
+   { "rsp_q", qla24xx_msix_rsp_q },
+   { "atio_q", qla83xx_msix_atio_q },
+   {

[PATCH v2 08/15] qla2xxx: use shadow register for ISP27XX

2017-06-13 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

For ISP27XX, use shadow register to read FW provided
REQQ's consumer index.  The shadow register is dma'ed
by firmware.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h| 1 +
 drivers/scsi/qla2xxx/qla_init.c   | 1 +
 drivers/scsi/qla2xxx/qla_os.c | 1 +
 drivers/scsi/qla2xxx/qla_target.c | 3 ++-
 4 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index dfa001357110..b3ba32773db4 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3266,6 +3266,7 @@ struct qla_qpair {
uint32_t fw_started:1;
uint32_t enable_class_2:1;
uint32_t enable_explicit_conf:1;
+   uint32_t use_shadow_reg:1;
 
uint16_t id;/* qp number used with FW */
uint16_t vp_idx;/* vport ID */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 360abede3f6b..f586f4f7dc57 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7614,6 +7614,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct 
scsi_qla_host *vha, int qos,
qpair->vha = vha;
qpair->qp_lock_ptr = >qp_lock;
spin_lock_init(>qp_lock);
+   qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0;
 
/* Assign available que pair id */
mutex_lock(>mq_lock);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 44be2c8237fd..1d66954b7e5a 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -384,6 +384,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, 
struct req_que *req,
ha->base_qpair->rsp = rsp;
ha->base_qpair->vha = vha;
ha->base_qpair->qp_lock_ptr = >hardware_lock;
+   ha->base_qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0;
/* init qpair to this cpu. Will adjust at run time. */
ha->base_qpair->msix = >msix_entries[QLA_MSIX_RSP_Q];
INIT_LIST_HEAD(>base_qpair->hints_list);
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 66bb4825339f..1d6cc24c0640 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2288,7 +2288,8 @@ static int qlt_check_reserve_free_req(struct qla_qpair 
*qpair,
struct req_que *req = qpair->req;
 
if (req->cnt < (req_cnt + 2)) {
-   cnt = (uint16_t)RD_REG_DWORD(req->req_q_out);
+   cnt = (uint16_t)(qpair->use_shadow_reg ? *req->out_ptr :
+   RD_REG_DWORD_RELAXED(req->req_q_out));
 
if  (req->ring_index < cnt)
req->cnt = cnt - req->ring_index;
-- 
2.12.0



[PATCH v2 05/15] qla2xxx: Add debug knob for user control workload

2017-06-13 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

For Target mode, user can control the work load by
placing qla2xxx's irq vector on certain CPU via the
smp_affinity knob. This patch allows user to control
the number of QPair's irq to be active. The irqs are
allocated at driver load time until unload. The work
itself is placed on the QPair based on user setting.

Usage:
  modprobe qla2xxx qlini_mode=disabled ql2xuctrlirq=1
  mount -t debugfs none /sys/kernel/debug
  echo 2 > /sys/kernel/debug/qla2xxx/qla2xxx_[host num]/naqp
  echo [cpu id] > /proc/irq/[irq id]/smp_affinity_list

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h|  7 ++-
 drivers/scsi/qla2xxx/qla_dfs.c| 89 +++
 drivers/scsi/qla2xxx/qla_gbl.h|  2 +
 drivers/scsi/qla2xxx/qla_isr.c| 11 +++--
 drivers/scsi/qla2xxx/qla_target.c | 32 ++
 5 files changed, 137 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 8b52f431a812..18b37c864250 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3322,6 +3322,7 @@ struct qlt_hw_data {
 
struct dentry *dfs_tgt_sess;
struct dentry *dfs_tgt_port_database;
+   struct dentry *dfs_naqp;
 
struct list_head q_full_list;
uint32_t num_pend_cmds;
@@ -3330,7 +3331,8 @@ struct qlt_hw_data {
spinlock_t q_full_lock;
uint32_t leak_exchg_thresh_hold;
spinlock_t sess_lock;
-   int rspq_vector_cpuid;
+   int num_act_qpairs;
+#define DEFAULT_NAQP 2
spinlock_t atio_lock cacheline_aligned;
struct btree_head32 host_map;
 };
@@ -4278,6 +4280,9 @@ enum nexus_wait_type {
WAIT_LUN,
 };
 
+#define USER_CTRL_IRQ(_ha) (ql2xuctrlirq && QLA_TGT_MODE_ENABLED() && \
+   (IS_QLA27XX(_ha) || IS_QLA83XX(_ha)))
+
 #include "qla_target.h"
 #include "qla_gbl.h"
 #include "qla_dbg.h"
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 391c50be2297..63d7374dce77 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -314,6 +314,81 @@ static const struct file_operations dfs_fce_ops = {
.release= qla2x00_dfs_fce_release,
 };
 
+static int
+qla_dfs_naqp_show(struct seq_file *s, void *unused)
+{
+   struct scsi_qla_host *vha = s->private;
+   struct qla_hw_data *ha = vha->hw;
+
+   seq_printf(s, "%d\n", ha->tgt.num_act_qpairs);
+   return 0;
+}
+
+static int
+qla_dfs_naqp_open(struct inode *inode, struct file *file)
+{
+   struct scsi_qla_host *vha = inode->i_private;
+
+   return single_open(file, qla_dfs_naqp_show, vha);
+}
+
+static ssize_t
+qla_dfs_naqp_write(struct file *file, const char __user *buffer,
+size_t count, loff_t *pos)
+{
+   struct seq_file *s = file->private_data;
+   struct scsi_qla_host *vha = s->private;
+   struct qla_hw_data *ha = vha->hw;
+   char *buf;
+   int rc = 0;
+   unsigned long num_act_qp;
+
+   if (!(IS_QLA27XX(ha) || IS_QLA83XX(ha))) {
+   pr_err("host%ld: this adapter does not support Multi Q.",
+   vha->host_no);
+   return -EINVAL;
+   }
+
+   if (!vha->flags.qpairs_available) {
+   pr_err("host%ld: Driver is not setup with Multi Q.",
+   vha->host_no);
+   return -EINVAL;
+   }
+   buf = memdup_user_nul(buffer, count);
+   if (IS_ERR(buf)) {
+   pr_err("host%ld: fail to copy user buffer.",
+   vha->host_no);
+   return PTR_ERR(buf);
+   }
+
+   num_act_qp = simple_strtoul(buf, NULL, 0);
+
+   if (num_act_qp >= vha->hw->max_qpairs) {
+   pr_err("User set invalid number of qpairs %lu. Max = %d",
+   num_act_qp, vha->hw->max_qpairs);
+   rc = -EINVAL;
+   goto out_free;
+   }
+
+   if (num_act_qp != ha->tgt.num_act_qpairs) {
+   ha->tgt.num_act_qpairs = num_act_qp;
+   qlt_clr_qp_table(vha);
+   }
+   rc = count;
+out_free:
+   kfree(buf);
+   return rc;
+}
+
+static const struct file_operations dfs_naqp_ops = {
+   .open   = qla_dfs_naqp_open,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release,
+   .write  = qla_dfs_naqp_write,
+};
+
+
 int
 qla2x00_dfs_setup(scsi_qla_host_t *vha)
 {
@@ -391,6 +466,15 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha)
goto out;
}
 
+   if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) {
+   ha->tgt.dfs_naqp = debugfs_create_file("naqp",
+   0400, ha->

[PATCH v2 10/15] qla2xxx: Add debug logging routine for qpair

2017-06-13 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

For target main path io routines that uses qpair,
create new logging & debugging routines to use
qpair instead of reaching for scsi_qla_host to
reduce cache thrash.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c| 101 ++
 drivers/scsi/qla2xxx/qla_dbg.h|   6 +++
 drivers/scsi/qla2xxx/qla_target.c |  28 +--
 drivers/scsi/qla2xxx/qla_target.h |   1 +
 4 files changed, 122 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 11e097e123bd..c0c90dcc7c7b 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -2713,3 +2713,104 @@ ql_dump_buffer(uint32_t level, scsi_qla_host_t *vha, 
int32_t id,
   buf + cnt, min(16U, size - cnt), false);
}
 }
+
+/*
+ * This function is for formatting and logging log messages.
+ * It is to be used when vha is available. It formats the message
+ * and logs it to the messages file. All the messages will be logged
+ * irrespective of value of ql2xextended_error_logging.
+ * parameters:
+ * level: The level of the log messages to be printed in the
+ *messages file.
+ * vha:   Pointer to the scsi_qla_host_t
+ * id:This is a unique id for the level. It identifies the
+ *part of the code from where the message originated.
+ * msg:   The message to be displayed.
+ */
+void
+ql_log_qp(uint32_t level, struct qla_qpair *qpair, int32_t id,
+const char *fmt, ...)
+{
+   va_list va;
+   struct va_format vaf;
+   char pbuf[128];
+
+   if (level > ql_errlev)
+   return;
+
+   if (qpair != NULL) {
+   const struct pci_dev *pdev = qpair->pdev;
+   /*  : Message */
+   snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: ",
+   QL_MSGHDR, dev_name(&(pdev->dev)), id);
+   } else {
+   snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ",
+   QL_MSGHDR, ":00:00.0", id);
+   }
+   pbuf[sizeof(pbuf) - 1] = 0;
+
+   va_start(va, fmt);
+
+   vaf.fmt = fmt;
+   vaf.va = 
+
+   switch (level) {
+   case ql_log_fatal: /* FATAL LOG */
+   pr_crit("%s%pV", pbuf, );
+   break;
+   case ql_log_warn:
+   pr_err("%s%pV", pbuf, );
+   break;
+   case ql_log_info:
+   pr_warn("%s%pV", pbuf, );
+   break;
+   default:
+   pr_info("%s%pV", pbuf, );
+   break;
+   }
+
+   va_end(va);
+}
+
+/*
+ * This function is for formatting and logging debug information.
+ * It is to be used when vha is available. It formats the message
+ * and logs it to the messages file.
+ * parameters:
+ * level: The level of the debug messages to be printed.
+ *If ql2xextended_error_logging value is correctly set,
+ *this message will appear in the messages file.
+ * vha:   Pointer to the scsi_qla_host_t.
+ * id:This is a unique identifier for the level. It identifies the
+ *part of the code from where the message originated.
+ * msg:   The message to be displayed.
+ */
+void
+ql_dbg_qp(uint32_t level, struct qla_qpair *qpair, int32_t id,
+const char *fmt, ...)
+{
+   va_list va;
+   struct va_format vaf;
+
+   if (!ql_mask_match(level))
+   return;
+
+   va_start(va, fmt);
+
+   vaf.fmt = fmt;
+   vaf.va = 
+
+   if (qpair != NULL) {
+   const struct pci_dev *pdev = qpair->pdev;
+   /*   : Message */
+   pr_warn("%s [%s]-%04x: %pV",
+   QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset,
+   );
+   } else {
+   pr_warn("%s [%s]-%04x: : %pV",
+   QL_MSGHDR, ":00:00.0", id + ql_dbg_offset, );
+   }
+
+   va_end(va);
+
+}
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index c6bffe929fe7..f60138f66dce 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -313,12 +313,18 @@ void __attribute__((format (printf, 4, 5)))
 ql_dbg(uint32_t, scsi_qla_host_t *vha, int32_t, const char *fmt, ...);
 void __attribute__((format (printf, 4, 5)))
 ql_dbg_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...);
+void __attribute__((format (printf, 4, 5)))
+ql_dbg_qp(uint32_t, struct qla_qpair *, int32_t, const char *fmt, ...);
+
 
 void __attribute__((format (printf, 4, 5)))
 ql_log(uint32_t, scsi_qla_host_t *vha, int32_t, const char *fmt, ...);
 void __attribute__((format (printf, 4, 5)))
 ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt,

[PATCH v2 15/15] qla2xxx: Update driver version to 9.01.00.00-k

2017-06-13 Thread Himanshu Madhani
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
Signed-off-by: Giridhar Malavali <giridhar.malav...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_version.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_version.h 
b/drivers/scsi/qla2xxx/qla_version.h
index 45bc84e8e3bf..dcbb9bb05e99 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,9 +7,9 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION  "9.00.00.00-k"
+#define QLA2XXX_VERSION  "9.01.00.00-k"
 
 #define QLA_DRIVER_MAJOR_VER   9
-#define QLA_DRIVER_MINOR_VER   0
+#define QLA_DRIVER_MINOR_VER   1
 #define QLA_DRIVER_PATCH_VER   0
 #define QLA_DRIVER_BETA_VER0
-- 
2.12.0



[PATCH v2 13/15] qla2xxx: Move target stat counters from vha to qpair.

2017-06-13 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Move counters to qpair to reduce cache miss.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h | 27 +++--
 drivers/scsi/qla2xxx/qla_dfs.c | 48 +++---
 drivers/scsi/qla2xxx/qla_iocb.c|  2 +-
 drivers/scsi/qla2xxx/qla_target.c  | 13 +--
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  8 +++
 5 files changed, 63 insertions(+), 35 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 17b13dd92511..e1af9db3691d 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3183,6 +3183,18 @@ struct qla_tc_param {
 #define QLA_MAX_VPORTS_QLA24XX 128
 #define QLA_MAX_VPORTS_QLA25XX 256
 
+struct qla_tgt_counters {
+   uint64_t qla_core_sbt_cmd;
+   uint64_t core_qla_que_buf;
+   uint64_t qla_core_ret_ctio;
+   uint64_t core_qla_snd_status;
+   uint64_t qla_core_ret_sta_ctio;
+   uint64_t core_qla_free_cmd;
+   uint64_t num_q_full_sent;
+   uint64_t num_alloc_iocb_failed;
+   uint64_t num_term_xchg_sent;
+};
+
 struct qla_qpair;
 
 /* Response queue data structure */
@@ -3285,6 +3297,7 @@ struct qla_qpair {
struct list_head qp_list_elem; /* vha->qp_list */
struct list_head hints_list;
uint16_t cpuid;
+   struct qla_tgt_counters tgt_counters;
 };
 
 /* Place holder for FW buffer parameters */
@@ -3964,18 +3977,6 @@ struct qla_hw_data {
int allow_cna_fw_dump;
 };
 
-struct qla_tgt_counters {
-   uint64_t qla_core_sbt_cmd;
-   uint64_t core_qla_que_buf;
-   uint64_t qla_core_ret_ctio;
-   uint64_t core_qla_snd_status;
-   uint64_t qla_core_ret_sta_ctio;
-   uint64_t core_qla_free_cmd;
-   uint64_t num_q_full_sent;
-   uint64_t num_alloc_iocb_failed;
-   uint64_t num_term_xchg_sent;
-};
-
 /*
  * Qlogic scsi host structure
  */
@@ -4140,10 +4141,8 @@ typedef struct scsi_qla_host {
struct fc_host_statistics fc_host_stat;
struct qla_statistics qla_stats;
struct bidi_statistics bidi_stats;
-
atomic_tvref_count;
struct qla8044_reset_template reset_tmplt;
-   struct qla_tgt_counters tgt_counters;
uint16_tbbcr;
struct name_list_extended gnl;
/* Count of active session/fcport */
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 63d7374dce77..d231e7156134 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -164,26 +164,56 @@ static int
 qla_dfs_tgt_counters_show(struct seq_file *s, void *unused)
 {
struct scsi_qla_host *vha = s->private;
+   struct qla_qpair *qpair = vha->hw->base_qpair;
+   uint64_t qla_core_sbt_cmd, core_qla_que_buf, qla_core_ret_ctio,
+   core_qla_snd_status, qla_core_ret_sta_ctio, core_qla_free_cmd,
+   num_q_full_sent, num_alloc_iocb_failed, num_term_xchg_sent;
+   u16 i;
+
+   qla_core_sbt_cmd = qpair->tgt_counters.qla_core_sbt_cmd;
+   core_qla_que_buf = qpair->tgt_counters.core_qla_que_buf;
+   qla_core_ret_ctio = qpair->tgt_counters.qla_core_ret_ctio;
+   core_qla_snd_status = qpair->tgt_counters.core_qla_snd_status;
+   qla_core_ret_sta_ctio = qpair->tgt_counters.qla_core_ret_sta_ctio;
+   core_qla_free_cmd = qpair->tgt_counters.core_qla_free_cmd;
+   num_q_full_sent = qpair->tgt_counters.num_q_full_sent;
+   num_alloc_iocb_failed = qpair->tgt_counters.num_alloc_iocb_failed;
+   num_term_xchg_sent = qpair->tgt_counters.num_term_xchg_sent;
+
+   for (i = 0; i < vha->hw->max_qpairs; i++) {
+   qpair = vha->hw->queue_pair_map[i];
+   qla_core_sbt_cmd += qpair->tgt_counters.qla_core_sbt_cmd;
+   core_qla_que_buf += qpair->tgt_counters.core_qla_que_buf;
+   qla_core_ret_ctio += qpair->tgt_counters.qla_core_ret_ctio;
+   core_qla_snd_status += qpair->tgt_counters.core_qla_snd_status;
+   qla_core_ret_sta_ctio +=
+   qpair->tgt_counters.qla_core_ret_sta_ctio;
+   core_qla_free_cmd += qpair->tgt_counters.core_qla_free_cmd;
+   num_q_full_sent += qpair->tgt_counters.num_q_full_sent;
+   num_alloc_iocb_failed +=
+   qpair->tgt_counters.num_alloc_iocb_failed;
+   num_term_xchg_sent += qpair->tgt_counters.num_term_xchg_sent;
+   }
 
seq_puts(s, "Target Counters\n");
seq_printf(s, "qla_core_sbt_cmd = %lld\n",
-   vha->tgt_counters.qla_core_sbt_cmd);
+   qla_core_sbt_cmd);
seq_printf(s, "qla_core_ret_sta_ctio = %lld\n",
-   vha->tgt_counters.

[PATCH v2 14/15] qla2xxx: Include Exchange offload/Extended Login into FW dump

2017-06-13 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Add missing memory dump of Exchange Offload and Extended
login into FW dump.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c  | 49 +
 drivers/scsi/qla2xxx/qla_dbg.h  | 11 +
 drivers/scsi/qla2xxx/qla_init.c |  7 ++
 drivers/scsi/qla2xxx/qla_os.c   |  3 ---
 4 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index c0c90dcc7c7b..f91ee717202d 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -498,6 +498,50 @@ qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, 
uint32_t **last_chain)
 }
 
 static inline void *
+qla25xx_copy_exlogin(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
+{
+   struct qla2xxx_offld_chain *c = ptr;
+
+   if (!ha->exlogin_buf)
+   return ptr;
+
+   *last_chain = >type;
+
+   c->type = cpu_to_be32(DUMP_CHAIN_EXLOGIN);
+   c->chain_size = cpu_to_be32(sizeof(struct qla2xxx_offld_chain) +
+   ha->exlogin_size);
+   c->size = cpu_to_be32(ha->exlogin_size);
+   c->addr = cpu_to_be64(ha->exlogin_buf_dma);
+
+   ptr += sizeof(struct qla2xxx_offld_chain);
+   memcpy(ptr, ha->exlogin_buf, ha->exlogin_size);
+
+   return (char *)ptr + cpu_to_be32(c->size);
+}
+
+static inline void *
+qla81xx_copy_exchoffld(struct qla_hw_data *ha, void *ptr, uint32_t 
**last_chain)
+{
+   struct qla2xxx_offld_chain *c = ptr;
+
+   if (!ha->exchoffld_buf)
+   return ptr;
+
+   *last_chain = >type;
+
+   c->type = cpu_to_be32(DUMP_CHAIN_EXCHG);
+   c->chain_size = cpu_to_be32(sizeof(struct qla2xxx_offld_chain) +
+   ha->exchoffld_size);
+   c->size = cpu_to_be32(ha->exchoffld_size);
+   c->addr = cpu_to_be64(ha->exchoffld_buf_dma);
+
+   ptr += sizeof(struct qla2xxx_offld_chain);
+   memcpy(ptr, ha->exchoffld_buf, ha->exchoffld_size);
+
+   return (char *)ptr + cpu_to_be32(c->size);
+}
+
+static inline void *
 qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr,
uint32_t **last_chain)
 {
@@ -1606,6 +1650,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, _chain);
nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, _chain);
nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, _chain);
+   nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, _chain);
if (last_chain) {
ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
*last_chain |= htonl(DUMP_CHAIN_LAST);
@@ -1932,6 +1977,8 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, _chain);
nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, _chain);
nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, _chain);
+   nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, _chain);
+   nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, _chain);
if (last_chain) {
ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
*last_chain |= htonl(DUMP_CHAIN_LAST);
@@ -2443,6 +2490,8 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, _chain);
nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, _chain);
nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, _chain);
+   nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, _chain);
+   nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, _chain);
if (last_chain) {
ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
*last_chain |= htonl(DUMP_CHAIN_LAST);
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index f60138f66dce..8877aa97d829 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -232,6 +232,15 @@ struct qla2xxx_fce_chain {
uint32_t eregs[8];
 };
 
+/* used by exchange off load and extended login offload */
+struct qla2xxx_offld_chain {
+   uint32_t type;
+   uint32_t chain_size;
+
+   uint32_t size;
+   u64  addr;
+};
+
 struct qla2xxx_mq_chain {
uint32_t type;
uint32_t chain_size;
@@ -258,6 +267,8 @@ struct qla2xxx_mqueue_chain {
 #define DUMP_CHAIN_FCE 0x7AF0
 #define DUMP_CHAIN_MQ  0x7AF1
 #define DUMP_CHAIN_QUEUE   0x7AF2
+#define DUMP_CHAIN_EXLOGIN 0x7AF3
+#define DUMP_CHAIN_EXCHG   0x7AF4
 #define DUMP_CHAIN_LAST0x8000
 
 struct qla2xxx_fw_dump {
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 48c0a58330d4..72d9ca138ffd 100644
--- a/driver

[PATCH v2 06/15] qla2xxx: Add fw_started flags to qpair

2017-06-13 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Add fw_started flag to qpair to reduce cache thrash.
This reduce access to qla_hw_data structure by each
qpair.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h| 21 +
 drivers/scsi/qla2xxx/qla_init.c   |  4 ++--
 drivers/scsi/qla2xxx/qla_isr.c|  2 +-
 drivers/scsi/qla2xxx/qla_target.c |  9 -
 4 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 18b37c864250..0dec148a4580 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3262,6 +3262,7 @@ struct qla_qpair {
/* move vha->flags.difdix_supported here */
uint32_t difdix_supported:1;
uint32_t delete_in_progress:1;
+   uint32_t fw_started:1;
 
uint16_t id;/* qp number used with FW */
uint16_t vp_idx;/* vport ID */
@@ -4183,6 +4184,26 @@ struct qla2_sgx {
srb_t   *sp;
 };
 
+#define QLA_FW_STARTED(_ha) {  \
+   int i;  \
+   _ha->flags.fw_started = 1;  \
+   _ha->base_qpair->fw_started = 1;\
+   for (i = 0; i < _ha->max_qpairs; i++) { \
+   if (_ha->queue_pair_map[i]) \
+   _ha->queue_pair_map[i]->fw_started = 1; \
+   }   \
+}
+
+#define QLA_FW_STOPPED(_ha) {  \
+   int i;  \
+   _ha->flags.fw_started = 0;  \
+   _ha->base_qpair->fw_started = 0;\
+   for (i = 0; i < _ha->max_qpairs; i++) { \
+   if (_ha->queue_pair_map[i]) \
+   _ha->queue_pair_map[i]->fw_started = 0; \
+   }   \
+}
+
 /*
  * Macros to help code, maintain, etc.
  */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index dcc306121a3d..e6a1f9ca0e95 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3207,7 +3207,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
} else {
ql_dbg(ql_dbg_init, vha, 0x00d3,
"Init Firmware -- success.\n");
-   ha->flags.fw_started = 1;
+   QLA_FW_STARTED(ha);
}
 
return (rval);
@@ -6841,7 +6841,7 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha)
ret = qla2x00_stop_firmware(vha);
}
 
-   ha->flags.fw_started = 0;
+   QLA_FW_STOPPED(ha);
ha->flags.fw_init_done = 0;
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 3c9f9aa7f2c2..40385bc1d1fa 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -710,7 +710,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que 
*rsp, uint16_t *mb)
 
ha->isp_ops->fw_dump(vha, 1);
ha->flags.fw_init_done = 0;
-   ha->flags.fw_started = 0;
+   QLA_FW_STOPPED(ha);
 
if (IS_FWI2_CAPABLE(ha)) {
if (mb[1] == 0 && mb[2] == 0) {
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index cbe6ff9f663e..e25f1fae2c3d 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -3086,7 +3086,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int 
xmit_type,
else
vha->tgt_counters.core_qla_que_buf++;
 
-   if (!ha->flags.fw_started || cmd->reset_count != ha->chip_reset) {
+   if (!qpair->fw_started || cmd->reset_count != vha->hw->chip_reset) {
/*
 * Either the port is not online or this request was from
 * previous life, just abort the processing.
@@ -3096,7 +3096,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int 
xmit_type,
ql_dbg(ql_dbg_async, vha, 0xe101,
"RESET-RSP online/active/old-count/new-count = 
%d/%d/%d/%d.\n",
vha->flags.online, qla2x00_reset_active(vha),
-   cmd->reset_count, ha->chip_reset);
+   cmd->reset_count, vha->hw->chip_reset);
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return 0;
}
@@ -3206,7 +3206,6 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
 {
struct ctio7_to_24xx *pkt;
struct scsi_qla_host *vha = cmd->vha;
-   struct qla_hw_data *ha = vha->hw;
struct qla_tgt *tgt = cmd->tgt;
struct qla_tgt_prm prm;
unsigned long flags = 0;
@@ -3223,7 +3222,7 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
if (qlt_pc

[PATCH v2 04/15] qla2xxx: Fix mailbox failure while deleting Queue pairs

2017-06-13 Thread Himanshu Madhani
From: Sawan Chandak <sawan.chan...@cavium.com>

In target mode driver, queue pairs are not created during driver load time,
instead they are created at the configuration time after chip reset.
If a user tries to load/unload driver after queue pairs are created, then
there would be mailbox failure, while deleting queue pairs.
Flag is added to check if queue pairs are created or not. Queue pairs will
be deleted only If they were created during target configuration.

Signed-off-by: Sawan Chandak <sawan.chan...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h  |  2 ++
 drivers/scsi/qla2xxx/qla_init.c | 10 --
 drivers/scsi/qla2xxx/qla_mid.c  |  4 
 drivers/scsi/qla2xxx/qla_os.c   |  1 +
 4 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 005ca2de3795..8b52f431a812 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3997,6 +3997,8 @@ typedef struct scsi_qla_host {
uint32_tfw_tgt_reported:1;
uint32_tbbcr_enable:1;
uint32_tqpairs_available:1;
+   uint32_tqpairs_req_created:1;
+   uint32_tqpairs_rsp_created:1;
} flags;
 
atomic_tloop_state;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index fa5e6ab8e4a7..dcc306121a3d 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7719,9 +7719,12 @@ struct qla_qpair *qla2xxx_create_qpair(struct 
scsi_qla_host *vha, int qos,
 
 int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair)
 {
-   int ret;
+   int ret = QLA_FUNCTION_FAILED;
struct qla_hw_data *ha = qpair->hw;
 
+   if (!vha->flags.qpairs_req_created && !vha->flags.qpairs_rsp_created)
+   goto fail;
+
qpair->delete_in_progress = 1;
while (atomic_read(>ref_count))
msleep(500);
@@ -7738,8 +7741,11 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, 
struct qla_qpair *qpair)
clear_bit(qpair->id, ha->qpair_qid_map);
ha->num_qpairs--;
list_del(>qp_list_elem);
-   if (list_empty(>qp_list))
+   if (list_empty(>qp_list)) {
vha->flags.qpairs_available = 0;
+   vha->flags.qpairs_req_created = 0;
+   vha->flags.qpairs_rsp_created = 0;
+   }
mempool_destroy(qpair->srb_mempool);
kfree(qpair);
mutex_unlock(>mq_lock);
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 4ad452a42dbe..f0605cd196fb 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -645,6 +645,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t 
options,
int ret = 0;
struct req_que *req = NULL;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
+   struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev);
uint16_t que_id = 0;
device_reg_t *reg;
uint32_t cnt;
@@ -741,6 +742,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t 
options,
mutex_unlock(>mq_lock);
goto que_failed;
}
+   vha->flags.qpairs_req_created = 1;
}
 
return req->id;
@@ -772,6 +774,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t 
options,
int ret = 0;
struct rsp_que *rsp = NULL;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
+   struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev);
uint16_t que_id = 0;
device_reg_t *reg;
 
@@ -855,6 +858,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t 
options,
mutex_unlock(>mq_lock);
goto que_failed;
}
+   vha->flags.qpairs_rsp_created = 1;
}
rsp->req = NULL;
 
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3963602aef35..13e4d2428a9a 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -384,6 +384,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, 
struct req_que *req,
ha->base_qpair->rsp = rsp;
ha->base_qpair->vha = vha;
ha->base_qpair->qp_lock_ptr = >hardware_lock;
+   /* init qpair to this cpu. Will adjust at run time. */
ha->base_qpair->msix = >msix_entries[QLA_MSIX_RSP_Q];
INIT_LIST_HEAD(>base_qpair->hints_list);
qla_cpu_update(rsp->qpair, smp_processor_id());
-- 
2.12.0



[PATCH v2 01/17] qla2xxx: Allow ABTS RX, RIDA on ATIOQ for ISP83XX/27XX

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Driver added mechanism to move ABTS/PUREX/RIDA mailbox to
ATIO queue as part of commit id 41dc529a4602ac737020f423f84686a81de38e6d
("qla2xxx: Improve RSCN handling in driver").

This patch addes a check to only allow ABTS/PURX/RIDA
to be moved to ATIO Queue for ISP83XX and ISP27XX.

Cc: <sta...@vger.kernel.org> # 4.11
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_init.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 0391fc317003..f6130e8b1ca1 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -2946,7 +2946,8 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
}
 
/* Move PUREX, ABTS RX & RIDA to ATIOQ */
-   if (ql2xmvasynctoatio) {
+   if (ql2xmvasynctoatio &&
+   (IS_QLA83XX(ha) || IS_QLA27XX(ha))) {
if (qla_tgt_mode_enabled(vha) ||
qla_dual_mode_enabled(vha))
ha->fw_options[2] |= BIT_11;
@@ -2958,7 +2959,9 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
"%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
__func__, ha->fw_options[1], ha->fw_options[2],
ha->fw_options[3], vha->host->active_mode);
-   qla2x00_set_fw_options(vha, ha->fw_options);
+
+   if (ha->fw_options[1] || ha->fw_options[2] || ha->fw_options[3])
+   qla2x00_set_fw_options(vha, ha->fw_options);
 
/* Update Serial Link options. */
if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0)
-- 
2.12.0



[PATCH v2 08/17] qla2xxx: Convert 32-bit LUN usage to 64-bit

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Acked-by: Nicholas Bellinger <n...@linux-iscsi.org>
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c  | 32 +++-
 drivers/scsi/qla2xxx/qla_target.h  |  4 ++--
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  2 +-
 3 files changed, 18 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index a2e17a5794ab..a1f33b06019d 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1799,7 +1799,7 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, 
uint32_t tag)
  * for the same lun)
  */
 static void abort_cmds_for_lun(struct scsi_qla_host *vha,
-   uint32_t lun, uint8_t *s_id)
+   u64 lun, uint8_t *s_id)
 {
struct qla_tgt_sess_op *op;
struct qla_tgt_cmd *cmd;
@@ -1810,7 +1810,7 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
spin_lock_irqsave(>cmd_list_lock, flags);
list_for_each_entry(op, >qla_sess_op_cmd_list, cmd_list) {
uint32_t op_key;
-   uint32_t op_lun;
+   u64 op_lun;
 
op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id);
op_lun = scsilun_to_int(
@@ -1832,7 +1832,7 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
 
list_for_each_entry(cmd, >qla_cmd_list, cmd_list) {
uint32_t cmd_key;
-   uint32_t cmd_lun;
+   u64 cmd_lun;
 
cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id);
cmd_lun = scsilun_to_int(
@@ -1850,18 +1850,15 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host 
*vha,
struct qla_hw_data *ha = vha->hw;
struct se_session *se_sess = sess->se_sess;
struct qla_tgt_mgmt_cmd *mcmd;
+   struct qla_tgt_cmd *cmd;
struct se_cmd *se_cmd;
-   u32 lun = 0;
int rc;
bool found_lun = false;
unsigned long flags;
 
spin_lock_irqsave(_sess->sess_cmd_lock, flags);
list_for_each_entry(se_cmd, _sess->sess_cmd_list, se_cmd_list) {
-   struct qla_tgt_cmd *cmd =
-   container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
if (se_cmd->tag == abts->exchange_addr_to_abort) {
-   lun = cmd->unpacked_lun;
found_lun = true;
break;
}
@@ -1895,12 +1892,13 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host 
*vha,
}
memset(mcmd, 0, sizeof(*mcmd));
 
+   cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
mcmd->sess = sess;
memcpy(>orig_iocb.abts, abts, sizeof(mcmd->orig_iocb.abts));
mcmd->reset_count = vha->hw->chip_reset;
mcmd->tmr_func = QLA_TGT_ABTS;
 
-   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, lun, mcmd->tmr_func,
+   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, cmd->unpacked_lun, 
mcmd->tmr_func,
abts->exchange_addr_to_abort);
if (rc != 0) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf052,
@@ -4334,13 +4332,12 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host 
*vha, void *iocb)
struct qla_hw_data *ha = vha->hw;
struct qla_tgt *tgt;
struct fc_port *sess;
-   uint32_t lun, unpacked_lun;
+   u64 unpacked_lun;
int fn;
unsigned long flags;
 
tgt = vha->vha_tgt.qla_tgt;
 
-   lun = a->u.isp24.fcp_cmnd.lun;
fn = a->u.isp24.fcp_cmnd.task_mgmt_flags;
 
spin_lock_irqsave(>tgt.sess_lock, flags);
@@ -4348,7 +4345,8 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host 
*vha, void *iocb)
a->u.isp24.fcp_hdr.s_id);
spin_unlock_irqrestore(>tgt.sess_lock, flags);
 
-   unpacked_lun = scsilun_to_int((struct scsi_lun *));
+   unpacked_lun =
+   scsilun_to_int((struct scsi_lun *)>u.isp24.fcp_cmnd.lun);
 
if (!sess) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf024,
@@ -4371,7 +4369,7 @@ static int __qlt_abort_task(struct scsi_qla_host *vha,
struct atio_from_isp *a = (struct atio_from_isp *)iocb;
struct qla_hw_data *ha = vha->hw;
struct qla_tgt_mgmt_cmd *mcmd;
-   uint32_t lun, unpacked_lun;
+   u64 unpacked_lun;
int rc;
 
mcmd = mempool_alloc(qla_tgt_mgmt_cmd_mempool, GFP_ATOMIC);
@@ -4387,8 +4385,8 @@ static int __qlt_abort_task(struct scsi_qla_host *vha,
memcpy(>orig_iocb.imm_ntfy, iocb,
sizeof(mcmd->orig_iocb.imm_ntfy));
 
-   lun = a->u.isp24.fcp_cmnd.lun;
-   unpacked_lun = scsilun_to_int((struct scsi_lun *));
+   unpacked_lun =
+   scsilun_to_int((struct scs

[PATCH v2 04/17] qla2xxx: Include Exchange offload/Extended Login into FW dump

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Add missing memory dump of Exchange Offload and Extended
login into FW dump.

Cc: <sta...@vger.kernel.org>
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c  | 51 +
 drivers/scsi/qla2xxx/qla_dbg.h  | 12 ++
 drivers/scsi/qla2xxx/qla_init.c |  7 ++
 drivers/scsi/qla2xxx/qla_os.c   |  3 ---
 4 files changed, 70 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 88748a6ab73f..108499837e5d 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -498,6 +498,52 @@ qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, 
uint32_t **last_chain)
 }
 
 static inline void *
+qla25xx_copy_exlogin(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
+{
+   struct qla2xxx_offld_chain *c = ptr;
+
+   if (!ha->exlogin_buf)
+   return ptr;
+
+   *last_chain = >type;
+
+   c->type = htonl(DUMP_CHAIN_EXLOGIN);
+   c->chain_size = htonl(sizeof(struct qla2xxx_offld_chain) +
+   ha->exlogin_size);
+   c->size = htonl(ha->exlogin_size);
+   c->addr_l = htonl(LSD(ha->exlogin_buf_dma));
+   c->addr_h = htonl(MSD(ha->exlogin_buf_dma));
+
+   ptr += sizeof(struct qla2xxx_offld_chain);
+   memcpy(ptr, ha->exlogin_buf, ha->exlogin_size);
+
+   return (char *)ptr + ntohl(c->size);
+}
+
+static inline void *
+qla81xx_copy_exchoffld(struct qla_hw_data *ha, void *ptr, uint32_t 
**last_chain)
+{
+   struct qla2xxx_offld_chain *c = ptr;
+
+   if (!ha->exchoffld_buf)
+   return ptr;
+
+   *last_chain = >type;
+
+   c->type = htonl(DUMP_CHAIN_EXCHG);
+   c->chain_size = htonl(sizeof(struct qla2xxx_offld_chain) +
+   ha->exchoffld_size);
+   c->size = htonl(ha->exchoffld_size);
+   c->addr_l = htonl(LSD(ha->exchoffld_buf_dma));
+   c->addr_h = htonl(MSD(ha->exchoffld_buf_dma));
+
+   ptr += sizeof(struct qla2xxx_offld_chain);
+   memcpy(ptr, ha->exchoffld_buf, ha->exchoffld_size);
+
+   return (char *)ptr + ntohl(c->size);
+}
+
+static inline void *
 qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr,
uint32_t **last_chain)
 {
@@ -1606,6 +1652,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, _chain);
nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, _chain);
nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, _chain);
+   nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, _chain);
if (last_chain) {
ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
*last_chain |= htonl(DUMP_CHAIN_LAST);
@@ -1932,6 +1979,8 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, _chain);
nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, _chain);
nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, _chain);
+   nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, _chain);
+   nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, _chain);
if (last_chain) {
ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
*last_chain |= htonl(DUMP_CHAIN_LAST);
@@ -2443,6 +2492,8 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, _chain);
nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, _chain);
nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, _chain);
+   nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, _chain);
+   nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, _chain);
if (last_chain) {
ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
*last_chain |= htonl(DUMP_CHAIN_LAST);
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index c6bffe929fe7..c4b1bb76cf48 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -232,6 +232,16 @@ struct qla2xxx_fce_chain {
uint32_t eregs[8];
 };
 
+/* used by exchange off load and extended login offload */
+struct qla2xxx_offld_chain {
+   uint32_t type;
+   uint32_t chain_size;
+
+   uint32_t size;
+   uint32_t addr_l;
+   uint32_t addr_h;
+};
+
 struct qla2xxx_mq_chain {
uint32_t type;
uint32_t chain_size;
@@ -258,6 +268,8 @@ struct qla2xxx_mqueue_chain {
 #define DUMP_CHAIN_FCE 0x7AF0
 #define DUMP_CHAIN_MQ  0x7AF1
 #define DUMP_CHAIN_QUEUE   0x7AF2
+#define DUMP_CHAIN_EXLOGIN 0x7AF3
+#define DUMP_CHAIN_EXCHG   0x7AF4
 #define DUMP_CHAIN_LAST0x8000
 
 struct qla2xxx_fw_dump {
diff -

[PATCH v2 13/17] qla2xxx: Remove redundant code

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

During ABTS or Abort task, qla2xxx does a pre-search for
the se_cmd, based on command's tag. The same search is
performed by TCM. Remove the extra search from qla2xxx.

The reason for hard coding LUN ID to 0 is that, from the FC
protocol perspective, ABTS does not have any knowledge of
LUN ID. So, there is no reason for qla2xxx driver to
manufacture the LUN ID.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
Acked-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/scsi/qla2xxx/qla_target.c | 39 +++
 1 file changed, 11 insertions(+), 28 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 765145151fa0..d2c9b565ca00 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1838,40 +1838,24 @@ static void abort_cmds_for_lun(struct scsi_qla_host 
*vha,
spin_unlock_irqrestore(>cmd_list_lock, flags);
 }
 
+/*
+ * From FC protocol perspective, ABTS does not have any knowledge of LUN ID.
+ * Passing default LUN ID of 0.
+ */
+#define DEFAULT_LUN_ID 0
+
 /* ha->hardware_lock supposed to be held on entry */
 static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
struct abts_recv_from_24xx *abts, struct fc_port *sess)
 {
struct qla_hw_data *ha = vha->hw;
-   struct se_session *se_sess = sess->se_sess;
struct qla_tgt_mgmt_cmd *mcmd;
-   struct qla_tgt_cmd *cmd;
-   struct se_cmd *se_cmd;
int rc;
-   bool found_lun = false;
-   unsigned long flags;
 
-   spin_lock_irqsave(_sess->sess_cmd_lock, flags);
-   list_for_each_entry(se_cmd, _sess->sess_cmd_list, se_cmd_list) {
-   if (se_cmd->tag == abts->exchange_addr_to_abort) {
-   found_lun = true;
-   break;
-   }
-   }
-   spin_unlock_irqrestore(_sess->sess_cmd_lock, flags);
-
-   /* cmd not in LIO lists, look in qla list */
-   if (!found_lun) {
-   if (abort_cmd_for_tag(vha, abts->exchange_addr_to_abort)) {
-   /* send TASK_ABORT response immediately */
-   qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_CMPL, false);
-   return 0;
-   } else {
-   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf081,
-   "unable to find cmd in driver or LIO for tag 
0x%x\n",
-   abts->exchange_addr_to_abort);
-   return -ENOENT;
-   }
+   if (abort_cmd_for_tag(vha, abts->exchange_addr_to_abort)) {
+   /* send TASK_ABORT response immediately */
+   qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_CMPL, false);
+   return 0;
}
 
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f,
@@ -1887,13 +1871,12 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host 
*vha,
}
memset(mcmd, 0, sizeof(*mcmd));
 
-   cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
mcmd->sess = sess;
memcpy(>orig_iocb.abts, abts, sizeof(mcmd->orig_iocb.abts));
mcmd->reset_count = vha->hw->chip_reset;
mcmd->tmr_func = QLA_TGT_ABTS;
 
-   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, cmd->unpacked_lun, 
mcmd->tmr_func,
+   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, DEFAULT_LUN_ID, mcmd->tmr_func,
abts->exchange_addr_to_abort);
if (rc != 0) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf052,
-- 
2.12.0



[PATCH v2 16/17] qla2xxx: Remove unused irq_cmd_count field.

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

When driver is unloaded, all sessions are torn down, all
commmands are flushed, chip is reset to ensure there is
no knowledge of target mode in ISP. The irq_cmd_count field
was used to make sure all commands are processed on top of that.
The irq_cmd_count is now redundant and not needed.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 9 +
 drivers/scsi/qla2xxx/qla_target.h | 1 -
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 3eb8e63834e6..c96dcd31b47b 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -5338,8 +5338,6 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, 
response_t *pkt)
 * Otherwise, some commands can stuck.
 */
 
-   tgt->irq_cmd_count++;
-
switch (pkt->entry_type) {
case CTIO_CRC2:
case CTIO_TYPE7:
@@ -5365,10 +5363,8 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, 
response_t *pkt)
}
 
rc = qlt_chk_qfull_thresh_hold(vha, atio, true);
-   if (rc != 0) {
-   tgt->irq_cmd_count--;
+   if (rc != 0)
return;
-   }
 
rc = qlt_handle_cmd_for_atio(vha, atio);
if (unlikely(rc != 0)) {
@@ -5500,7 +5496,6 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, 
response_t *pkt)
break;
}
 
-   tgt->irq_cmd_count--;
 }
 
 /*
@@ -5530,7 +5525,6 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host 
*vha,
 * Otherwise, some commands can stuck.
 */
 
-   tgt->irq_cmd_count++;
 
switch (code) {
case MBA_RESET: /* Reset */
@@ -5618,7 +5612,6 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host 
*vha,
break;
}
 
-   tgt->irq_cmd_count--;
 }
 
 static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha,
diff --git a/drivers/scsi/qla2xxx/qla_target.h 
b/drivers/scsi/qla2xxx/qla_target.h
index 07ff565485b7..c328a267c4c3 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -790,7 +790,6 @@ struct qla_tgt {
 * because req_pkt() can drop/reaquire HW lock inside. Protected by
 * HW lock.
 */
-   int irq_cmd_count;
int atio_irq_cmd_count;
 
int datasegs_per_cmd, datasegs_per_cont, sg_tablesize;
-- 
2.12.0



[PATCH v2 14/17] qla2xxx: Remove redundant wait when target is stopped.

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Current code already destroy all target sessions when
target Mode is stopped. Target core would waits for
all commands that belong to each session to purge.
The extra wait for interrupts to settle down is not
relevant.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 33 -
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index d2c9b565ca00..3eb8e63834e6 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1427,6 +1427,8 @@ int qlt_stop_phase1(struct qla_tgt *tgt)
 
if (npiv_vports) {
mutex_unlock(_tgt_mutex);
+   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf021,
+   "NPIV is in use. Can not stop target\n");
return -EPERM;
}
}
@@ -1437,7 +1439,7 @@ int qlt_stop_phase1(struct qla_tgt *tgt)
return -EPERM;
}
 
-   ql_dbg(ql_dbg_tgt, vha, 0xe003, "Stopping target for host %ld(%p)\n",
+   ql_dbg(ql_dbg_tgt_mgt, vha, 0xe003, "Stopping target for host 
%ld(%p)\n",
vha->host_no, vha);
/*
 * Mutex needed to sync with qla_tgt_fc_port_[added,deleted].
@@ -1480,9 +1482,7 @@ EXPORT_SYMBOL(qlt_stop_phase1);
 /* Called by tcm_qla2xxx configfs code */
 void qlt_stop_phase2(struct qla_tgt *tgt)
 {
-   struct qla_hw_data *ha = tgt->ha;
-   scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
-   unsigned long flags;
+   scsi_qla_host_t *vha = tgt->vha;
 
if (tgt->tgt_stopped) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04f,
@@ -1490,24 +1490,19 @@ void qlt_stop_phase2(struct qla_tgt *tgt)
dump_stack();
return;
}
-
-   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00b,
-   "Waiting for %d IRQ commands to complete (tgt %p)",
-   tgt->irq_cmd_count, tgt);
+   if (!tgt->tgt_stop) {
+   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00b,
+   "%s: phase1 stop is not completed\n", __func__);
+   dump_stack();
+   return;
+   }
 
mutex_lock(>vha_tgt.tgt_mutex);
-   spin_lock_irqsave(>hardware_lock, flags);
-   while ((tgt->irq_cmd_count != 0) || (tgt->atio_irq_cmd_count != 0)) {
-   spin_unlock_irqrestore(>hardware_lock, flags);
-   udelay(2);
-   spin_lock_irqsave(>hardware_lock, flags);
-   }
tgt->tgt_stop = 0;
tgt->tgt_stopped = 1;
-   spin_unlock_irqrestore(>hardware_lock, flags);
mutex_unlock(>vha_tgt.tgt_mutex);
 
-   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00c, "Stop of tgt %p finished",
+   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00c, "Stop of tgt %p finished\n",
tgt);
 }
 EXPORT_SYMBOL(qlt_stop_phase2);
@@ -1517,6 +1512,10 @@ static void qlt_release(struct qla_tgt *tgt)
 {
scsi_qla_host_t *vha = tgt->vha;
 
+   if ((vha->vha_tgt.qla_tgt != NULL) && !tgt->tgt_stop &&
+   !tgt->tgt_stopped)
+   qlt_stop_phase1(tgt);
+
if ((vha->vha_tgt.qla_tgt != NULL) && !tgt->tgt_stopped)
qlt_stop_phase2(tgt);
 
@@ -5514,7 +5513,7 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host 
*vha,
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
int login_code;
 
-   if (!ha->tgt.tgt_ops)
+   if (!tgt || tgt->tgt_stop || tgt->tgt_stopped)
return;
 
if (unlikely(tgt == NULL)) {
-- 
2.12.0



[PATCH v2 12/17] qla2xxx: Add ql2xiniexchg parameter

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Previously, the ql2xexchoffld module parameter was used to control
the max number of exchanges to be offload onto host memory.

Module parameter ql_dm_tgt_ex_pct was used to control the percentage
of exchanges allocated to the Target side.

With this patch, module parameter ql_dm_tgt_ex_pct is no longer used
to control exchanges for the driver. New module parameter ql2xiniexchg
is added to control exchanges between target mode and initiator mode.

With the updated module parameters, users can control the exact number
of exchanges for either Initiator or Target. The exchange offload feature
will be automatically enabled when the total number of exchanges exceeds
2048 limit.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h|   6 +-
 drivers/scsi/qla2xxx/qla_gbl.h|   3 +-
 drivers/scsi/qla2xxx/qla_init.c   |   2 +-
 drivers/scsi/qla2xxx/qla_inline.h |  16 +
 drivers/scsi/qla2xxx/qla_mbx.c|  14 ++--
 drivers/scsi/qla2xxx/qla_os.c | 136 +++---
 drivers/scsi/qla2xxx/qla_target.c |  54 ---
 7 files changed, 143 insertions(+), 88 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 51b262b236b4..ddf93efe3986 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -286,7 +286,7 @@ struct name_list_extended {
 #define RESPONSE_ENTRY_CNT_MQ  128 /* Number of response entries.*/
 #define ATIO_ENTRY_CNT_24XX4096/* Number of ATIO entries. */
 #define RESPONSE_ENTRY_CNT_FX00256 /* Number of response 
entries.*/
-#define EXTENDED_EXCH_ENTRY_CNT32768   /* Entries for offload 
case */
+#define FW_DEF_EXCHANGES_CNT 2048
 
 struct req_que;
 struct qla_tgt_sess;
@@ -3593,6 +3593,10 @@ struct qla_hw_data {
 #define IS_SHADOW_REG_CAPABLE(ha)  (IS_QLA27XX(ha))
 #define IS_DPORT_CAPABLE(ha)  (IS_QLA83XX(ha) || IS_QLA27XX(ha))
 #define IS_FAWWN_CAPABLE(ha)   (IS_QLA83XX(ha) || IS_QLA27XX(ha))
+#define IS_EXCHG_OFFLD_CAPABLE(ha) \
+   (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
+#define IS_EXLOGIN_OFFLD_CAPABLE(ha) \
+   (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
 
/* HBA serial number */
uint8_t serial0;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 5b2451745e9f..f8540f5c9e5d 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -137,6 +137,7 @@ extern int ql2xmdcapmask;
 extern int ql2xmdenable;
 extern int ql2xexlogins;
 extern int ql2xexchoffld;
+extern int ql2xiniexchg;
 extern int ql2xfwholdabts;
 extern int ql2xmvasynctoatio;
 
@@ -839,7 +840,7 @@ extern int qla_get_exlogin_status(scsi_qla_host_t *, 
uint16_t *,
uint16_t *);
 extern int qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr);
 extern int qla_get_exchoffld_status(scsi_qla_host_t *, uint16_t *, uint16_t *);
-extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *, dma_addr_t);
+extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *);
 extern void qlt_handle_abts_recv(struct scsi_qla_host *, response_t *);
 
 int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *,
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index c422c14dfb07..0ee9159457e4 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -2730,7 +2730,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
if (ql2xexlogins)
ha->flags.exlogins_enabled = 1;
 
-   if (ql2xexchoffld)
+   if (qla_is_exch_offld_enabled(vha))
ha->flags.exchoffld_enabled = 1;
 
rval = qla2x00_execute_fw(vha, srisc_address);
diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index c61a6a871c8e..9996ec0daab1 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -307,3 +307,19 @@ qla2x00_set_retry_delay_timestamp(fc_port_t *fcport, 
uint16_t retry_delay)
fcport->retry_delay_timestamp = jiffies +
(retry_delay * HZ / 10);
 }
+
+static inline bool
+qla_is_exch_offld_enabled(struct scsi_qla_host *vha)
+{
+   if (qla_ini_mode_enabled(vha) &&
+   (ql2xiniexchg > FW_DEF_EXCHANGES_CNT))
+   return true;
+   else if (qla_tgt_mode_enabled(vha) &&
+   (ql2xexchoffld > FW_DEF_EXCHANGES_CNT))
+   return true;
+   else if (qla_dual_mode_enabled(vha) &&
+   ((ql2xiniexchg + ql2xexchoffld) > FW_DEF_EXCHANGES_CNT))
+   return true;
+   else
+   return false;
+}
diff --git a/drivers/scsi/qla2xxx/q

[PATCH v2 10/17] qla2xxx: Cleanup debug message IDs

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Assign unique id to all traces and logs for debug purpose.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_attr.c   |   2 +-
 drivers/scsi/qla2xxx/qla_bsg.c|   2 +-
 drivers/scsi/qla2xxx/qla_dbg.c|   2 +-
 drivers/scsi/qla2xxx/qla_dfs.c|   8 +-
 drivers/scsi/qla2xxx/qla_gs.c | 100 +++--
 drivers/scsi/qla2xxx/qla_init.c   | 290 +++---
 drivers/scsi/qla2xxx/qla_isr.c|  18 +--
 drivers/scsi/qla2xxx/qla_mbx.c|  52 +++
 drivers/scsi/qla2xxx/qla_os.c |  30 ++--
 drivers/scsi/qla2xxx/qla_target.c | 217 ++--
 10 files changed, 352 insertions(+), 369 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 7c8d6c54ab70..a93eb42718e5 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -769,7 +769,7 @@ qla2x00_issue_logo(struct file *filp, struct kobject *kobj,
did.b.area = (type & 0xff00) >> 8;
did.b.al_pa = (type & 0x00ff);
 
-   ql_log(ql_log_info, vha, 0x70e3, "portid=%02x%02x%02x done\n",
+   ql_log(ql_log_info, vha, 0xd04d, "portid=%02x%02x%02x done\n",
did.b.domain, did.b.area, did.b.al_pa);
 
ql_log(ql_log_info, vha, 0x70e4, "%s: %d\n", __func__, type);
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index ca3420de5a01..e093795a0371 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -2135,7 +2135,7 @@ qla8044_serdes_op(struct bsg_job *bsg_job)
bsg_reply->reply_payload_rcv_len = sizeof(sr);
break;
default:
-   ql_dbg(ql_dbg_user, vha, 0x70cf,
+   ql_dbg(ql_dbg_user, vha, 0x7020,
"Unknown serdes cmd %x.\n", sr.cmd);
rval = -EINVAL;
break;
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 108499837e5d..54b55b03a5b3 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -62,7 +62,7 @@
  * | Misc |   0xd301   | 0xd031-0xd0ff |
  * |  || 0xd101-0xd1fe |
  * |  || 0xd214-0xd2fe |
- * | Target Mode |   0xe080   ||
+ * | Target Mode |   0xe081   ||
  * | Target Mode Management  |   0xf09b   | 0xf002 |
  * |  || 0xf046-0xf049  |
  * | Target Mode Task Management  |  0x1000d  ||
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 989e17b0758c..391c50be2297 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -70,7 +70,7 @@ qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void 
*unused)
qla2x00_gid_list_size(ha),
_list_dma, GFP_KERNEL);
if (!gid_list) {
-   ql_dbg(ql_dbg_user, vha, 0x705c,
+   ql_dbg(ql_dbg_user, vha, 0x7018,
"DMA allocation failed for %u\n",
 qla2x00_gid_list_size(ha));
return 0;
@@ -370,7 +370,7 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha)
ha->tgt.dfs_tgt_port_database = debugfs_create_file("tgt_port_database",
S_IRUSR,  ha->dfs_dir, vha, _tgt_port_database_ops);
if (!ha->tgt.dfs_tgt_port_database) {
-   ql_log(ql_log_warn, vha, 0x,
+   ql_log(ql_log_warn, vha, 0xd03f,
"Unable to create debugFS tgt_port_database node.\n");
goto out;
}
@@ -386,8 +386,8 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha)
ha->tgt.dfs_tgt_sess = debugfs_create_file("tgt_sess",
S_IRUSR, ha->dfs_dir, vha, _tgt_sess_ops);
if (!ha->tgt.dfs_tgt_sess) {
-   ql_log(ql_log_warn, vha, 0x,
-   "Unable to create debugFS tgt_sess node.\n");
+   ql_log(ql_log_warn, vha, 0xd040,
+   "Unable to create debugFS tgt_sess node.\n");
goto out;
}
 
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index ef8e8891d54f..540fec524ccb 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -2024,7 +2024,7 @@ qla2x00_fdmiv2_rhba(scsi_qla_host_t *vha)
eiter->len = cpu_to_be16(4 + alen);
size += 4 + alen;
 
-   ql_dbg(ql_dbg_disc, vha, 0x20b1,
+   ql_dbg(ql_dbg_disc, vha, 0x201b,
&qu

[PATCH v2 06/17] tcm_qla2xxx: Do not allow aborted cmd to advance.

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

In case of hardware queue full, commands can loop between
TCM stack and tcm_qla2xx shim layers for retry. While command
is waiting for retry, task mgmt can get ahead and abort the
cmmand that encountered queue full condition. Fix this by
dropping the command, if task mgmt has already started the
command free process.

Acked-by: Nicholas Bellinger <n...@linux-iscsi.org>
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/tcm_qla2xxx.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c 
b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 7443e4efa3ae..1131fe8e2dd2 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -686,6 +686,19 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
struct qla_tgt_cmd, se_cmd);
int xmit_type = QLA_TGT_XMIT_STATUS;
 
+   if (cmd->aborted) {
+   /*
+* Cmd can loop during Q-full. tcm_qla2xxx_aborted_task
+* can get ahead of this cmd. tcm_qla2xxx_aborted_task
+* already kick start the free.
+*/
+   pr_debug(
+   "queue_data_in aborted cmd[%p] refcount %d transport_state 
%x, t_state %x, se_cmd_flags %x\n",
+   cmd, kref_read(>se_cmd.cmd_kref),
+   cmd->se_cmd.transport_state, cmd->se_cmd.t_state,
+   cmd->se_cmd.se_cmd_flags);
+   return 0;
+   }
cmd->bufflen = se_cmd->data_length;
cmd->sg = NULL;
cmd->sg_cnt = 0;
-- 
2.12.0



[PATCH v2 02/17] qla2xxx: Replace usage of spin_lock with spin_lock_irqsave

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Convert usage of spin_lock to spin_lock_irqsave because qla2xxx driver
accesses all the data structures in an interrupt context.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 26 ++
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index e766d8412384..a2e17a5794ab 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1762,13 +1762,13 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, 
uint32_t tag)
 {
struct qla_tgt_sess_op *op;
struct qla_tgt_cmd *cmd;
+   unsigned long flags;
 
-   spin_lock(>cmd_list_lock);
-
+   spin_lock_irqsave(>cmd_list_lock, flags);
list_for_each_entry(op, >qla_sess_op_cmd_list, cmd_list) {
if (tag == op->atio.u.isp24.exchange_addr) {
op->aborted = true;
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
return 1;
}
}
@@ -1776,7 +1776,7 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, 
uint32_t tag)
list_for_each_entry(op, >unknown_atio_list, cmd_list) {
if (tag == op->atio.u.isp24.exchange_addr) {
op->aborted = true;
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
return 1;
}
}
@@ -1784,12 +1784,12 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, 
uint32_t tag)
list_for_each_entry(cmd, >qla_cmd_list, cmd_list) {
if (tag == cmd->atio.u.isp24.exchange_addr) {
cmd->aborted = 1;
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
return 1;
}
}
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
 
-   spin_unlock(>cmd_list_lock);
return 0;
 }
 
@@ -1804,9 +1804,10 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
struct qla_tgt_sess_op *op;
struct qla_tgt_cmd *cmd;
uint32_t key;
+   unsigned long flags;
 
key = sid_to_key(s_id);
-   spin_lock(>cmd_list_lock);
+   spin_lock_irqsave(>cmd_list_lock, flags);
list_for_each_entry(op, >qla_sess_op_cmd_list, cmd_list) {
uint32_t op_key;
uint32_t op_lun;
@@ -1839,7 +1840,7 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
if (cmd_key == key && cmd_lun == lun)
cmd->aborted = 1;
}
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
 }
 
 /* ha->hardware_lock supposed to be held on entry */
@@ -4216,9 +4217,9 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host 
*vha,
memcpy(>atio, atio, sizeof(*atio));
op->vha = vha;
 
-   spin_lock(>cmd_list_lock);
+   spin_lock_irqsave(>cmd_list_lock, flags);
list_add_tail(>cmd_list, >qla_sess_op_cmd_list);
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
 
INIT_WORK(>work, qlt_create_sess_from_atio);
queue_work(qla_tgt_wq, >work);
@@ -4529,12 +4530,13 @@ static int abort_cmds_for_s_id(struct scsi_qla_host 
*vha, port_id_t *s_id)
struct qla_tgt_cmd *cmd;
uint32_t key;
int count = 0;
+   unsigned long flags;
 
key = (((u32)s_id->b.domain << 16) |
   ((u32)s_id->b.area   <<  8) |
   ((u32)s_id->b.al_pa));
 
-   spin_lock(>cmd_list_lock);
+   spin_lock_irqsave(>cmd_list_lock, flags);
list_for_each_entry(op, >qla_sess_op_cmd_list, cmd_list) {
uint32_t op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id);
 
@@ -4559,7 +4561,7 @@ static int abort_cmds_for_s_id(struct scsi_qla_host *vha, 
port_id_t *s_id)
count++;
}
}
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
 
return count;
 }
-- 
2.12.0



[PATCH v2 00/17] qla2xxx: Cleanup and minor fixes

2017-05-30 Thread Himanshu Madhani
Hi Martin,

This series contains patches that were dropped from 4.12.0-rc3 inclusion, since
they can go to 4.13 merge window.

Changes from v1 --> v2
o addressed 0-day kernel warning.
o addressed cleanups and updates as per Bart's comments.
o added Acked-by tag from Nicholas to applicable patches.

Please apply this series to for-next branch to be included in 4.13 merge window.

Thanks,
Himanshu 

Joe Carnuccio (1):
  qla2xxx: Retain loop test for fwdump length exceeding buffer length

Quinn Tran (15):
  qla2xxx: Allow ABTS RX, RIDA on ATIOQ for ISP83XX/27XX
  qla2xxx: Replace usage of spin_lock with spin_lock_irqsave
  qla2xxx: Include Exchange offload/Extended Login into FW dump
  qla2xxx: Fix path recovery
  tcm_qla2xxx: Do not allow aborted cmd to advance.
  qla2xxx: Convert 32-bit LUN usage to 64-bit
  qla2xxx: Fix name server relogin
  qla2xxx: Cleanup debug message IDs
  qla2xxx: Turn on FW option for exchange check
  qla2xxx: Add ql2xiniexchg parameter
  qla2xxx: Remove redundant code
  qla2xxx: Remove redundant wait when target is stopped.
  qla2xxx: Accelerate SCSI BUSY status generation in target mode
  qla2xxx: Remove unused irq_cmd_count field.
  qla2xxx: Remove extra register read

Sawan Chandak (1):
  qla2xxx: Use flag PFLG_DISCONNECTED.

 drivers/scsi/qla2xxx/qla_attr.c|   2 +-
 drivers/scsi/qla2xxx/qla_bsg.c |   2 +-
 drivers/scsi/qla2xxx/qla_dbg.c |  53 -
 drivers/scsi/qla2xxx/qla_dbg.h |  12 +
 drivers/scsi/qla2xxx/qla_def.h |   9 +-
 drivers/scsi/qla2xxx/qla_dfs.c |   8 +-
 drivers/scsi/qla2xxx/qla_gbl.h |   3 +-
 drivers/scsi/qla2xxx/qla_gs.c  | 141 +++-
 drivers/scsi/qla2xxx/qla_init.c| 379 ++-
 drivers/scsi/qla2xxx/qla_inline.h  |  16 ++
 drivers/scsi/qla2xxx/qla_iocb.c|   4 +-
 drivers/scsi/qla2xxx/qla_isr.c |  35 ++-
 drivers/scsi/qla2xxx/qla_mbx.c |  73 +++---
 drivers/scsi/qla2xxx/qla_os.c  | 167 +-
 drivers/scsi/qla2xxx/qla_target.c  | 441 -
 drivers/scsi/qla2xxx/qla_target.h  |   7 +-
 drivers/scsi/qla2xxx/qla_tmpl.c|  16 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  15 +-
 18 files changed, 796 insertions(+), 587 deletions(-)

-- 
2.12.0



[PATCH v2 09/17] qla2xxx: Fix name server relogin

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Name server login is normally handle by FW. In some
rare case where one of the switches is being updated,
name server login could get affected. Trigger relogin
to name server when driver detects this condition.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h  |  2 ++
 drivers/scsi/qla2xxx/qla_gs.c   | 20 
 drivers/scsi/qla2xxx/qla_init.c | 38 +-
 drivers/scsi/qla2xxx/qla_isr.c  | 17 +
 4 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 4127f35b669c..51b262b236b4 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -252,6 +252,8 @@
 #define NPH_F_PORT 0x7fe   /*  FE */
 #define NPH_IP_BROADCAST   0x7ff   /*  FF */
 
+#define NPH_SNS_LID(ha)(IS_FWI2_CAPABLE(ha) ? NPH_SNS : 
SIMPLE_NAME_SERVER)
+
 #define MAX_CMDSZ  16  /* SCSI maximum CDB size. */
 #include "qla_fw.h"
 
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 5acebaf57796..ef8e8891d54f 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -124,6 +124,7 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t 
*ms_pkt,
int rval;
uint16_t comp_status;
struct qla_hw_data *ha = vha->hw;
+   bool lid_is_sns = false;
 
rval = QLA_FUNCTION_FAILED;
if (ms_pkt->entry_status != 0) {
@@ -155,6 +156,25 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, 
ms_iocb_entry_t *ms_pkt,
} else
rval = QLA_SUCCESS;
break;
+   case CS_PORT_LOGGED_OUT:
+   if (IS_FWI2_CAPABLE(ha)) {
+   if (le16_to_cpu(ms_pkt->loop_id.extended) ==
+   NPH_SNS)
+   lid_is_sns = true;
+   } else {
+   if (le16_to_cpu(ms_pkt->loop_id.extended) ==
+   SIMPLE_NAME_SERVER)
+   lid_is_sns = true;
+   }
+   if (lid_is_sns) {
+   ql_dbg(ql_dbg_async, vha, 0x502b,
+   "%s failed, Name server has logged out",
+   routine);
+   rval = QLA_NOT_LOGGED_IN;
+   set_bit(LOOP_RESYNC_NEEDED, >dpc_flags);
+   set_bit(LOCAL_LOOP_UPDATE, >dpc_flags);
+   }
+   break;
default:
ql_dbg(ql_dbg_disc, vha, 0x2033,
"%s failed, completion status (%x) on port_id: "
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 2d23885083b0..33a7d7a7e870 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1041,6 +1041,20 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, 
struct event_arg *ea)
 
switch (ea->event) {
case FCME_RELOGIN:
+   case FCME_RSCN:
+   case FCME_GIDPN_DONE:
+   case FCME_GPSC_DONE:
+   case FCME_GPNID_DONE:
+   if (test_bit(LOOP_RESYNC_NEEDED, >dpc_flags) ||
+   test_bit(LOOP_RESYNC_ACTIVE, >dpc_flags))
+   return;
+   break;
+   default:
+   break;
+   }
+
+   switch (ea->event) {
+   case FCME_RELOGIN:
if (test_bit(UNLOADING, >dpc_flags))
return;
 
@@ -4458,20 +4472,31 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
/* EMPTY */
ql_dbg(ql_dbg_disc, vha, 0x2045,
"Register FC-4 TYPE failed.\n");
+   if (test_bit(LOOP_RESYNC_NEEDED,
+   >dpc_flags))
+   break;
}
if (qla2x00_rff_id(vha)) {
/* EMPTY */
ql_dbg(ql_dbg_disc, vha, 0x2049,
"Register FC-4 Features failed.\n");
+   if (test_bit(LOOP_RESYNC_NEEDED,
+   >dpc_flags))
+   break;
}
if (qla2x00_rnn_id(vha)) {
/* EMPTY */
   

[PATCH v2 05/17] qla2xxx: Fix path recovery

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

If the port is moved/changed, current code would trigger
a deletion. If the port is already deleted, then do relogin.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_gs.c | 21 -
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 9bc9aa9e164a..5acebaf57796 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3118,16 +3118,27 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
 
if (fcport) {
/* cable moved. just plugged in */
-   ql_dbg(ql_dbg_disc, vha, 0x,
-  "%s %d %8phC post del sess\n",
-  __func__, __LINE__, fcport->port_name);
-
fcport->rscn_gen++;
fcport->d_id = ea->id;
fcport->scan_state = QLA_FCPORT_FOUND;
fcport->flags |= FCF_FABRIC_DEVICE;
 
-   qlt_schedule_sess_for_deletion_lock(fcport);
+   switch (fcport->disc_state) {
+   case DSC_DELETED:
+   ql_dbg(ql_dbg_disc, vha, 0x210d,
+   "%s %d %8phC login\n", __func__, __LINE__,
+   fcport->port_name);
+   qla24xx_fcport_handle_login(vha, fcport);
+   break;
+   case DSC_DELETE_PEND:
+   break;
+   default:
+   ql_dbg(ql_dbg_disc, vha, 0x2064,
+   "%s %d %8phC post del sess\n",
+   __func__, __LINE__, fcport->port_name);
+   qlt_schedule_sess_for_deletion_lock(fcport);
+   break;
+   }
} else {
/* create new fcport */
ql_dbg(ql_dbg_disc, vha, 0x,
-- 
2.12.0



[PATCH v2 03/17] qla2xxx: Retain loop test for fwdump length exceeding buffer length

2017-05-30 Thread Himanshu Madhani
From: Joe Carnuccio <joe.carnuc...@cavium.com>

Signed-off-by: Joe Carnuccio <joe.carnuc...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_init.c |  8 
 drivers/scsi/qla2xxx/qla_tmpl.c | 16 +---
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f6130e8b1ca1..e4876f4220e4 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -6356,8 +6356,8 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t 
*srisc_addr,
"-> template size %x bytes\n", dlen);
if (dlen > risc_size * sizeof(*dcode)) {
ql_log(ql_log_warn, vha, 0x0167,
-   "Failed fwdump template exceeds array by %x bytes\n",
-   (uint32_t)(dlen - risc_size * sizeof(*dcode)));
+   "Failed fwdump template exceeds array by %lx bytes\n",
+   (size_t)(dlen - risc_size * sizeof(*dcode)));
goto default_template;
}
ha->fw_dump_template_len = dlen;
@@ -6658,8 +6658,8 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t 
*srisc_addr)
"-> template size %x bytes\n", dlen);
if (dlen > risc_size * sizeof(*fwcode)) {
ql_log(ql_log_warn, vha, 0x0177,
-   "Failed fwdump template exceeds array by %x bytes\n",
-   (uint32_t)(dlen - risc_size * sizeof(*fwcode)));
+   "Failed fwdump template exceeds array by %lx bytes\n",
+   (size_t)(dlen - risc_size * sizeof(*fwcode)));
goto default_template;
}
ha->fw_dump_template_len = dlen;
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c
index c197972a3e2d..33142610882f 100644
--- a/drivers/scsi/qla2xxx/qla_tmpl.c
+++ b/drivers/scsi/qla2xxx/qla_tmpl.c
@@ -219,8 +219,6 @@ qla27xx_skip_entry(struct qla27xx_fwdt_entry *ent, void 
*buf)
 {
if (buf)
ent->hdr.driver_flags |= DRIVER_FLAG_SKIP_ENTRY;
-   ql_dbg(ql_dbg_misc + ql_dbg_verbose, NULL, 0xd011,
-   "Skipping entry %d\n", ent->hdr.entry_type);
 }
 
 static int
@@ -818,6 +816,8 @@ qla27xx_walk_template(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_misc, vha, 0xd01a,
"%s: entry count %lx\n", __func__, count);
while (count--) {
+   if (buf && *len >= vha->hw->fw_dump_len)
+   break;
if (qla27xx_find_entry(ent->hdr.entry_type)(vha, ent, buf, len))
break;
ent = qla27xx_next_entry(ent);
@@ -825,18 +825,20 @@ qla27xx_walk_template(struct scsi_qla_host *vha,
 
if (count)
ql_dbg(ql_dbg_misc, vha, 0xd018,
-   "%s: residual count (%lx)\n", __func__, count);
+   "%s: entry residual count (%lx)\n", __func__, count);
 
if (ent->hdr.entry_type != ENTRY_TYPE_TMP_END)
ql_dbg(ql_dbg_misc, vha, 0xd019,
-   "%s: missing end (%lx)\n", __func__, count);
+   "%s: missing end entry (%lx)\n", __func__, count);
 
-   ql_dbg(ql_dbg_misc, vha, 0xd01b,
-   "%s: len=%lx\n", __func__, *len);
+   if (buf && *len != vha->hw->fw_dump_len)
+   ql_dbg(ql_dbg_misc, vha, 0xd01b,
+   "%s: length=%#lx residual=%+ld\n",
+   __func__, *len, vha->hw->fw_dump_len - *len);
 
if (buf) {
ql_log(ql_log_warn, vha, 0xd015,
-   "Firmware dump saved to temp buffer (%ld/%p)\n",
+   "Firmware dump saved to temp buffer (%lu/%p)\n",
vha->host_no, vha->hw->fw_dump);
qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
}
-- 
2.12.0



[PATCH v2 07/17] qla2xxx: Use flag PFLG_DISCONNECTED.

2017-05-30 Thread Himanshu Madhani
From: Sawan Chandak <sawan.chan...@cavium.com>

There is already flag defined PFLG_DISCONNECTED, which is set
for PCI or register disconnect error condition. There is no need to have
flag PCI_ERR, which has same purpose. Remove use of PCI_ERR flag and use
PFLG_DISCONNECTED flag during error condition.

Signed-off-by: Sawan Chandak <sawan.chan...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h | 1 -
 drivers/scsi/qla2xxx/qla_mbx.c | 5 ++---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index eddbc1218a39..4127f35b669c 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -4017,7 +4017,6 @@ typedef struct scsi_qla_host {
 #define PFLG_DISCONNECTED  0   /* PCI device removed */
 #define PFLG_DRIVER_REMOVING   1   /* PCI driver .remove */
 #define PFLG_DRIVER_PROBING2   /* PCI driver .probe */
-#define PCI_ERR30
 
uint32_tdevice_flags;
 #define SWITCH_FOUND   BIT_0
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index cba1fc5e8be9..fffa1f7cd8d2 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -124,7 +124,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t 
*mcp)
}
 
/* if PCI error, then avoid mbx processing.*/
-   if (test_bit(PCI_ERR, _vha->dpc_flags)) {
+   if (test_bit(PFLG_DISCONNECTED, _vha->dpc_flags) &&
+   test_bit(UNLOADING, _vha->dpc_flags)) {
ql_log(ql_log_warn, vha, 0x1191,
"PCI error, exiting.\n");
return QLA_FUNCTION_TIMEOUT;
@@ -384,8 +385,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t 
*mcp)
 * then only PCI ERR flag would be set.
 * we will do premature exit for above case.
 */
-   if (test_bit(UNLOADING, _vha->dpc_flags))
-   set_bit(PCI_ERR, _vha->dpc_flags);
ha->flags.mbox_busy = 0;
rval = QLA_FUNCTION_TIMEOUT;
goto premature_exit;
-- 
2.12.0



[PATCH v2 11/17] qla2xxx: Turn on FW option for exchange check

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Tell FW to track exchange/cmd state to prevent driver
from using stale exchange or exchange that is not meant
for this command.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_init.c   | 18 ++
 drivers/scsi/qla2xxx/qla_target.c | 26 +++---
 drivers/scsi/qla2xxx/qla_target.h |  2 +-
 3 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 9f14e6752b83..c422c14dfb07 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -2976,6 +2976,18 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
ha->fw_options[2] &= ~BIT_11;
}
 
+   if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+   /*
+* Tell FW to track each exchange to prevent
+* driver from using stale exchange.
+*/
+   if (qla_tgt_mode_enabled(vha) ||
+   qla_dual_mode_enabled(vha))
+   ha->fw_options[2] |= BIT_4;
+   else
+   ha->fw_options[2] &= ~BIT_4;
+   }
+
ql_dbg(ql_dbg_init, vha, 0x00e8,
"%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
__func__, ha->fw_options[1], ha->fw_options[2],
@@ -7368,6 +7380,12 @@ qla81xx_update_fw_options(scsi_qla_host_t *vha)
ha->fw_options[2] &= ~BIT_11;
}
 
+   if (qla_tgt_mode_enabled(vha) ||
+   qla_dual_mode_enabled(vha))
+   ha->fw_options[2] |= BIT_4;
+   else
+   ha->fw_options[2] &= ~BIT_4;
+
if (ql2xetsenable) {
/* Enable ETS Burst. */
memset(ha->fw_options, 0, sizeof(ha->fw_options));
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 4ad09584d4a8..3cdffdd90279 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2016,8 +2016,9 @@ static void qlt_24xx_send_task_mgmt_ctio(struct 
scsi_qla_host *ha,
ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
ctio->exchange_addr = atio->u.isp24.exchange_addr;
-   ctio->u.status1.flags = (atio->u.isp24.attr << 9) |
-   cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS);
+   temp = (atio->u.isp24.attr << 9)|
+   CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS;
+   ctio->u.status1.flags = cpu_to_le16(temp);
temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
ctio->u.status1.ox_id = cpu_to_le16(temp);
ctio->u.status1.scsi_status =
@@ -2070,8 +2071,9 @@ void qlt_send_resp_ctio(scsi_qla_host_t *vha, struct 
qla_tgt_cmd *cmd,
ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
ctio->exchange_addr = atio->u.isp24.exchange_addr;
-   ctio->u.status1.flags = (atio->u.isp24.attr << 9) |
-   cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS);
+   temp = (atio->u.isp24.attr << 9) |
+   CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS;
+   ctio->u.status1.flags = cpu_to_le16(temp);
temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
ctio->u.status1.ox_id = cpu_to_le16(temp);
ctio->u.status1.scsi_status =
@@ -2359,7 +2361,8 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm 
*prm,
pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
pkt->exchange_addr = atio->u.isp24.exchange_addr;
-   pkt->u.status0.flags |= (atio->u.isp24.attr << 9);
+   temp = atio->u.isp24.attr << 9;
+   pkt->u.status0.flags |= cpu_to_le16(temp);
temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
pkt->u.status0.ox_id = cpu_to_le16(temp);
pkt->u.status0.relative_offset = cpu_to_le32(prm->cmd->offset);
@@ -3484,9 +3487,9 @@ static int __qlt_send_term_exchange(struct scsi_qla_host 
*vha,
ctio24->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
ctio24->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
ctio24->exchange_addr = atio->u.isp24.exchange_addr;
-   ctio24->u.status1.flags = (atio->u.isp24.attr << 9) |
-   cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 |
-   CTIO7_FLAGS_TERMINATE);
+   temp = (atio->u.isp24.attr << 9) | CTIO7_FLAGS_STATUS_MODE_1 |
+   CTIO7_FLAGS_TERMINATE;
+   ctio24-

[PATCH v2 15/17] qla2xxx: Accelerate SCSI BUSY status generation in target mode

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Accelerate generation of SCSI busy to let initiators slow
down when target is running low in resources.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_init.c | 13 +++--
 drivers/scsi/qla2xxx/qla_mbx.c  |  2 ++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 0ee9159457e4..3a51ddab36b8 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7381,10 +7381,19 @@ qla81xx_update_fw_options(scsi_qla_host_t *vha)
}
 
if (qla_tgt_mode_enabled(vha) ||
-   qla_dual_mode_enabled(vha))
+   qla_dual_mode_enabled(vha)) {
+   /* FW auto send SCSI status during */
+   ha->fw_options[1] |= BIT_8;
+   ha->fw_options[10] |= (u16)SAM_STAT_BUSY << 8;
+
+   /* FW perform Exchang validation */
ha->fw_options[2] |= BIT_4;
-   else
+   } else {
+   ha->fw_options[1]  &= ~BIT_8;
+   ha->fw_options[10] &= 0x00ff;
+
ha->fw_options[2] &= ~BIT_4;
+   }
 
if (ql2xetsenable) {
/* Enable ETS Burst. */
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index bebac42d9e9e..f02a2baffb5b 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -1048,6 +1048,8 @@ qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t 
*fwopts)
mcp->in_mb = MBX_0;
if (IS_FWI2_CAPABLE(vha->hw)) {
mcp->in_mb |= MBX_1;
+   mcp->mb[10] = fwopts[10];
+   mcp->out_mb |= MBX_10;
} else {
mcp->mb[10] = fwopts[10];
mcp->mb[11] = fwopts[11];
-- 
2.12.0



[PATCH v2 17/17] qla2xxx: Remove extra register read

2017-05-30 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Remove extra register read in each interrupt processing
to improve performance.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_iocb.c   |  4 +++-
 drivers/scsi/qla2xxx/qla_target.c | 11 ++-
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index ea027f6a7fd4..8404f17f3c6c 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -464,7 +464,9 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct 
req_que *req)
req->ring_ptr++;
 
/* Set chip new ring index. */
-   if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+   if (ha->mqenable || IS_QLA27XX(ha)) {
+   WRT_REG_DWORD(req->req_q_in, req->ring_index);
+   } else if (IS_QLA83XX(ha)) {
WRT_REG_DWORD(req->req_q_in, req->ring_index);
RD_REG_DWORD_RELAXED(>iobase->isp24.hccr);
} else if (IS_QLAFX00(ha)) {
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index c96dcd31b47b..78ac031cc551 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2235,11 +2235,10 @@ static void qlt_unmap_sg(struct scsi_qla_host *vha, 
struct qla_tgt_cmd *cmd)
 static int qlt_check_reserve_free_req(struct scsi_qla_host *vha,
uint32_t req_cnt)
 {
-   uint32_t cnt, cnt_in;
+   uint32_t cnt;
 
if (vha->req->cnt < (req_cnt + 2)) {
cnt = (uint16_t)RD_REG_DWORD(vha->req->req_q_out);
-   cnt_in = (uint16_t)RD_REG_DWORD(vha->req->req_q_in);
 
if  (vha->req->ring_index < cnt)
vha->req->cnt = cnt - vha->req->ring_index;
@@ -2247,14 +2246,8 @@ static int qlt_check_reserve_free_req(struct 
scsi_qla_host *vha,
vha->req->cnt = vha->req->length -
(vha->req->ring_index - cnt);
 
-   if (unlikely(vha->req->cnt < (req_cnt + 2))) {
-   ql_dbg(ql_dbg_io, vha, 0x305a,
-   "qla_target(%d): There is no room in the request 
ring: vha->req->ring_index=%d, vha->req->cnt=%d, req_cnt=%d Req-out=%d 
Req-in=%d Req-Length=%d\n",
-   vha->vp_idx, vha->req->ring_index,
-   vha->req->cnt, req_cnt, cnt, cnt_in,
-   vha->req->length);
+   if (unlikely(vha->req->cnt < (req_cnt + 2)))
return -EAGAIN;
-   }
}
 
vha->req->cnt -= req_cnt;
-- 
2.12.0



[PATCH 00/25] qla2xxx: Bug fixes and cleanups

2017-05-19 Thread Himanshu Madhani
Hi Martin, 

This series contains bug fixes and cleanups for the driver that we posted in 
4.11. 

Patches 1-10 needs to go in 4.12.0-rcX. Rest of the patches can be queued to 
for-next branch.
Please let me know if the series is okay to be included in 4.12.0-rcX. if we 
are too late
for big series in rcX then would you please queue patches 10-25 for 
4.13/scsi-queue.

Thanks,
Himnanshu

Himanshu Madhani (1):
  qla2xxx: Fix Target mode configuration for ISP25XX

Joe Carnuccio (6):
  qla2xxx: Reduce excessive debug print during 27xx fwdump.
  qla2xxx: Allow fwdump template T262 to specify same start/end.
  qla2xxx: Set bit 15 for DIAG_ECHO_TEST MBC.
  qla2xxx: Fix mailbox pointer error in classic fwdump.
  qla2xxx: Prevent null pointer dereference of ctx.
  qla2xxx: Simplify debug printing of portid.

Quinn Tran (16):
  qla2xxx: Remove redundant fc_host_port_name call
  qla2xxx: Allow ABTS RX, RIDA on ATIOQ for ISP83XX/27XX
  qla2xxx: Replace usage of spin_lock with spin_lock_irqsave
  qla2xxx: Include Exchange offload/Extended Login into FW dump
  qla2xxx: Fix path recovery
  tcm_qla2xxx: Do not allow aborted cmd to advance.
  qla2xxx: Convert 32-bit LUN usage to 64-bit
  qla2xxx: Fix name server relogin
  qla2xxx: Cleanup debug messager IDs.
  qla2xxx: Turn on FW option for exchange check
  qla2xxx: Replace ql2xexchoffld & ql_dm_tgt_ex_pct parameter
  qla2xxx: Remove redundant code
  qla2xxx: Remove redundant wait when target is stopped.
  qla2xxx: Enable auto SCSI BUSY status for target mode
  qla2xxx: Remove unused irq_cmd_count field.
  qla2xxx: Remove extra register read

Sawan Chandak (2):
  qla2xxx: Fix number of queue pairs creation for MQ
  qla2xxx: Use flag PFLG_DISCONNECTED.

 drivers/scsi/qla2xxx/qla_attr.c|  28 ++-
 drivers/scsi/qla2xxx/qla_bsg.c |  28 ++-
 drivers/scsi/qla2xxx/qla_dbg.c |  58 -
 drivers/scsi/qla2xxx/qla_dbg.h |  12 +
 drivers/scsi/qla2xxx/qla_def.h |  10 +-
 drivers/scsi/qla2xxx/qla_dfs.c |  12 +-
 drivers/scsi/qla2xxx/qla_gbl.h |   5 +-
 drivers/scsi/qla2xxx/qla_gs.c  | 225 +-
 drivers/scsi/qla2xxx/qla_init.c| 460 -
 drivers/scsi/qla2xxx/qla_inline.h  |  50 ++--
 drivers/scsi/qla2xxx/qla_iocb.c|  22 +-
 drivers/scsi/qla2xxx/qla_isr.c |  95 
 drivers/scsi/qla2xxx/qla_mbx.c |  97 
 drivers/scsi/qla2xxx/qla_os.c  | 203 ++--
 drivers/scsi/qla2xxx/qla_target.c  | 453 +++-
 drivers/scsi/qla2xxx/qla_target.h  |   7 +-
 drivers/scsi/qla2xxx/qla_tmpl.c|  18 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  16 +-
 18 files changed, 963 insertions(+), 836 deletions(-)

-- 
2.12.0



[PATCH 02/25] qla2xxx: Remove redundant fc_host_port_name call

2017-05-19 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Remove redundant fc_host_port_name calls to prevent
early access of scsi_host->shost_data buffer. This
prevent null pointer access.

Cc: <sta...@vger.kernel.org>
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_mbx.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index a113ab3592a7..12fea77e31c6 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -3676,15 +3676,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
qlt_update_host_map(vha, id);
}
 
-   fc_host_port_name(vha->host) =
-   wwn_to_u64(vha->port_name);
-
-   if (qla_ini_mode_enabled(vha))
-   ql_dbg(ql_dbg_mbx, vha, 0x1018,
-   "FA-WWN portname %016llx (%x)\n",
-   fc_host_port_name(vha->host),
-   rptid_entry->vp_status);
-
set_bit(REGISTER_FC4_NEEDED, >dpc_flags);
set_bit(REGISTER_FDMI_NEEDED, >dpc_flags);
} else {
-- 
2.12.0



[PATCH 11/25] qla2xxx: Include Exchange offload/Extended Login into FW dump

2017-05-19 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Add missing memory dump of Exchange Offload and Extended
login into FW dump.

Cc: <sta...@vger.kernel.org>
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c  | 52 +
 drivers/scsi/qla2xxx/qla_dbg.h  | 12 ++
 drivers/scsi/qla2xxx/qla_init.c |  7 ++
 drivers/scsi/qla2xxx/qla_os.c   |  3 ---
 4 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 88748a6ab73f..ba8cd7c4e3a6 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -498,6 +498,53 @@ qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, 
uint32_t **last_chain)
 }
 
 static inline void *
+qla25xx_copy_exlogin(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
+{
+   struct qla2xxx_offld_chain *c = ptr;
+
+   if (!ha->exlogin_buf)
+   return ptr;
+
+   *last_chain = >type;
+
+   c->type = htonl(DUMP_CHAIN_EXLOGIN);
+   c->chain_size = htonl(sizeof(struct qla2xxx_offld_chain) +
+   ha->exlogin_size);
+   c->size = htonl(ha->exlogin_size);
+   c->addr_l = htonl(LSD(ha->exlogin_buf_dma));
+   c->addr_h = htonl(MSD(ha->exlogin_buf_dma));
+
+   ptr += sizeof(struct qla2xxx_offld_chain);
+   memcpy(ptr, ha->exlogin_buf, ha->exlogin_size);
+
+   return (char *)ptr + ntohl(c->size);
+}
+
+static inline void *
+qla81xx_copy_exchoffld(struct qla_hw_data *ha, void *ptr, uint32_t 
**last_chain)
+{
+   struct qla2xxx_offld_chain *c = ptr;
+
+   if (!ha->exchoffld_buf)
+   return ptr;
+
+   *last_chain = >type;
+
+   c->type = htonl(DUMP_CHAIN_EXCHG);
+   c->chain_size = htonl(sizeof(struct qla2xxx_offld_chain) +
+   ha->exchoffld_size);
+   c->size = htonl(ha->exchoffld_size);
+   c->addr_l = htonl(LSD(ha->exchoffld_buf_dma));
+   c->addr_h = htonl(MSD(ha->exchoffld_buf_dma));
+
+   ptr += sizeof(struct qla2xxx_offld_chain);
+   memcpy(ptr, ha->exchoffld_buf, ha->exchoffld_size);
+
+   return (char *)ptr + ntohl(c->size);
+}
+
+
+static inline void *
 qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr,
uint32_t **last_chain)
 {
@@ -1606,6 +1653,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, _chain);
nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, _chain);
nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, _chain);
+   nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, _chain);
if (last_chain) {
ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
*last_chain |= htonl(DUMP_CHAIN_LAST);
@@ -1932,6 +1980,8 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, _chain);
nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, _chain);
nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, _chain);
+   nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, _chain);
+   nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, _chain);
if (last_chain) {
ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
*last_chain |= htonl(DUMP_CHAIN_LAST);
@@ -2443,6 +2493,8 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, _chain);
nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, _chain);
nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, _chain);
+   nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, _chain);
+   nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, _chain);
if (last_chain) {
ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT);
*last_chain |= htonl(DUMP_CHAIN_LAST);
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index c6bffe929fe7..c4b1bb76cf48 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -232,6 +232,16 @@ struct qla2xxx_fce_chain {
uint32_t eregs[8];
 };
 
+/* used by exchange off load and extended login offload */
+struct qla2xxx_offld_chain {
+   uint32_t type;
+   uint32_t chain_size;
+
+   uint32_t size;
+   uint32_t addr_l;
+   uint32_t addr_h;
+};
+
 struct qla2xxx_mq_chain {
uint32_t type;
uint32_t chain_size;
@@ -258,6 +268,8 @@ struct qla2xxx_mqueue_chain {
 #define DUMP_CHAIN_FCE 0x7AF0
 #define DUMP_CHAIN_MQ  0x7AF1
 #define DUMP_CHAIN_QUEUE   0x7AF2
+#define DUMP_CHAIN_EXLOGIN 0x7AF3
+#define DUMP_CHAIN_EXCHG   0x7AF4
 #define DUMP_CHAIN_LAST0x8000
 
 struct qla2xxx_fw

[PATCH 17/25] qla2xxx: Cleanup debug messager IDs.

2017-05-19 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Assign unique id to all traces and logs for debug purpose.
Minor cleanup of indentation and spacing around traces and logs.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_attr.c   |  26 ++--
 drivers/scsi/qla2xxx/qla_bsg.c|   4 +-
 drivers/scsi/qla2xxx/qla_dbg.c|   2 +-
 drivers/scsi/qla2xxx/qla_dfs.c|  12 +-
 drivers/scsi/qla2xxx/qla_gs.c | 141 +
 drivers/scsi/qla2xxx/qla_init.c   | 312 +++---
 drivers/scsi/qla2xxx/qla_isr.c|  20 +--
 drivers/scsi/qla2xxx/qla_mbx.c|  56 +++
 drivers/scsi/qla2xxx/qla_os.c |  34 ++---
 drivers/scsi/qla2xxx/qla_target.c | 227 +--
 10 files changed, 407 insertions(+), 427 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 7c8d6c54ab70..a7ac81b473a4 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -44,7 +44,7 @@ qla2x00_sysfs_read_fw_dump(struct file *filp, struct kobject 
*kobj,
MCTP_DUMP_SIZE);
else if (ha->fw_dump_reading)
return memory_read_from_buffer(buf, count, , ha->fw_dump,
-   ha->fw_dump_len);
+   ha->fw_dump_len);
else
return 0;
 }
@@ -162,7 +162,7 @@ qla2x00_sysfs_read_nvram(struct file *filp, struct kobject 
*kobj,
ha->isp_ops->read_optrom(vha, ha->nvram, ha->flt_region_nvram 
<< 2,
ha->nvram_size);
return memory_read_from_buffer(buf, count, , ha->nvram,
-   ha->nvram_size);
+   ha->nvram_size);
 }
 
 static ssize_t
@@ -406,8 +406,8 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct 
kobject *kobj,
start == (ha->flt_region_fw * 4))
valid = 1;
else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)
-   || IS_CNA_CAPABLE(ha) || IS_QLA2031(ha)
-   || IS_QLA27XX(ha))
+   || IS_CNA_CAPABLE(ha) || IS_QLA2031(ha)
+   || IS_QLA27XX(ha))
valid = 1;
if (!valid) {
ql_log(ql_log_warn, vha, 0x7065,
@@ -769,7 +769,7 @@ qla2x00_issue_logo(struct file *filp, struct kobject *kobj,
did.b.area = (type & 0xff00) >> 8;
did.b.al_pa = (type & 0x00ff);
 
-   ql_log(ql_log_info, vha, 0x70e3, "portid=%02x%02x%02x done\n",
+   ql_log(ql_log_info, vha, 0xd04d, "portid=%02x%02x%02x done\n",
did.b.domain, did.b.area, did.b.al_pa);
 
ql_log(ql_log_info, vha, 0x70e4, "%s: %d\n", __func__, type);
@@ -1295,7 +1295,7 @@ qla24xx_84xx_fw_version_show(struct device *dev,
 
if ((rval == QLA_SUCCESS) && (status[0] == 0))
return scnprintf(buf, PAGE_SIZE, "%u\n",
-   (uint32_t)ha->cs84xx->op_fw_version);
+   (uint32_t)ha->cs84xx->op_fw_version);
 
return scnprintf(buf, PAGE_SIZE, "\n");
 }
@@ -1608,7 +1608,7 @@ static void
 qla2x00_get_host_speed(struct Scsi_Host *shost)
 {
struct qla_hw_data *ha = ((struct scsi_qla_host *)
-   (shost_priv(shost)))->hw;
+   (shost_priv(shost)))->hw;
u32 speed = FC_PORTSPEED_UNKNOWN;
 
if (IS_QLAFX00(ha)) {
@@ -1853,7 +1853,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
!ha->dpc_active) {
/* Must be in a 'READY' state for statistics retrieval. */
rval = qla2x00_get_link_status(base_vha, base_vha->loop_id,
-   stats, stats_dma);
+   stats, stats_dma);
}
 
if (rval != QLA_SUCCESS)
@@ -2063,8 +2063,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool 
disable)
vha->flags.difdix_supported = 0;
}
 
-   if (scsi_add_host_with_dma(vha->host, _vport->dev,
-  >pdev->dev)) {
+   if (scsi_add_host_with_dma(vha->host, _vport->dev, >pdev->dev)) {
ql_dbg(ql_dbg_user, vha, 0x7083,
"scsi_add_host failure for VP[%d].\n", vha->vp_idx);
goto vport_create_failed_2;
@@ -2087,9 +2086,10 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool 
disable)
 
/* Create a request queue in QoS mode for the vport */
for (cnt = 0; cnt < ha->nvram_npiv_size; cnt++) {
-   if (memcmp(ha->npiv_info[cnt].port_name, vha->port_name, 8) == 0
-   && memcmp(ha->npiv_info[cnt].node_na

[PATCH 14/25] qla2xxx: Use flag PFLG_DISCONNECTED.

2017-05-19 Thread Himanshu Madhani
From: Sawan Chandak <sawan.chan...@cavium.com>

There is already flag defined PFLG_DISCONNECTED, which is set
for PCI or register disconnect error condition. There is no need to have
flag PCI_ERR, which has same purpose. Remove use of PCI_ERR flag and use
PFLG_DISCONNECTED flag during error condition.

Cc: <sta...@vger.kernel.org>
Fixes: 783e0dc4f66a ("qla2xxx: Check for device state before unloading the 
driver.")
Signed-off-by: Sawan Chandak <sawan.chan...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h | 1 -
 drivers/scsi/qla2xxx/qla_mbx.c | 5 ++---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index eddbc1218a39..4127f35b669c 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -4017,7 +4017,6 @@ typedef struct scsi_qla_host {
 #define PFLG_DISCONNECTED  0   /* PCI device removed */
 #define PFLG_DRIVER_REMOVING   1   /* PCI driver .remove */
 #define PFLG_DRIVER_PROBING2   /* PCI driver .probe */
-#define PCI_ERR30
 
uint32_tdevice_flags;
 #define SWITCH_FOUND   BIT_0
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index cba1fc5e8be9..fffa1f7cd8d2 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -124,7 +124,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t 
*mcp)
}
 
/* if PCI error, then avoid mbx processing.*/
-   if (test_bit(PCI_ERR, _vha->dpc_flags)) {
+   if (test_bit(PFLG_DISCONNECTED, _vha->dpc_flags) &&
+   test_bit(UNLOADING, _vha->dpc_flags)) {
ql_log(ql_log_warn, vha, 0x1191,
"PCI error, exiting.\n");
return QLA_FUNCTION_TIMEOUT;
@@ -384,8 +385,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t 
*mcp)
 * then only PCI ERR flag would be set.
 * we will do premature exit for above case.
 */
-   if (test_bit(UNLOADING, _vha->dpc_flags))
-   set_bit(PCI_ERR, _vha->dpc_flags);
ha->flags.mbox_busy = 0;
rval = QLA_FUNCTION_TIMEOUT;
goto premature_exit;
-- 
2.12.0



[PATCH 04/25] qla2xxx: Replace usage of spin_lock with spin_lock_irqsave

2017-05-19 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

qla2xxx driver lives in interrupt context. Remove
spin_lock usage to prevent leaving CPU in a strange
state.

Cc: <sta...@vger.kernel.org>
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 26 ++
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 0e03ca2ab3e5..4c64f8e3f9b6 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1762,13 +1762,13 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, 
uint32_t tag)
 {
struct qla_tgt_sess_op *op;
struct qla_tgt_cmd *cmd;
+   unsigned long flags;
 
-   spin_lock(>cmd_list_lock);
-
+   spin_lock_irqsave(>cmd_list_lock, flags);
list_for_each_entry(op, >qla_sess_op_cmd_list, cmd_list) {
if (tag == op->atio.u.isp24.exchange_addr) {
op->aborted = true;
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
return 1;
}
}
@@ -1776,7 +1776,7 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, 
uint32_t tag)
list_for_each_entry(op, >unknown_atio_list, cmd_list) {
if (tag == op->atio.u.isp24.exchange_addr) {
op->aborted = true;
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
return 1;
}
}
@@ -1784,12 +1784,12 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, 
uint32_t tag)
list_for_each_entry(cmd, >qla_cmd_list, cmd_list) {
if (tag == cmd->atio.u.isp24.exchange_addr) {
cmd->aborted = 1;
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
return 1;
}
}
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
 
-   spin_unlock(>cmd_list_lock);
return 0;
 }
 
@@ -1804,9 +1804,10 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
struct qla_tgt_sess_op *op;
struct qla_tgt_cmd *cmd;
uint32_t key;
+   unsigned long flags;
 
key = sid_to_key(s_id);
-   spin_lock(>cmd_list_lock);
+   spin_lock_irqsave(>cmd_list_lock, flags);
list_for_each_entry(op, >qla_sess_op_cmd_list, cmd_list) {
uint32_t op_key;
uint32_t op_lun;
@@ -1839,7 +1840,7 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
if (cmd_key == key && cmd_lun == lun)
cmd->aborted = 1;
}
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
 }
 
 /* ha->hardware_lock supposed to be held on entry */
@@ -4214,9 +4215,9 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host 
*vha,
memcpy(>atio, atio, sizeof(*atio));
op->vha = vha;
 
-   spin_lock(>cmd_list_lock);
+   spin_lock_irqsave(>cmd_list_lock, flags);
list_add_tail(>cmd_list, >qla_sess_op_cmd_list);
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
 
INIT_WORK(>work, qlt_create_sess_from_atio);
queue_work(qla_tgt_wq, >work);
@@ -4527,12 +4528,13 @@ static int abort_cmds_for_s_id(struct scsi_qla_host 
*vha, port_id_t *s_id)
struct qla_tgt_cmd *cmd;
uint32_t key;
int count = 0;
+   unsigned long flags;
 
key = (((u32)s_id->b.domain << 16) |
   ((u32)s_id->b.area   <<  8) |
   ((u32)s_id->b.al_pa));
 
-   spin_lock(>cmd_list_lock);
+   spin_lock_irqsave(>cmd_list_lock, flags);
list_for_each_entry(op, >qla_sess_op_cmd_list, cmd_list) {
uint32_t op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id);
 
@@ -4557,7 +4559,7 @@ static int abort_cmds_for_s_id(struct scsi_qla_host *vha, 
port_id_t *s_id)
count++;
}
}
-   spin_unlock(>cmd_list_lock);
+   spin_unlock_irqrestore(>cmd_list_lock, flags);
 
return count;
 }
-- 
2.12.0



[PATCH 07/25] qla2xxx: Allow fwdump template T262 to specify same start/end.

2017-05-19 Thread Himanshu Madhani
From: Joe Carnuccio <joe.carnuc...@cavium.com>

Cc: <sta...@vger.kernel.org>
Signed-off-by: Joe Carnuccio <joe.carnuc...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_tmpl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c
index 2f2633a8c4ad..33142610882f 100644
--- a/drivers/scsi/qla2xxx/qla_tmpl.c
+++ b/drivers/scsi/qla2xxx/qla_tmpl.c
@@ -369,7 +369,7 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
goto done;
}
 
-   if (end <= start || start == 0 || end == 0) {
+   if (end < start || start == 0 || end == 0) {
ql_dbg(ql_dbg_misc, vha, 0xd023,
"%s: unusable range (start=%x end=%x)\n", __func__,
ent->t262.end_addr, ent->t262.start_addr);
-- 
2.12.0



[PATCH 03/25] qla2xxx: Allow ABTS RX, RIDA on ATIOQ for ISP83XX/27XX

2017-05-19 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Allow ABTS RX, RIDA to be moved to ATIO Queue only for
ISP83XX and ISP27XX.

Cc: <sta...@vger.kernel.org>
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_init.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 034743309ada..a017a1af1707 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -2946,7 +2946,8 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
}
 
/* Move PUREX, ABTS RX & RIDA to ATIOQ */
-   if (ql2xmvasynctoatio) {
+   if (ql2xmvasynctoatio &&
+   (IS_QLA83XX(ha) || IS_QLA27XX(ha))) {
if (qla_tgt_mode_enabled(vha) ||
qla_dual_mode_enabled(vha))
ha->fw_options[2] |= BIT_11;
@@ -2958,7 +2959,9 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
"%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
__func__, ha->fw_options[1], ha->fw_options[2],
ha->fw_options[3], vha->host->active_mode);
-   qla2x00_set_fw_options(vha, ha->fw_options);
+
+   if (ha->fw_options[1] || ha->fw_options[2] || ha->fw_options[3])
+   qla2x00_set_fw_options(vha, ha->fw_options);
 
/* Update Serial Link options. */
if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0)
-- 
2.12.0



[PATCH 10/25] qla2xxx: Prevent null pointer dereference of ctx.

2017-05-19 Thread Himanshu Madhani
From: Joe Carnuccio <joe.carnuc...@cavium.com>

Fixes following signature in the stack trace:

BUG: unable to handle kernel NULL pointer dereference at 0374
IP: [] qla2x00_sp_free_dma+0xeb/0x2a0 [qla2xxx]

Cc: <sta...@vger.kernel.org>
Signed-off-by: Joe Carnuccio <joe.carnuc...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_inline.h | 26 +++---
 drivers/scsi/qla2xxx/qla_os.c | 30 +++---
 drivers/scsi/qla2xxx/qla_target.c |  8 +---
 3 files changed, 31 insertions(+), 33 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index 66df6cec59da..c61a6a871c8e 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -129,28 +129,16 @@ qla2x00_clear_loop_id(fc_port_t *fcport) {
 }
 
 static inline void
-qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp,
-   struct qla_tgt_cmd *tc)
+qla2x00_clean_dsd_pool(struct qla_hw_data *ha, struct crc_context *ctx)
 {
-   struct dsd_dma *dsd_ptr, *tdsd_ptr;
-   struct crc_context *ctx;
-
-   if (sp)
-   ctx = (struct crc_context *)GET_CMD_CTX_SP(sp);
-   else if (tc)
-   ctx = (struct crc_context *)tc->ctx;
-   else {
-   BUG();
-   return;
-   }
+   struct dsd_dma *dsd, *tdsd;
 
/* clean up allocated prev pool */
-   list_for_each_entry_safe(dsd_ptr, tdsd_ptr,
-   >dsd_list, list) {
-   dma_pool_free(ha->dl_dma_pool, dsd_ptr->dsd_addr,
-   dsd_ptr->dsd_list_dma);
-   list_del(_ptr->list);
-   kfree(dsd_ptr);
+   list_for_each_entry_safe(dsd, tdsd, >dsd_list, list) {
+   dma_pool_free(ha->dl_dma_pool, dsd->dsd_addr,
+   dsd->dsd_list_dma);
+   list_del(>list);
+   kfree(dsd);
}
INIT_LIST_HEAD(>dsd_list);
 }
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 1c7957903283..c8282a1ab6dc 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -630,29 +630,34 @@ qla2x00_sp_free_dma(void *ptr)
sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
}
 
+   if (!ctx)
+   goto end;
+
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
/* List assured to be having elements */
-   qla2x00_clean_dsd_pool(ha, sp, NULL);
+   qla2x00_clean_dsd_pool(ha, ctx);
sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
}
 
if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
-   dma_pool_free(ha->dl_dma_pool, ctx,
-   ((struct crc_context *)ctx)->crc_ctx_dma);
+   struct crc_context *ctx0 = ctx;
+
+   dma_pool_free(ha->dl_dma_pool, ctx0, ctx0->crc_ctx_dma);
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
}
 
if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
-   struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx;
+   struct ct6_dsd *ctx1 = ctx;
 
dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
-   ctx1->fcp_cmnd_dma);
+   ctx1->fcp_cmnd_dma);
list_splice(>dsd_list, >gbl_dsd_list);
ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt;
ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
mempool_free(ctx1, ha->ctx_mempool);
}
 
+end:
CMD_SP(cmd) = NULL;
qla2x00_rel_sp(sp);
 }
@@ -699,21 +704,24 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
}
 
+   if (!ctx)
+   goto end;
+
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
/* List assured to be having elements */
-   qla2x00_clean_dsd_pool(ha, sp, NULL);
+   qla2x00_clean_dsd_pool(ha, ctx);
sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
}
 
if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
-   dma_pool_free(ha->dl_dma_pool, ctx,
-   ((struct crc_context *)ctx)->crc_ctx_dma);
+   struct crc_context *ctx0 = ctx;
+
+   dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma);
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
}
 
if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
-   struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx;
-
+   struct ct6_dsd *ctx1 = ctx;
dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
ctx1->fcp_cmnd_dma);
list_splice(>dsd_list, >gbl_dsd_list);
@@ -721,7 +729,7 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
ha-&

[PATCH 06/25] qla2xxx: Reduce excessive debug print during 27xx fwdump.

2017-05-19 Thread Himanshu Madhani
From: Joe Carnuccio <joe.carnuc...@cavium.com>

Retain loop test for fwdump length exceeding buffer length.

Cc: <sta...@vger.kernel.org>
Signed-off-by: Joe Carnuccio <joe.carnuc...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_init.c |  8 
 drivers/scsi/qla2xxx/qla_tmpl.c | 16 +---
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f6130e8b1ca1..eaaf73fd23d9 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -6356,8 +6356,8 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t 
*srisc_addr,
"-> template size %x bytes\n", dlen);
if (dlen > risc_size * sizeof(*dcode)) {
ql_log(ql_log_warn, vha, 0x0167,
-   "Failed fwdump template exceeds array by %x bytes\n",
-   (uint32_t)(dlen - risc_size * sizeof(*dcode)));
+   "Failed fwdump template exceeds array by %lx bytes\n",
+   dlen - risc_size * sizeof(*dcode));
goto default_template;
}
ha->fw_dump_template_len = dlen;
@@ -6658,8 +6658,8 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t 
*srisc_addr)
"-> template size %x bytes\n", dlen);
if (dlen > risc_size * sizeof(*fwcode)) {
ql_log(ql_log_warn, vha, 0x0177,
-   "Failed fwdump template exceeds array by %x bytes\n",
-   (uint32_t)(dlen - risc_size * sizeof(*fwcode)));
+   "Failed fwdump template exceeds array by %lx bytes\n",
+   dlen - risc_size * sizeof(*fwcode));
goto default_template;
}
ha->fw_dump_template_len = dlen;
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c
index 8a58ef3adab4..2f2633a8c4ad 100644
--- a/drivers/scsi/qla2xxx/qla_tmpl.c
+++ b/drivers/scsi/qla2xxx/qla_tmpl.c
@@ -219,8 +219,6 @@ qla27xx_skip_entry(struct qla27xx_fwdt_entry *ent, void 
*buf)
 {
if (buf)
ent->hdr.driver_flags |= DRIVER_FLAG_SKIP_ENTRY;
-   ql_dbg(ql_dbg_misc + ql_dbg_verbose, NULL, 0xd011,
-   "Skipping entry %d\n", ent->hdr.entry_type);
 }
 
 static int
@@ -818,6 +816,8 @@ qla27xx_walk_template(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_misc, vha, 0xd01a,
"%s: entry count %lx\n", __func__, count);
while (count--) {
+   if (buf && *len >= vha->hw->fw_dump_len)
+   break;
if (qla27xx_find_entry(ent->hdr.entry_type)(vha, ent, buf, len))
break;
ent = qla27xx_next_entry(ent);
@@ -825,18 +825,20 @@ qla27xx_walk_template(struct scsi_qla_host *vha,
 
if (count)
ql_dbg(ql_dbg_misc, vha, 0xd018,
-   "%s: residual count (%lx)\n", __func__, count);
+   "%s: entry residual count (%lx)\n", __func__, count);
 
if (ent->hdr.entry_type != ENTRY_TYPE_TMP_END)
ql_dbg(ql_dbg_misc, vha, 0xd019,
-   "%s: missing end (%lx)\n", __func__, count);
+   "%s: missing end entry (%lx)\n", __func__, count);
 
-   ql_dbg(ql_dbg_misc, vha, 0xd01b,
-   "%s: len=%lx\n", __func__, *len);
+   if (buf && *len != vha->hw->fw_dump_len)
+   ql_dbg(ql_dbg_misc, vha, 0xd01b,
+   "%s: length=%#lx residual=%+ld\n",
+   __func__, *len, vha->hw->fw_dump_len - *len);
 
if (buf) {
ql_log(ql_log_warn, vha, 0xd015,
-   "Firmware dump saved to temp buffer (%ld/%p)\n",
+   "Firmware dump saved to temp buffer (%lu/%p)\n",
vha->host_no, vha->hw->fw_dump);
qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
}
-- 
2.12.0



[PATCH 09/25] qla2xxx: Fix mailbox pointer error in classic fwdump.

2017-05-19 Thread Himanshu Madhani
From: Joe Carnuccio <joe.carnuc...@qlogic.com>

Cc: <sta...@vger.kernel.org>
Signed-off-by: Joe Carnuccio <joe.carnuc...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 51b4179469d1..88748a6ab73f 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -1131,7 +1131,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
/* Mailbox registers. */
mbx_reg = >mailbox0;
-   for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, dmp_reg++)
+   for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)
fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));
 
/* Transfer sequence registers. */
@@ -2090,7 +2090,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 
/* Mailbox registers. */
mbx_reg = >mailbox0;
-   for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, dmp_reg++)
+   for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)
fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));
 
/* Transfer sequence registers. */
-- 
2.12.0



[PATCH 05/25] qla2xxx: Fix number of queue pairs creation for MQ

2017-05-19 Thread Himanshu Madhani
From: Sawan Chandak <sawan.chan...@cavium.com>

when driver is loaded with Multi Queue enabled, it was
noticed that there was one less queue pair created.

Following message would indicate this

"No resources to create additional q pair."

The result of one less queue pair means that system can crash,
if the block mq layer thinks there is an extra hardware queue
available, and the driver will use a NULL ptr qpair in that instance.

Following stack trace is seen in one of the crash

irq_create_affinity_masks+0x98/0x530
irq_create_affinity_masks+0x98/0x530
__pci_enable_msix+0x321/0x4e0
mutex_lock+0x12/0x40
pci_alloc_irq_vectors_affinity+0xb5/0x140
qla24xx_enable_msix+0x79/0x530 [qla2xxx]
qla2x00_request_irqs+0x61/0x2d0 [qla2xxx]
qla2x00_probe_one+0xc73/0x2390 [qla2xxx]
ida_simple_get+0x98/0x100
kernfs_next_descendant_post+0x40/0x50
local_pci_probe+0x45/0xa0
pci_device_probe+0xfc/0x140
driver_probe_device+0x2c5/0x470
__driver_attach+0xdd/0xe0
driver_probe_device+0x470/0x470
bus_for_each_dev+0x6c/0xc0
driver_attach+0x1e/0x20
bus_add_driver+0x45/0x270
driver_register+0x60/0xe0
__pci_register_driver+0x4c/0x50
qla2x00_module_init+0x1ce/0x21e [qla2xxx]

Cc: <sta...@vger.kernel.org> #4.10
Signed-off-by: Sawan Chandak <sawan.chan...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h  | 1 +
 drivers/scsi/qla2xxx/qla_init.c | 5 -
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index ae119018dfaa..eddbc1218a39 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3425,6 +3425,7 @@ struct qla_hw_data {
uint8_t max_req_queues;
uint8_t max_rsp_queues;
uint8_t max_qpairs;
+   uint8_t num_qpairs;
struct qla_qpair *base_qpair;
struct qla_npiv_entry *npiv_info;
uint16_tnvram_npiv_size;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index a017a1af1707..f6130e8b1ca1 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7546,12 +7546,13 @@ struct qla_qpair *qla2xxx_create_qpair(struct 
scsi_qla_host *vha, int qos, int v
/* Assign available que pair id */
mutex_lock(>mq_lock);
qpair_id = find_first_zero_bit(ha->qpair_qid_map, 
ha->max_qpairs);
-   if (qpair_id >= ha->max_qpairs) {
+   if (ha->num_qpairs >= ha->max_qpairs) {
mutex_unlock(>mq_lock);
ql_log(ql_log_warn, vha, 0x0183,
"No resources to create additional q pair.\n");
goto fail_qid_map;
}
+   ha->num_qpairs++;
set_bit(qpair_id, ha->qpair_qid_map);
ha->queue_pair_map[qpair_id] = qpair;
qpair->id = qpair_id;
@@ -7638,6 +7639,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct 
scsi_qla_host *vha, int qos, int v
 fail_msix:
ha->queue_pair_map[qpair_id] = NULL;
clear_bit(qpair_id, ha->qpair_qid_map);
+   ha->num_qpairs--;
mutex_unlock(>mq_lock);
 fail_qid_map:
kfree(qpair);
@@ -7663,6 +7665,7 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, 
struct qla_qpair *qpair)
mutex_lock(>mq_lock);
ha->queue_pair_map[qpair->id] = NULL;
clear_bit(qpair->id, ha->qpair_qid_map);
+   ha->num_qpairs--;
list_del(>qp_list_elem);
if (list_empty(>qp_list))
vha->flags.qpairs_available = 0;
-- 
2.12.0



[PATCH 08/25] qla2xxx: Set bit 15 for DIAG_ECHO_TEST MBC.

2017-05-19 Thread Himanshu Madhani
From: Joe Carnuccio <joe.carnuc...@cavium.com>

Set bit (BIT_15) to send right ECHO payload information
for Diagnostic Echo Test command.

Signed-off-by: Joe Carnuccio <joe.carnuc...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_bsg.c | 9 +
 drivers/scsi/qla2xxx/qla_mbx.c | 4 ++--
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 16d1cd50feed..ca3420de5a01 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -730,6 +730,8 @@ qla2x00_process_loopback(struct bsg_job *bsg_job)
return -EIO;
}
 
+   memset(, 0, sizeof(elreq));
+
elreq.req_sg_cnt = dma_map_sg(>pdev->dev,
bsg_job->request_payload.sg_list, 
bsg_job->request_payload.sg_cnt,
DMA_TO_DEVICE);
@@ -795,10 +797,9 @@ qla2x00_process_loopback(struct bsg_job *bsg_job)
 
if (atomic_read(>loop_state) == LOOP_READY &&
(ha->current_topology == ISP_CFG_F ||
-   ((IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) &&
-   le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE
-   && req_data_len == MAX_ELS_FRAME_PAYLOAD)) &&
-   elreq.options == EXTERNAL_LOOPBACK) {
+   (le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE &&
+req_data_len == MAX_ELS_FRAME_PAYLOAD)) &&
+   elreq.options == EXTERNAL_LOOPBACK) {
type = "FC_BSG_HST_VENDOR_ECHO_DIAG";
ql_dbg(ql_dbg_user, vha, 0x701e,
"BSG request type: %s.\n", type);
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 12fea77e31c6..cba1fc5e8be9 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -4812,9 +4812,9 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct 
msg_echo_lb *mreq,
 
memset(mcp->mb, 0 , sizeof(mcp->mb));
mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
-   mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit 
address */
+   /* BIT_6 specifies 64bit address */
+   mcp->mb[1] = mreq->options | BIT_15 | BIT_6;
if (IS_CNA_CAPABLE(ha)) {
-   mcp->mb[1] |= BIT_15;
mcp->mb[2] = vha->fcoe_fcf_idx;
}
mcp->mb[16] = LSW(mreq->rcv_dma);
-- 
2.12.0



[PATCH 19/25] qla2xxx: Replace ql2xexchoffld & ql_dm_tgt_ex_pct parameter

2017-05-19 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Replace driver parameters ql2xexchoffld & ql_dm_tgt_ex_pct with
ql2xtgtexchg & ql2xiniexchg for readability.

Previously, the ql2xexchoffld module parameter was used to control
the max number of exchanges to be offload onto host memory.
Module parameter ql_dm_tgt_ex_pct was used to control the percentage
of exchanges allocated to the Target side.

With the updated module parameters, users can control the exact number
of exchanges for either Initiator or Target. The exchange offload feature
will be automatically enabled when the total number of exchanges exceeds
2048 limit.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h|   6 +-
 drivers/scsi/qla2xxx/qla_gbl.h|   5 +-
 drivers/scsi/qla2xxx/qla_init.c   |   2 +-
 drivers/scsi/qla2xxx/qla_inline.h |  16 +
 drivers/scsi/qla2xxx/qla_mbx.c|  14 ++--
 drivers/scsi/qla2xxx/qla_os.c | 138 +++---
 drivers/scsi/qla2xxx/qla_target.c |  53 +++
 7 files changed, 141 insertions(+), 93 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 51b262b236b4..ddf93efe3986 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -286,7 +286,7 @@ struct name_list_extended {
 #define RESPONSE_ENTRY_CNT_MQ  128 /* Number of response entries.*/
 #define ATIO_ENTRY_CNT_24XX4096/* Number of ATIO entries. */
 #define RESPONSE_ENTRY_CNT_FX00256 /* Number of response 
entries.*/
-#define EXTENDED_EXCH_ENTRY_CNT32768   /* Entries for offload 
case */
+#define FW_DEF_EXCHANGES_CNT 2048
 
 struct req_que;
 struct qla_tgt_sess;
@@ -3593,6 +3593,10 @@ struct qla_hw_data {
 #define IS_SHADOW_REG_CAPABLE(ha)  (IS_QLA27XX(ha))
 #define IS_DPORT_CAPABLE(ha)  (IS_QLA83XX(ha) || IS_QLA27XX(ha))
 #define IS_FAWWN_CAPABLE(ha)   (IS_QLA83XX(ha) || IS_QLA27XX(ha))
+#define IS_EXCHG_OFFLD_CAPABLE(ha) \
+   (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
+#define IS_EXLOGIN_OFFLD_CAPABLE(ha) \
+   (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
 
/* HBA serial number */
uint8_t serial0;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 5b2451745e9f..8ceb7299014c 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -136,7 +136,8 @@ extern uint64_t ql2xmaxlun;
 extern int ql2xmdcapmask;
 extern int ql2xmdenable;
 extern int ql2xexlogins;
-extern int ql2xexchoffld;
+extern int ql2xiniexchg;
+extern int ql2xtgtexchg;
 extern int ql2xfwholdabts;
 extern int ql2xmvasynctoatio;
 
@@ -839,7 +840,7 @@ extern int qla_get_exlogin_status(scsi_qla_host_t *, 
uint16_t *,
uint16_t *);
 extern int qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr);
 extern int qla_get_exchoffld_status(scsi_qla_host_t *, uint16_t *, uint16_t *);
-extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *, dma_addr_t);
+extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *);
 extern void qlt_handle_abts_recv(struct scsi_qla_host *, response_t *);
 
 int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *,
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 32fb3ed4fb33..0b91b886e5a3 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -2730,7 +2730,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
if (ql2xexlogins)
ha->flags.exlogins_enabled = 1;
 
-   if (ql2xexchoffld)
+   if (qla_is_exch_offld_enabled(vha))
ha->flags.exchoffld_enabled = 1;
 
rval = qla2x00_execute_fw(vha, srisc_address);
diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index c61a6a871c8e..2ad74353f21e 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -307,3 +307,19 @@ qla2x00_set_retry_delay_timestamp(fc_port_t *fcport, 
uint16_t retry_delay)
fcport->retry_delay_timestamp = jiffies +
(retry_delay * HZ / 10);
 }
+
+static inline bool
+qla_is_exch_offld_enabled(struct scsi_qla_host *vha)
+{
+   if (qla_ini_mode_enabled(vha) &&
+   (ql2xiniexchg > FW_DEF_EXCHANGES_CNT))
+   return true;
+   else if (qla_tgt_mode_enabled(vha) &&
+   (ql2xtgtexchg > FW_DEF_EXCHANGES_CNT))
+   return true;
+   else if (qla_dual_mode_enabled(vha) &&
+   ((ql2xiniexchg + ql2xtgtexchg) > FW_DEF_EXCHANGES_CNT))
+   return true;
+   else
+   return false;
+}
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 8c

[PATCH 12/25] qla2xxx: Fix path recovery

2017-05-19 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

If the port is moved/changed, current code would trigger
a deletion. If the port is already deleted, then do relogin.

Cc: <sta...@vger.kernel.org>
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_gs.c | 21 -
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 9bc9aa9e164a..5acebaf57796 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3118,16 +3118,27 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
 
if (fcport) {
/* cable moved. just plugged in */
-   ql_dbg(ql_dbg_disc, vha, 0x,
-  "%s %d %8phC post del sess\n",
-  __func__, __LINE__, fcport->port_name);
-
fcport->rscn_gen++;
fcport->d_id = ea->id;
fcport->scan_state = QLA_FCPORT_FOUND;
fcport->flags |= FCF_FABRIC_DEVICE;
 
-   qlt_schedule_sess_for_deletion_lock(fcport);
+   switch (fcport->disc_state) {
+   case DSC_DELETED:
+   ql_dbg(ql_dbg_disc, vha, 0x210d,
+   "%s %d %8phC login\n", __func__, __LINE__,
+   fcport->port_name);
+   qla24xx_fcport_handle_login(vha, fcport);
+   break;
+   case DSC_DELETE_PEND:
+   break;
+   default:
+   ql_dbg(ql_dbg_disc, vha, 0x2064,
+   "%s %d %8phC post del sess\n",
+   __func__, __LINE__, fcport->port_name);
+   qlt_schedule_sess_for_deletion_lock(fcport);
+   break;
+   }
} else {
/* create new fcport */
ql_dbg(ql_dbg_disc, vha, 0x,
-- 
2.12.0



[PATCH 15/25] qla2xxx: Convert 32-bit LUN usage to 64-bit

2017-05-19 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Convert 32bit LUN field to 64bit LUN.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c  | 30 +-
 drivers/scsi/qla2xxx/qla_target.h  |  4 ++--
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  2 +-
 3 files changed, 16 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index a2e17a5794ab..d6ad8d711e4c 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1799,7 +1799,7 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, 
uint32_t tag)
  * for the same lun)
  */
 static void abort_cmds_for_lun(struct scsi_qla_host *vha,
-   uint32_t lun, uint8_t *s_id)
+   u64 lun, uint8_t *s_id)
 {
struct qla_tgt_sess_op *op;
struct qla_tgt_cmd *cmd;
@@ -1810,7 +1810,7 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
spin_lock_irqsave(>cmd_list_lock, flags);
list_for_each_entry(op, >qla_sess_op_cmd_list, cmd_list) {
uint32_t op_key;
-   uint32_t op_lun;
+   u64 op_lun;
 
op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id);
op_lun = scsilun_to_int(
@@ -1832,7 +1832,7 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
 
list_for_each_entry(cmd, >qla_cmd_list, cmd_list) {
uint32_t cmd_key;
-   uint32_t cmd_lun;
+   u64 cmd_lun;
 
cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id);
cmd_lun = scsilun_to_int(
@@ -1851,17 +1851,13 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host 
*vha,
struct se_session *se_sess = sess->se_sess;
struct qla_tgt_mgmt_cmd *mcmd;
struct se_cmd *se_cmd;
-   u32 lun = 0;
int rc;
bool found_lun = false;
unsigned long flags;
 
spin_lock_irqsave(_sess->sess_cmd_lock, flags);
list_for_each_entry(se_cmd, _sess->sess_cmd_list, se_cmd_list) {
-   struct qla_tgt_cmd *cmd =
-   container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
if (se_cmd->tag == abts->exchange_addr_to_abort) {
-   lun = cmd->unpacked_lun;
found_lun = true;
break;
}
@@ -1900,7 +1896,7 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host 
*vha,
mcmd->reset_count = vha->hw->chip_reset;
mcmd->tmr_func = QLA_TGT_ABTS;
 
-   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, lun, mcmd->tmr_func,
+   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, 0, mcmd->tmr_func,
abts->exchange_addr_to_abort);
if (rc != 0) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf052,
@@ -4334,13 +4330,12 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host 
*vha, void *iocb)
struct qla_hw_data *ha = vha->hw;
struct qla_tgt *tgt;
struct fc_port *sess;
-   uint32_t lun, unpacked_lun;
+   u64 unpacked_lun;
int fn;
unsigned long flags;
 
tgt = vha->vha_tgt.qla_tgt;
 
-   lun = a->u.isp24.fcp_cmnd.lun;
fn = a->u.isp24.fcp_cmnd.task_mgmt_flags;
 
spin_lock_irqsave(>tgt.sess_lock, flags);
@@ -4348,7 +4343,8 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host 
*vha, void *iocb)
a->u.isp24.fcp_hdr.s_id);
spin_unlock_irqrestore(>tgt.sess_lock, flags);
 
-   unpacked_lun = scsilun_to_int((struct scsi_lun *));
+   unpacked_lun =
+   scsilun_to_int((struct scsi_lun *)>u.isp24.fcp_cmnd.lun);
 
if (!sess) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf024,
@@ -4371,7 +4367,7 @@ static int __qlt_abort_task(struct scsi_qla_host *vha,
struct atio_from_isp *a = (struct atio_from_isp *)iocb;
struct qla_hw_data *ha = vha->hw;
struct qla_tgt_mgmt_cmd *mcmd;
-   uint32_t lun, unpacked_lun;
+   u64 unpacked_lun;
int rc;
 
mcmd = mempool_alloc(qla_tgt_mgmt_cmd_mempool, GFP_ATOMIC);
@@ -4387,8 +4383,8 @@ static int __qlt_abort_task(struct scsi_qla_host *vha,
memcpy(>orig_iocb.imm_ntfy, iocb,
sizeof(mcmd->orig_iocb.imm_ntfy));
 
-   lun = a->u.isp24.fcp_cmnd.lun;
-   unpacked_lun = scsilun_to_int((struct scsi_lun *));
+   unpacked_lun =
+   scsilun_to_int((struct scsi_lun *)>u.isp24.fcp_cmnd.lun);
mcmd->reset_count = vha->hw->chip_reset;
mcmd->tmr_func = QLA_TGT_2G_ABORT_TASK;
 
@@ -5877,7 +5873,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
unsigned long flags;
uint8_t *s_id = NULL; /* to hide compiler warnings */
int rc;
-   uint32_t lun, unpacked_

[PATCH 01/25] qla2xxx: Fix Target mode configuration for ISP25XX

2017-05-19 Thread Himanshu Madhani
Following messages are seen into system logs

qla2xxx [:09:00.0]-00af:9: Performing ISP error recovery -
ha=98315ee3.
qla2xxx [:09:00.0]-504b:9: RISC paused -- HCCR=40, Dumping firmware.
qla2xxx [:09:00.0]-d009:9: Firmware has been previously dumped
(ba488c001000) -- ignoring request.
qla2xxx [:09:00.0]-504b:9: RISC paused -- HCCR=40, Dumping firmware.

See Bugzilla for details
https://bugzilla.kernel.org/show_bug.cgi?id=195285

Fixes: d74595278f4ab ("scsi: qla2xxx: Add multiple queue pair functionality.")
Cc: <sta...@vger.kernel.org> # 4.10
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
Signed-off-by: Giridhar Malavali <giridhar.malav...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_isr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index aac03504d9a3..2572121b765b 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -3282,7 +3282,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct 
rsp_que *rsp)
}
 
/* Enable MSI-X vector for response queue update for queue 0 */
-   if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+   if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
if (ha->msixbase && ha->mqiobase &&
(ha->max_rsp_queues > 1 || ha->max_req_queues > 1 ||
 ql2xmqsupport))
-- 
2.12.0



[PATCH 24/25] qla2xxx: Remove extra register read

2017-05-19 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Register read is expensive in IO path, remove extra register
read in each interrupt processing to improve performance.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_iocb.c   |  4 +++-
 drivers/scsi/qla2xxx/qla_target.c | 11 ++-
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index ea027f6a7fd4..8404f17f3c6c 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -464,7 +464,9 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct 
req_que *req)
req->ring_ptr++;
 
/* Set chip new ring index. */
-   if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+   if (ha->mqenable || IS_QLA27XX(ha)) {
+   WRT_REG_DWORD(req->req_q_in, req->ring_index);
+   } else if (IS_QLA83XX(ha)) {
WRT_REG_DWORD(req->req_q_in, req->ring_index);
RD_REG_DWORD_RELAXED(>iobase->isp24.hccr);
} else if (IS_QLAFX00(ha)) {
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 95aad9c329d7..f42313e49443 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -2223,11 +2223,10 @@ static void qlt_unmap_sg(struct scsi_qla_host *vha, 
struct qla_tgt_cmd *cmd)
 static int qlt_check_reserve_free_req(struct scsi_qla_host *vha,
uint32_t req_cnt)
 {
-   uint32_t cnt, cnt_in;
+   uint32_t cnt;
 
if (vha->req->cnt < (req_cnt + 2)) {
cnt = (uint16_t)RD_REG_DWORD(vha->req->req_q_out);
-   cnt_in = (uint16_t)RD_REG_DWORD(vha->req->req_q_in);
 
if  (vha->req->ring_index < cnt)
vha->req->cnt = cnt - vha->req->ring_index;
@@ -2235,14 +2234,8 @@ static int qlt_check_reserve_free_req(struct 
scsi_qla_host *vha,
vha->req->cnt = vha->req->length -
(vha->req->ring_index - cnt);
 
-   if (unlikely(vha->req->cnt < (req_cnt + 2))) {
-   ql_dbg(ql_dbg_io, vha, 0x305a,
-   "qla_target(%d): There is no room in the request 
ring: vha->req->ring_index=%d, vha->req->cnt=%d, req_cnt=%d Req-out=%d 
Req-in=%d Req-Length=%d\n",
-   vha->vp_idx, vha->req->ring_index,
-   vha->req->cnt, req_cnt, cnt, cnt_in,
-   vha->req->length);
+   if (unlikely(vha->req->cnt < (req_cnt + 2)))
return -EAGAIN;
-   }
}
 
vha->req->cnt -= req_cnt;
-- 
2.12.0



[PATCH 23/25] qla2xxx: Remove unused irq_cmd_count field.

2017-05-19 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

When driver is unloaded, all sessions are torn down, all
commmands are flushed, chip is reset to ensure there is
no knowledge of target mode in ISP. The irq_cmd_count field
was used to make sure all commands are processed on top of that.
The irq_cmd_count is now redundant and not needed.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 9 +
 drivers/scsi/qla2xxx/qla_target.h | 1 -
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 5a8ed73e6ef2..95aad9c329d7 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -5326,8 +5326,6 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, 
response_t *pkt)
 * Otherwise, some commands can stuck.
 */
 
-   tgt->irq_cmd_count++;
-
switch (pkt->entry_type) {
case CTIO_CRC2:
case CTIO_TYPE7:
@@ -5353,10 +5351,8 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, 
response_t *pkt)
}
 
rc = qlt_chk_qfull_thresh_hold(vha, atio, true);
-   if (rc != 0) {
-   tgt->irq_cmd_count--;
+   if (rc != 0)
return;
-   }
 
rc = qlt_handle_cmd_for_atio(vha, atio);
if (unlikely(rc != 0)) {
@@ -5488,7 +5484,6 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, 
response_t *pkt)
break;
}
 
-   tgt->irq_cmd_count--;
 }
 
 /*
@@ -5518,7 +5513,6 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host 
*vha,
 * Otherwise, some commands can stuck.
 */
 
-   tgt->irq_cmd_count++;
 
switch (code) {
case MBA_RESET: /* Reset */
@@ -5606,7 +5600,6 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host 
*vha,
break;
}
 
-   tgt->irq_cmd_count--;
 }
 
 static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha,
diff --git a/drivers/scsi/qla2xxx/qla_target.h 
b/drivers/scsi/qla2xxx/qla_target.h
index de6b8c3a863e..6ce720f9f890 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -790,7 +790,6 @@ struct qla_tgt {
 * because req_pkt() can drop/reaquire HW lock inside. Protected by
 * HW lock.
 */
-   int irq_cmd_count;
int atio_irq_cmd_count;
 
int datasegs_per_cmd, datasegs_per_cont, sg_tablesize;
-- 
2.12.0



[PATCH 22/25] qla2xxx: Enable auto SCSI BUSY status for target mode

2017-05-19 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

Accelerate generation of SCSI busy to let initiators slow
down when target is running low in resources.

Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_init.c | 13 +++--
 drivers/scsi/qla2xxx/qla_mbx.c  |  2 ++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 0b91b886e5a3..497cba4ba72f 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7379,10 +7379,19 @@ qla81xx_update_fw_options(scsi_qla_host_t *vha)
}
 
if (qla_tgt_mode_enabled(vha) ||
-   qla_dual_mode_enabled(vha))
+   qla_dual_mode_enabled(vha)) {
+   /* FW auto send SCSI status during */
+   ha->fw_options[1] |= BIT_8;
+   ha->fw_options[10] |= (u16)SAM_STAT_BUSY << 8;
+
+   /* FW perform Exchang validation */
ha->fw_options[2] |= BIT_4;
-   else
+   } else {
+   ha->fw_options[1]  &= ~BIT_8;
+   ha->fw_options[10] &= 0x00ff;
+
ha->fw_options[2] &= ~BIT_4;
+   }
 
if (ql2xetsenable) {
/* Enable ETS Burst. */
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index e69b854f19ae..864a2db3a317 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -1048,6 +1048,8 @@ qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t 
*fwopts)
mcp->in_mb = MBX_0;
if (IS_FWI2_CAPABLE(vha->hw)) {
mcp->in_mb |= MBX_1;
+   mcp->mb[10] = fwopts[10];
+   mcp->out_mb |= MBX_10;
} else {
mcp->mb[10] = fwopts[10];
mcp->mb[11] = fwopts[11];
-- 
2.12.0



[PATCH 25/25] qla2xxx: Simplify debug printing of portid.

2017-05-19 Thread Himanshu Madhani
From: Joe Carnuccio <joe.carnuc...@cavium.com>

Signed-off-by: Joe Carnuccio <joe.carnuc...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/qla_attr.c   |  4 +-
 drivers/scsi/qla2xxx/qla_bsg.c| 15 +++
 drivers/scsi/qla2xxx/qla_gs.c | 54 +-
 drivers/scsi/qla2xxx/qla_init.c   | 82 ++-
 drivers/scsi/qla2xxx/qla_inline.h |  8 ++--
 drivers/scsi/qla2xxx/qla_iocb.c   | 18 -
 drivers/scsi/qla2xxx/qla_isr.c| 58 +++
 drivers/scsi/qla2xxx/qla_mbx.c|  7 ++--
 8 files changed, 91 insertions(+), 155 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index a7ac81b473a4..4ab771cc0c15 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -769,9 +769,7 @@ qla2x00_issue_logo(struct file *filp, struct kobject *kobj,
did.b.area = (type & 0xff00) >> 8;
did.b.al_pa = (type & 0x00ff);
 
-   ql_log(ql_log_info, vha, 0xd04d, "portid=%02x%02x%02x done\n",
-   did.b.domain, did.b.area, did.b.al_pa);
-
+   ql_log(ql_log_info, vha, 0xd04d, "portid=%06x done\n", did.b24);
ql_log(ql_log_info, vha, 0x70e4, "%s: %d\n", __func__, type);
 
qla24xx_els_dcmd_iocb(vha, ELS_DCMD_LOGO, did);
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index eb2b873f12ba..7d025aec7b9d 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -382,10 +382,9 @@ qla2x00_process_els(struct bsg_job *bsg_job)
sp->done = qla2x00_bsg_job_done;
 
ql_dbg(ql_dbg_user, vha, 0x700a,
-   "bsg rqst type: %s els type: %x - loop-id=%x "
-   "portid=%-2x%02x%02x.\n", type,
-   bsg_request->rqst_data.h_els.command_code, fcport->loop_id,
-   fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa);
+   "bsg rqst type: %s els type: %x - loop-id=%x portid=%06x.\n",
+   type, bsg_request->rqst_data.h_els.command_code, fcport->loop_id,
+   fcport->d_id.b24);
 
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) {
@@ -529,11 +528,9 @@ qla2x00_process_ct(struct bsg_job *bsg_job)
sp->done = qla2x00_bsg_job_done;
 
ql_dbg(ql_dbg_user, vha, 0x7016,
-   "bsg rqst type: %s else type: %x - "
-   "loop-id=%x portid=%02x%02x%02x.\n", type,
-   (bsg_request->rqst_data.h_ct.preamble_word2 >> 16),
-   fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
-   fcport->d_id.b.al_pa);
+   "bsg rqst type: %s else type: %x - loop-id=%x portid=%06x.\n",
+   type, bsg_request->rqst_data.h_ct.preamble_word2 >> 16,
+   fcport->loop_id, fcport->d_id.b24);
 
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) {
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 7a2fe05baf4f..1b6fc3d80ec8 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -129,9 +129,8 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t 
*ms_pkt,
rval = QLA_FUNCTION_FAILED;
if (ms_pkt->entry_status != 0) {
ql_dbg(ql_dbg_disc, vha, 0x2031,
-   "%s failed, error status (%x) on port_id: %02x%02x%02x.\n",
-   routine, ms_pkt->entry_status, vha->d_id.b.domain,
-   vha->d_id.b.area, vha->d_id.b.al_pa);
+   "%s failed, error status (%x) on port_id: %06x.\n",
+   routine, ms_pkt->entry_status, vha->d_id.b24);
} else {
if (IS_FWI2_CAPABLE(ha))
comp_status = le16_to_cpu(
@@ -145,10 +144,9 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, 
ms_iocb_entry_t *ms_pkt,
if (ct_rsp->header.response !=
cpu_to_be16(CT_ACCEPT_RESPONSE)) {
ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077,
-   "%s failed rejected request on port_id: 
%02x%02x%02x Completion status 0x%x, response 0x%x\n",
-   routine, vha->d_id.b.domain,
-   vha->d_id.b.area, vha->d_id.b.al_pa,
-   comp_status, ct_rsp->header.response);
+   "%s failed rejected request on port_id: 
%06x Compeltion status 0x%x, response 0x%x\n",
+   routine, vha->d_id.b24, comp_status,
+   ct_rsp->header.response);
ql_dump_buffer(ql_dbg_disc + ql_

[PATCH 13/25] tcm_qla2xxx: Do not allow aborted cmd to advance.

2017-05-19 Thread Himanshu Madhani
From: Quinn Tran <quinn.t...@cavium.com>

In case of hardware queue full, commands can loop between
TCM stack and tcm_qla2xx shim layers for retry. While command
is waiting for retry, task mgmt can get ahead and abort the
cmmand that encountered queue full condition. Fix this by
dropping the command, if task mgmt has already started the
command free process.

Cc: <sta...@vger.kernel.org>
Signed-off-by: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madh...@cavium.com>
---
 drivers/scsi/qla2xxx/tcm_qla2xxx.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c 
b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 7443e4efa3ae..07f8ad001bcb 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -686,6 +686,20 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
struct qla_tgt_cmd, se_cmd);
int xmit_type = QLA_TGT_XMIT_STATUS;
 
+   if (cmd->aborted) {
+   /*
+* Cmd can loop during Q-full. tcm_qla2xxx_aborted_task
+* can get ahead of this cmd. tcm_qla2xxx_aborted_task
+* already kick start the free.
+*/
+   pr_debug(
+   "queue_data_in aborted cmd[%p] refcount %d transport_state 
%x, t_state %x, se_cmd_flags %x\n",
+   cmd, kref_read(>se_cmd.cmd_kref),
+   cmd->se_cmd.transport_state, cmd->se_cmd.t_state,
+   cmd->se_cmd.se_cmd_flags);
+   return 0;
+   }
+
cmd->bufflen = se_cmd->data_length;
cmd->sg = NULL;
cmd->sg_cnt = 0;
-- 
2.12.0



<    1   2   3   4   5   6   7   8   9   10   >