All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target.
@ 2017-02-03 22:40 Himanshu Madhani
  2017-02-03 22:40 ` [PATCH v2 01/14] qla2xxx: Fix delayed response to command for loop mode/direct connect Himanshu Madhani
                   ` (14 more replies)
  0 siblings, 15 replies; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

Hi Bart,

Please consider this series for inclusion in target-pending.

This series contains following changes.

o Fix for the deadlock because of inconsistent lock usage reported by you. 
o Added patch to submit non-critical MBX command via IOCB path.
o Improved T10-DIF/PI handling with target stack.
o Changed scsi host lookup method.
o Some minor bug fixes.

Changes from v1 -> v2

o Dropped patch for indentation as its already part of scsi-target-for-v4.11 branch.
o Rebased series based on scsi-target-for-v4.11 branch.

Please apply to target-pending.

Thanks,
Himanshu  

Anil Gurumurthy (1):
  qla2xxx: Export DIF stats via debugfs

Himanshu Madhani (2):
  qla2xxx: Add DebugFS node to display Port Database
  qla2xxx: Update driver version to 9.00.00.00-k

Joe Carnuccio (1):
  qla2xxx: Allow vref count to timeout on vport delete.

Quinn Tran (10):
  qla2xxx: Fix delayed response to command for loop mode/direct connect.
  qla2xxx: Allow relogin to proceed if remote login did not finish
  qla2xxx: Use IOCB interface to submit non-critical MBX.
  qla2xxx: Improve T10-DIF/PI handling in driver.
  qla2xxx: Change scsi host lookup method
  qla2xxx: Fix memory leak for abts processing
  qla2xxx: Fix request queue corruption.
  qla2xxx: Fix inadequate lock protection for ABTS.
  qla2xxx: Add async new target notification
  qla2xxx: Fix sess_lock & hardware_lock lock order problem.

 drivers/scsi/qla2xxx/Kconfig       |   1 +
 drivers/scsi/qla2xxx/qla_attr.c    |   4 +-
 drivers/scsi/qla2xxx/qla_dbg.h     |   1 +
 drivers/scsi/qla2xxx/qla_def.h     |  56 ++-
 drivers/scsi/qla2xxx/qla_dfs.c     | 107 ++++-
 drivers/scsi/qla2xxx/qla_gbl.h     |  13 +-
 drivers/scsi/qla2xxx/qla_init.c    |  88 ++--
 drivers/scsi/qla2xxx/qla_isr.c     |  41 +-
 drivers/scsi/qla2xxx/qla_mbx.c     | 307 ++++++++++++--
 drivers/scsi/qla2xxx/qla_mid.c     |  12 +-
 drivers/scsi/qla2xxx/qla_os.c      |  46 ++-
 drivers/scsi/qla2xxx/qla_target.c  | 804 +++++++++++++++++++++++--------------
 drivers/scsi/qla2xxx/qla_target.h  |  38 +-
 drivers/scsi/qla2xxx/qla_version.h |   6 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  84 +++-
 15 files changed, 1158 insertions(+), 450 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 01/14] qla2xxx: Fix delayed response to command for loop mode/direct connect.
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-08 18:35   ` Bart Van Assche
  2017-02-03 22:40 ` [PATCH v2 02/14] qla2xxx: Allow relogin to proceed if remote login did not finish Himanshu Madhani
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

From: Quinn Tran <quinn.tran@cavium.com>

Current driver wait for FW to be in the ready state before
processing in-coming commands. For Arbitrated Loop or
Point-to- Point (not switch), FW Ready state can take a while.
FW will transition to ready state after all Nports have been
logged in. In the mean time, certain initiators have completed
the login and starts IO. Driver needs to start processing all
queues if FW is already started.

Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h    | 13 +++++++++--
 drivers/scsi/qla2xxx/qla_gbl.h    |  1 +
 drivers/scsi/qla2xxx/qla_init.c   | 12 +++++++++++
 drivers/scsi/qla2xxx/qla_isr.c    | 14 +++++++++++-
 drivers/scsi/qla2xxx/qla_mbx.c    |  6 +++---
 drivers/scsi/qla2xxx/qla_os.c     | 45 ++++++++++++++++++++++++++++++++++++++-
 drivers/scsi/qla2xxx/qla_target.c | 38 ++++++++++++++++++++++-----------
 7 files changed, 109 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index ac37e91..fbaa39b 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3290,6 +3290,10 @@ struct qlt_hw_data {
 
 #define LEAK_EXCHG_THRESH_HOLD_PERCENT 75	/* 75 percent */
 
+#define QLA_EARLY_LINKUP(_ha) \
+	((_ha->flags.n2n_ae || _ha->flags.lip_ae) && \
+	 _ha->flags.fw_started && !_ha->flags.fw_init_done)
+
 /*
  * Qlogic host adapter specific data structure.
 */
@@ -3339,7 +3343,11 @@ struct qla_hw_data {
 		uint32_t	fawwpn_enabled:1;
 		uint32_t	exlogins_enabled:1;
 		uint32_t	exchoffld_enabled:1;
-		/* 35 bits */
+
+		uint32_t	lip_ae:1;
+		uint32_t	n2n_ae:1;
+		uint32_t	fw_started:1;
+		uint32_t	fw_init_done:1;
 	} flags;
 
 	/* This spinlock is used to protect "io transactions", you must
@@ -3432,7 +3440,6 @@ struct qla_hw_data {
 #define P2P_LOOP  3
 	uint8_t		interrupts_on;
 	uint32_t	isp_abort_cnt;
-
 #define PCI_DEVICE_ID_QLOGIC_ISP2532    0x2532
 #define PCI_DEVICE_ID_QLOGIC_ISP8432    0x8432
 #define PCI_DEVICE_ID_QLOGIC_ISP8001	0x8001
@@ -3913,6 +3920,7 @@ struct qla_tgt_counters {
 	struct list_head vp_fcports;	/* list of fcports */
 	struct list_head work_list;
 	spinlock_t work_lock;
+	struct work_struct iocb_work;
 
 	/* Commonly used flags and state information. */
 	struct Scsi_Host *host;
@@ -3932,6 +3940,7 @@ struct qla_tgt_counters {
 		uint32_t	fw_tgt_reported:1;
 		uint32_t	bbcr_enable:1;
 		uint32_t	qpairs_available:1;
+		uint32_t	iocb_work_sheduled:1;
 	} flags;
 
 	atomic_t	loop_state;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index b3d6441..862d5f5 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -193,6 +193,7 @@ extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
 void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *,
 	uint16_t *);
 int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *);
+void qla2x00_schedule_work(struct scsi_qla_host *);
 
 /*
  * Global Functions in qla_mid.c source file.
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f654314..9f3db52 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3212,6 +3212,7 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
 	} else {
 		ql_dbg(ql_dbg_init, vha, 0x00d3,
 		    "Init Firmware -- success.\n");
+		ha->flags.fw_started = 1;
 	}
 
 	return (rval);
@@ -4036,6 +4037,7 @@ static void qla2xxx_nvram_wwn_from_ofw(scsi_qla_host_t *vha, nvram_t *nv)
 			atomic_set(&vha->loop_state, LOOP_READY);
 			ql_dbg(ql_dbg_disc, vha, 0x2069,
 			    "LOOP READY.\n");
+			ha->flags.fw_init_done = 1;
 
 			/*
 			 * Process any ATIO queue entries that came in
@@ -5526,6 +5528,11 @@ int qla2x00_perform_loop_resync(scsi_qla_host_t *ha)
 	if (!(IS_P3P_TYPE(ha)))
 		ha->isp_ops->reset_chip(vha);
 
+	ha->flags.n2n_ae = 0;
+	ha->flags.lip_ae = 0;
+	ha->current_topology = 0;
+	ha->flags.fw_started = 0;
+	ha->flags.fw_init_done = 0;
 	ha->chip_reset++;
 
 	atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
@@ -6802,6 +6809,8 @@ uint8_t qla27xx_find_valid_image(struct scsi_qla_host *vha)
 		return;
 	if (!ha->fw_major_version)
 		return;
+	if (!ha->flags.fw_started)
+		return;
 
 	ret = qla2x00_stop_firmware(vha);
 	for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT &&
@@ -6815,6 +6824,9 @@ uint8_t qla27xx_find_valid_image(struct scsi_qla_host *vha)
 		    "Attempting retry of stop-firmware command.\n");
 		ret = qla2x00_stop_firmware(vha);
 	}
+
+	ha->flags.fw_started = 0;
+	ha->flags.fw_init_done = 0;
 }
 
 int
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 914cc5a..0fd3258 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -708,6 +708,8 @@ static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
 		    "mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx);
 
 		ha->isp_ops->fw_dump(vha, 1);
+		ha->flags.fw_init_done = 0;
+		ha->flags.fw_started = 0;
 
 		if (IS_FWI2_CAPABLE(ha)) {
 			if (mb[1] == 0 && mb[2] == 0) {
@@ -761,6 +763,9 @@ static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
 		break;
 
 	case MBA_LIP_OCCURRED:		/* Loop Initialization Procedure */
+		ha->flags.lip_ae = 1;
+		ha->flags.n2n_ae = 0;
+
 		ql_dbg(ql_dbg_async, vha, 0x5009,
 		    "LIP occurred (%x).\n", mb[1]);
 
@@ -797,6 +802,10 @@ static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
 		break;
 
 	case MBA_LOOP_DOWN:		/* Loop Down Event */
+		ha->flags.n2n_ae = 0;
+		ha->flags.lip_ae = 0;
+		ha->current_topology = 0;
+
 		mbx = (IS_QLA81XX(ha) || IS_QLA8031(ha))
 			? RD_REG_WORD(&reg24->mailbox4) : 0;
 		mbx = (IS_P3P_TYPE(ha)) ? RD_REG_WORD(&reg82->mailbox_out[4])
@@ -866,6 +875,9 @@ static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
 
 	/* case MBA_DCBX_COMPLETE: */
 	case MBA_POINT_TO_POINT:	/* Point-to-Point */
+		ha->flags.lip_ae = 0;
+		ha->flags.n2n_ae = 1;
+
 		if (IS_QLA2100(ha))
 			break;
 
@@ -2691,7 +2703,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
 	struct sts_entry_24xx *pkt;
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!vha->flags.online)
+	if (!ha->flags.fw_started)
 		return;
 
 	while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 35079f4..db6bd92 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -3612,11 +3612,11 @@ struct tsk_mgmt_cmd {
 
 	if (rptid_entry->format == 0) {
 		/* loop */
-		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b7,
+		ql_dbg(ql_dbg_async, vha, 0x10b7,
 		    "Format 0 : Number of VPs setup %d, number of "
 		    "VPs acquired %d.\n", rptid_entry->vp_setup,
 		    rptid_entry->vp_acquired);
-		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b8,
+		ql_dbg(ql_dbg_async, vha, 0x10b8,
 		    "Primary port id %02x%02x%02x.\n",
 		    rptid_entry->port_id[2], rptid_entry->port_id[1],
 		    rptid_entry->port_id[0]);
@@ -3631,7 +3631,7 @@ struct tsk_mgmt_cmd {
 
 	} else if (rptid_entry->format == 1) {
 		/* fabric */
-		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b9,
+		ql_dbg(ql_dbg_async, vha, 0x10b9,
 		    "Format 1: VP[%d] enabled - status %d - with "
 		    "port id %02x%02x%02x.\n", rptid_entry->vp_idx,
 			rptid_entry->vp_status,
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 6e2f8fe..10cb4990 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -4324,7 +4324,11 @@ struct qla_work_evt *
 	spin_lock_irqsave(&vha->work_lock, flags);
 	list_add_tail(&e->list, &vha->work_list);
 	spin_unlock_irqrestore(&vha->work_lock, flags);
-	qla2xxx_wake_dpc(vha);
+
+	if (QLA_EARLY_LINKUP(vha->hw))
+		qla2x00_schedule_work(vha);
+	else
+		qla2xxx_wake_dpc(vha);
 
 	return QLA_SUCCESS;
 }
@@ -4574,6 +4578,45 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
 	}
 }
 
+static void qla2x00_iocb_work_fn(struct work_struct *work)
+{
+	struct scsi_qla_host *vha = container_of(work,
+		struct scsi_qla_host, iocb_work);
+	unsigned long flags;
+	int cnt = 0;
+
+	while (!list_empty(&vha->work_list)) {
+		qla2x00_do_work(vha);
+		cnt++;
+		if (cnt > 10)
+			break;
+	}
+
+	spin_lock_irqsave(&vha->work_lock, flags);
+	vha->flags.iocb_work_sheduled = 0;
+	spin_unlock_irqrestore(&vha->work_lock, flags);
+}
+
+void qla2x00_schedule_work(struct scsi_qla_host *vha)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&vha->work_lock, flags);
+	if (vha->flags.iocb_work_sheduled) {
+		spin_unlock_irqrestore(&vha->work_lock, flags);
+		return;
+	}
+	vha->flags.iocb_work_sheduled = 1;
+	spin_unlock_irqrestore(&vha->work_lock, flags);
+
+	/*
+	 * We're in the middle of bringing up the adapter.
+	 * the scheduled work need to go out now.
+	 */
+	INIT_WORK(&vha->iocb_work, qla2x00_iocb_work_fn);
+	schedule_work(&vha->iocb_work);
+}
+
 /* Relogins all the fcports of a vport
  * Context: dpc thread
  */
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 0a32a37..19ac2b5 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -613,6 +613,7 @@ int qla24xx_async_notify_ack(scsi_qla_host_t *vha, fc_port_t *fcport,
 		break;
 	case SRB_NACK_PRLI:
 		fcport->fw_login_state = DSC_LS_PRLI_PEND;
+		fcport->deleted = 0;
 		c = "PRLI";
 		break;
 	case SRB_NACK_LOGO:
@@ -1551,6 +1552,9 @@ static void qlt_send_notify_ack(struct scsi_qla_host *vha,
 	request_t *pkt;
 	struct nack_to_isp *nack;
 
+	if (!ha->flags.fw_started)
+		return;
+
 	ql_dbg(ql_dbg_tgt, vha, 0xe004, "Sending NOTIFY_ACK (ha=%p)\n", ha);
 
 	/* Send marker if required */
@@ -2885,7 +2889,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
 	else
 		vha->tgt_counters.core_qla_que_buf++;
 
-	if (!vha->flags.online || cmd->reset_count != ha->chip_reset) {
+	if (!ha->flags.fw_started || cmd->reset_count != ha->chip_reset) {
 		/*
 		 * Either the port is not online or this request was from
 		 * previous life, just abort the processing.
@@ -3026,7 +3030,7 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 
-	if (!vha->flags.online || (cmd->reset_count != ha->chip_reset) ||
+	if (!ha->flags.fw_started || (cmd->reset_count != ha->chip_reset) ||
 	    (cmd->sess && cmd->sess->deleted)) {
 		/*
 		 * Either the port is not online or this request was from
@@ -3230,7 +3234,7 @@ static int __qlt_send_term_imm_notif(struct scsi_qla_host *vha,
 	ql_dbg(ql_dbg_tgt_tmr, vha, 0xe01c,
 	    "Sending TERM ELS CTIO (ha=%p)\n", ha);
 
-	pkt = (request_t *)qla2x00_alloc_iocbs_ready(vha, NULL);
+	pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL);
 	if (pkt == NULL) {
 		ql_dbg(ql_dbg_tgt, vha, 0xe080,
 		    "qla_target(%d): %s failed: unable to allocate "
@@ -4564,7 +4568,8 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
 		}
 
 		if (sess != NULL) {
-			if (sess->fw_login_state == DSC_LS_PLOGI_PEND) {
+			if ((sess->fw_login_state != DSC_LS_PLOGI_PEND) &&
+			    (sess->fw_login_state != DSC_LS_PLOGI_COMP)) {
 				/*
 				 * Impatient initiator sent PRLI before last
 				 * PLOGI could finish. Will force him to re-try,
@@ -4603,15 +4608,23 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
 
 		/* Make session global (not used in fabric mode) */
 		if (ha->current_topology != ISP_CFG_F) {
-			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
-			set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
-			qla2xxx_wake_dpc(vha);
+			if (sess) {
+				ql_dbg(ql_dbg_disc, vha, 0xffff,
+				    "%s %d %8phC post nack\n",
+				    __func__, __LINE__, sess->port_name);
+				qla24xx_post_nack_work(vha, sess, iocb,
+					SRB_NACK_PRLI);
+				res = 0;
+			} else {
+				set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+				set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
+				qla2xxx_wake_dpc(vha);
+			}
 		} else {
 			if (sess) {
 				ql_dbg(ql_dbg_disc, vha, 0xffff,
-					   "%s %d %8phC post nack\n",
-					   __func__, __LINE__, sess->port_name);
-
+				    "%s %d %8phC post nack\n",
+				    __func__, __LINE__, sess->port_name);
 				qla24xx_post_nack_work(vha, sess, iocb,
 					SRB_NACK_PRLI);
 				res = 0;
@@ -4619,7 +4632,6 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
 		}
 		break;
 
-
 	case ELS_TPRLO:
 		if (le16_to_cpu(iocb->u.isp24.flags) &
 			NOTIFY24XX_FLAGS_GLOBAL_TPRLO) {
@@ -5083,7 +5095,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
 	unsigned long flags;
 
 	if (unlikely(tgt == NULL)) {
-		ql_dbg(ql_dbg_io, vha, 0x3064,
+		ql_dbg(ql_dbg_tgt, vha, 0x3064,
 		    "ATIO pkt, but no tgt (ha %p)", ha);
 		return;
 	}
@@ -6214,7 +6226,7 @@ static void qlt_disable_vha(struct scsi_qla_host *vha)
 	struct atio_from_isp *pkt;
 	int cnt, i;
 
-	if (!vha->flags.online)
+	if (!ha->flags.fw_started)
 		return;
 
 	while ((ha->tgt.atio_ring_ptr->signature != ATIO_PROCESSED) ||
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 02/14] qla2xxx: Allow relogin to proceed if remote login did not finish
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
  2017-02-03 22:40 ` [PATCH v2 01/14] qla2xxx: Fix delayed response to command for loop mode/direct connect Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-08 18:42   ` Bart Van Assche
  2017-02-03 22:40 ` [PATCH v2 03/14] qla2xxx: Allow vref count to timeout on vport delete Himanshu Madhani
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

From: Quinn Tran <quinn.tran@cavium.com>

If the remote port have started the login process, then the
PLOGI and PRLI should be back to back. Driver will allow
the remote port to complete the process. For the case where
the remote port decide to back off from sending PRLI, this
local port sets an expiration timer for the PRLI. Once the
expiration time passes, the relogin retry logic is allowed
to go through and perform login with the remote port.

Signed-off-by: Quinn Tran <quinn.tran@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h    |  2 ++
 drivers/scsi/qla2xxx/qla_init.c   | 16 ++++++++++++++--
 drivers/scsi/qla2xxx/qla_isr.c    | 25 +++++++++++++++++++------
 drivers/scsi/qla2xxx/qla_target.c |  1 +
 4 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index fbaa39b..bf2ae8d3 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2300,6 +2300,8 @@ enum rscn_addr_format {
 	struct ct_sns_desc ct_desc;
 	enum discovery_state disc_state;
 	enum login_state fw_login_state;
+	unsigned long plogi_nack_done_jiff;
+
 	u32 login_gen, last_login_gen;
 	u32 rscn_gen, last_rscn_gen;
 	u32 chip_reset;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 9f3db52..e84ab37 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -876,10 +876,16 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
 	fcport->login_retry--;
 
 	if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
-	    (fcport->fw_login_state == DSC_LS_PLOGI_COMP) ||
 	    (fcport->fw_login_state == DSC_LS_PRLI_PEND))
 		return 0;
 
+	if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
+		unsigned long t = fcport->plogi_nack_done_jiff + HZ;
+
+		if (time_before_eq(jiffies, t))
+			return 0;
+	}
+
 	/* for pure Target Mode. Login will not be initiated */
 	if (vha->host->active_mode == MODE_TARGET)
 		return 0;
@@ -1041,10 +1047,16 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
 		fcport->flags);
 
 	if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
-	    (fcport->fw_login_state == DSC_LS_PLOGI_COMP) ||
 	    (fcport->fw_login_state == DSC_LS_PRLI_PEND))
 		return;
 
+	if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
+		unsigned long t = fcport->plogi_nack_done_jiff + HZ;
+
+		if (time_before_eq(jiffies, t))
+			return;
+	}
+
 	if (fcport->flags & FCF_ASYNC_SENT) {
 		fcport->login_retry++;
 		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 0fd3258..f1da53d 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1630,9 +1630,9 @@ static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
 		QLA_LOGIO_LOGIN_RETRIED : 0;
 	if (logio->entry_status) {
 		ql_log(ql_log_warn, fcport->vha, 0x5034,
-		    "Async-%s error entry - hdl=%x"
+		    "Async-%s error entry - %8phC hdl=%x"
 		    "portid=%02x%02x%02x entry-status=%x.\n",
-		    type, sp->handle, fcport->d_id.b.domain,
+		    type, fcport->port_name, sp->handle, fcport->d_id.b.domain,
 		    fcport->d_id.b.area, fcport->d_id.b.al_pa,
 		    logio->entry_status);
 		ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x504d,
@@ -1643,8 +1643,9 @@ static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
 
 	if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) {
 		ql_dbg(ql_dbg_async, fcport->vha, 0x5036,
-		    "Async-%s complete - hdl=%x portid=%02x%02x%02x "
-		    "iop0=%x.\n", type, sp->handle, fcport->d_id.b.domain,
+		    "Async-%s complete - %8phC hdl=%x portid=%02x%02x%02x "
+		    "iop0=%x.\n", type, fcport->port_name, sp->handle,
+		    fcport->d_id.b.domain,
 		    fcport->d_id.b.area, fcport->d_id.b.al_pa,
 		    le32_to_cpu(logio->io_parameter[0]));
 
@@ -1684,6 +1685,17 @@ static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
 	case LSC_SCODE_NPORT_USED:
 		data[0] = MBS_LOOP_ID_USED;
 		break;
+	case LSC_SCODE_CMD_FAILED:
+		if (iop[1] == 0x0606) {
+			/*
+			 * PLOGI/PRLI Completed. We must have Recv PLOGI/PRLI,
+			 * Target side acked.
+			 */
+			data[0] = MBS_COMMAND_COMPLETE;
+			goto logio_done;
+		}
+		data[0] = MBS_COMMAND_ERROR;
+		break;
 	case LSC_SCODE_NOXCB:
 		vha->hw->exch_starvation++;
 		if (vha->hw->exch_starvation > 5) {
@@ -1705,8 +1717,9 @@ static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
 	}
 
 	ql_dbg(ql_dbg_async, fcport->vha, 0x5037,
-	    "Async-%s failed - hdl=%x portid=%02x%02x%02x comp=%x "
-	    "iop0=%x iop1=%x.\n", type, sp->handle, fcport->d_id.b.domain,
+	    "Async-%s failed - %8phC hdl=%x portid=%02x%02x%02x comp=%x "
+	    "iop0=%x iop1=%x.\n", type, fcport->port_name,
+		sp->handle, fcport->d_id.b.domain,
 	    fcport->d_id.b.area, fcport->d_id.b.al_pa,
 	    le16_to_cpu(logio->comp_status),
 	    le32_to_cpu(logio->io_parameter[0]),
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 19ac2b5..8d21c04 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -554,6 +554,7 @@ void qla2x00_async_nack_sp_done(void *s, int res)
 		sp->fcport->login_gen++;
 		sp->fcport->fw_login_state = DSC_LS_PLOGI_COMP;
 		sp->fcport->logout_on_delete = 1;
+		sp->fcport->plogi_nack_done_jiff = jiffies;
 		break;
 
 	case SRB_NACK_PRLI:
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 03/14] qla2xxx: Allow vref count to timeout on vport delete.
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
  2017-02-03 22:40 ` [PATCH v2 01/14] qla2xxx: Fix delayed response to command for loop mode/direct connect Himanshu Madhani
  2017-02-03 22:40 ` [PATCH v2 02/14] qla2xxx: Allow relogin to proceed if remote login did not finish Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-08 13:03   ` Christoph Hellwig
  2017-02-03 22:40 ` [PATCH v2 04/14] qla2xxx: Use IOCB interface to submit non-critical MBX Himanshu Madhani
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

From: Joe Carnuccio <joe.carnuccio@cavium.com>

Signed-off-by: Joe Carnuccio <joe.carnuccio@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
---
 drivers/scsi/qla2xxx/qla_attr.c |  4 +---
 drivers/scsi/qla2xxx/qla_mid.c  | 12 +++++++-----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index f610103..435ff7f 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -2154,8 +2154,6 @@ struct device_attribute *qla2x00_host_attrs[] = {
 		    "Timer for the VP[%d] has stopped\n", vha->vp_idx);
 	}
 
-	BUG_ON(atomic_read(&vha->vref_count));
-
 	qla2x00_free_fcports(vha);
 
 	mutex_lock(&ha->vport_lock);
@@ -2166,7 +2164,7 @@ struct device_attribute *qla2x00_host_attrs[] = {
 	dma_free_coherent(&ha->pdev->dev, vha->gnl.size, vha->gnl.l,
 	    vha->gnl.ldma);
 
-	if (vha->qpair->vp_idx == vha->vp_idx) {
+	if (vha->qpair && vha->qpair->vp_idx == vha->vp_idx) {
 		if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS)
 			ql_log(ql_log_warn, vha, 0x7087,
 			    "Queue Pair delete failed.\n");
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index c6d6f0d..bf8e1e2 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -65,6 +65,7 @@
 	uint16_t vp_id;
 	struct qla_hw_data *ha = vha->hw;
 	unsigned long flags = 0;
+	unsigned int count = 10;
 
 	mutex_lock(&ha->vport_lock);
 	/*
@@ -74,13 +75,14 @@
 	 * ensures no active vp_list traversal while the vport is removed
 	 * from the queue)
 	 */
-	spin_lock_irqsave(&ha->vport_slock, flags);
-	while (atomic_read(&vha->vref_count)) {
-		spin_unlock_irqrestore(&ha->vport_slock, flags);
-
+	while (count-- && atomic_read(&vha->vref_count))
 		msleep(500);
 
-		spin_lock_irqsave(&ha->vport_slock, flags);
+	spin_lock_irqsave(&ha->vport_slock, flags);
+	if (atomic_read(&vha->vref_count)) {
+		ql_dbg(ql_dbg_vport, vha, 0xfffa,
+		    "vha->vref_count=%u timeout\n", vha->vref_count.counter);
+		vha->vref_count = (atomic_t)ATOMIC_INIT(0);
 	}
 	list_del(&vha->list);
 	qlt_update_vp_map(vha, RESET_VP_IDX);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 04/14] qla2xxx: Use IOCB interface to submit non-critical MBX.
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
                   ` (2 preceding siblings ...)
  2017-02-03 22:40 ` [PATCH v2 03/14] qla2xxx: Allow vref count to timeout on vport delete Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-08 18:48   ` Bart Van Assche
  2017-02-03 22:40 ` [PATCH v2 05/14] qla2xxx: Add DebugFS node to display Port Database Himanshu Madhani
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

From: Quinn Tran <quinn.tran@cavium.com>

The Mailbox interface is currently over subscribed. We like
to reserve the Mailbox interface for the chip managment and
link initialization. Any non essential Mailbox command will
be routed through the IOCB interface. The IOCB interface is
able to absorb more commands.

Following commands are being routed through IOCB interface

- Get ID List (007Ch)
- Get Port DB (0064h)
- Get Link Priv Stats (006Dh)

Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h    |   8 +-
 drivers/scsi/qla2xxx/qla_gbl.h    |  10 +-
 drivers/scsi/qla2xxx/qla_init.c   |  46 +------
 drivers/scsi/qla2xxx/qla_isr.c    |   2 +-
 drivers/scsi/qla2xxx/qla_mbx.c    | 273 ++++++++++++++++++++++++++++++++++++--
 drivers/scsi/qla2xxx/qla_target.c |   4 +-
 6 files changed, 279 insertions(+), 64 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index bf2ae8d3..f92977b 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -395,11 +395,15 @@ struct srb_iocb {
 			struct completion comp;
 		} abt;
 		struct ct_arg ctarg;
+#define MAX_IOCB_MB_REG 28
+#define SIZEOF_IOCB_MB_REG (MAX_IOCB_MB_REG * sizeof(uint16_t))
 		struct {
-			__le16 in_mb[28]; 	/* fr fw */
-			__le16 out_mb[28];	/* to fw */
+			__le16 in_mb[MAX_IOCB_MB_REG];	/* from FW */
+			__le16 out_mb[MAX_IOCB_MB_REG];	/* to FW */
 			void *out, *in;
 			dma_addr_t out_dma, in_dma;
+			struct completion comp;
+			int rc;
 		} mbx;
 		struct {
 			struct imm_ntfy_from_isp *ntfy;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 862d5f5..48a1190 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -194,6 +194,7 @@ void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *,
 	uint16_t *);
 int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *);
 void qla2x00_schedule_work(struct scsi_qla_host *);
+int qla24xx_async_abort_cmd(srb_t *);
 
 /*
  * Global Functions in qla_mid.c source file.
@@ -369,7 +370,7 @@ extern int qla24xx_build_scsi_crc_2_iocbs(srb_t *,
 
 extern int
 qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *,
-    dma_addr_t, uint);
+    dma_addr_t, uint16_t);
 
 extern int qla24xx_abort_command(srb_t *);
 extern int qla24xx_async_abort_command(srb_t *);
@@ -473,6 +474,13 @@ extern int qla24xx_set_fcp_prio(scsi_qla_host_t *, uint16_t, uint16_t,
 extern int
 qla26xx_dport_diagnostics(scsi_qla_host_t *, void *, uint, uint);
 
+int qla24xx_send_mb_cmd(struct scsi_qla_host *, mbx_cmd_t *);
+int qla24xx_gpdb_wait(struct scsi_qla_host *, fc_port_t *, u8);
+int qla24xx_gidlist_wait(struct scsi_qla_host *, void *, dma_addr_t,
+    uint16_t *);
+int __qla24xx_parse_gpdb(struct scsi_qla_host *, fc_port_t *,
+	struct port_database_24xx *);
+
 /*
  * Global Function Prototypes in qla_isr.c source file.
  */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index e84ab37..5aca3df 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -629,7 +629,6 @@ void qla24xx_async_gpdb_sp_done(void *s, int res)
 	struct srb *sp = s;
 	struct scsi_qla_host *vha = sp->vha;
 	struct qla_hw_data *ha = vha->hw;
-	uint64_t zero = 0;
 	struct port_database_24xx *pd;
 	fc_port_t *fcport = sp->fcport;
 	u16 *mb = sp->u.iocb_cmd.u.mbx.in_mb;
@@ -649,48 +648,7 @@ void qla24xx_async_gpdb_sp_done(void *s, int res)
 
 	pd = (struct port_database_24xx *)sp->u.iocb_cmd.u.mbx.in;
 
-	/* Check for logged in state. */
-	if (pd->current_login_state != PDS_PRLI_COMPLETE &&
-	    pd->last_login_state != PDS_PRLI_COMPLETE) {
-		ql_dbg(ql_dbg_mbx, vha, 0xffff,
-		    "Unable to verify login-state (%x/%x) for "
-		    "loop_id %x.\n", pd->current_login_state,
-		    pd->last_login_state, fcport->loop_id);
-		rval = QLA_FUNCTION_FAILED;
-		goto gpd_error_out;
-	}
-
-	if (fcport->loop_id == FC_NO_LOOP_ID ||
-	    (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
-		memcmp(fcport->port_name, pd->port_name, 8))) {
-		/* We lost the device mid way. */
-		rval = QLA_NOT_LOGGED_IN;
-		goto gpd_error_out;
-	}
-
-	/* Names are little-endian. */
-	memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
-
-	/* Get port_id of device. */
-	fcport->d_id.b.domain = pd->port_id[0];
-	fcport->d_id.b.area = pd->port_id[1];
-	fcport->d_id.b.al_pa = pd->port_id[2];
-	fcport->d_id.b.rsvd_1 = 0;
-
-	/* If not target must be initiator or unknown type. */
-	if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
-		fcport->port_type = FCT_INITIATOR;
-	else
-		fcport->port_type = FCT_TARGET;
-
-	/* Passback COS information. */
-	fcport->supported_classes = (pd->flags & PDF_CLASS_2) ?
-		FC_COS_CLASS2 : FC_COS_CLASS3;
-
-	if (pd->prli_svc_param_word_3[0] & BIT_7) {
-		fcport->flags |= FCF_CONF_COMP_SUPPORTED;
-		fcport->conf_compl_supported = 1;
-	}
+	rval = __qla24xx_parse_gpdb(vha, fcport, pd);
 
 gpd_error_out:
 	memset(&ea, 0, sizeof(ea));
@@ -1270,7 +1228,7 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
 	complete(&abt->u.abt.comp);
 }
 
-static int
+int
 qla24xx_async_abort_cmd(srb_t *cmd_sp)
 {
 	scsi_qla_host_t *vha = cmd_sp->vha;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index f1da53d..3c2599a 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -2702,7 +2702,7 @@ struct scsi_dif_tuple {
 		return;
 
 	abt = &sp->u.iocb_cmd;
-	abt->u.abt.comp_status = le32_to_cpu(pkt->nport_handle);
+	abt->u.abt.comp_status = le16_to_cpu(pkt->nport_handle);
 	sp->done(sp, 0);
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index db6bd92..4225256 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -10,6 +10,29 @@
 #include <linux/delay.h>
 #include <linux/gfp.h>
 
+static struct mb_cmd_name {
+	uint16_t cmd;
+	char *str;
+} mb_str[] = {
+	{0xffff,		"unknown"},
+	{MBC_GET_PORT_DATABASE,	"GPDB"},
+	{MBC_GET_ID_LIST,	"GIDList"},
+	{MBC_GET_LINK_PRIV_STATS, "Stats"},
+};
+
+static char *mb_to_str(uint16_t cmd)
+{
+	int i;
+	struct mb_cmd_name *e;
+
+	for (i = 0; i < ARRAY_SIZE(mb_str); i++) {
+		e = mb_str + i;
+		if (cmd == e->cmd)
+			return e->str;
+	}
+	return mb_str[0].str; /* unknown */
+}
+
 static struct rom_cmd {
 	uint16_t cmd;
 } rom_cmds[] = {
@@ -2818,7 +2841,7 @@ static int is_rom_cmd(uint16_t cmd)
 
 int
 qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
-    dma_addr_t stats_dma, uint options)
+    dma_addr_t stats_dma, uint16_t options)
 {
 	int rval;
 	mbx_cmd_t mc;
@@ -2828,19 +2851,17 @@ static int is_rom_cmd(uint16_t cmd)
 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088,
 	    "Entered %s.\n", __func__);
 
-	mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
-	mcp->mb[2] = MSW(stats_dma);
-	mcp->mb[3] = LSW(stats_dma);
-	mcp->mb[6] = MSW(MSD(stats_dma));
-	mcp->mb[7] = LSW(MSD(stats_dma));
-	mcp->mb[8] = sizeof(struct link_statistics) / 4;
-	mcp->mb[9] = vha->vp_idx;
-	mcp->mb[10] = options;
-	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
-	mcp->in_mb = MBX_2|MBX_1|MBX_0;
-	mcp->tov = MBX_TOV_SECONDS;
-	mcp->flags = IOCTL_CMD;
-	rval = qla2x00_mailbox_command(vha, mcp);
+	memset(&mc, 0, sizeof(mc));
+	mc.mb[0] = MBC_GET_LINK_PRIV_STATS;
+	mc.mb[2] = MSW(stats_dma);
+	mc.mb[3] = LSW(stats_dma);
+	mc.mb[6] = MSW(MSD(stats_dma));
+	mc.mb[7] = LSW(MSD(stats_dma));
+	mc.mb[8] = sizeof(struct link_statistics) / 4;
+	mc.mb[9] = cpu_to_le16(vha->vp_idx);
+	mc.mb[10] = cpu_to_le16(options);
+
+	rval = qla24xx_send_mb_cmd(vha, &mc);
 
 	if (rval == QLA_SUCCESS) {
 		if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
@@ -5827,3 +5848,227 @@ struct cs84xx_mgmt_cmd {
 
 	return rval;
 }
+
+static void qla2x00_async_mb_sp_done(void *s, int res)
+{
+	struct srb *sp = s;
+
+	sp->u.iocb_cmd.u.mbx.rc = res;
+
+	complete(&sp->u.iocb_cmd.u.mbx.comp);
+	/* don't free sp here. Let the caller do the free */
+}
+
+/*
+ * This mailbox uses the iocb interface to send MB command.
+ * This allows non-critial (non chip setup) command to go
+ * out in parrallel.
+ */
+int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp)
+{
+	int rval = QLA_FUNCTION_FAILED;
+	srb_t *sp;
+	struct srb_iocb *c;
+	char *name;
+
+	if (!vha->hw->flags.fw_started)
+		goto done;
+
+	sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
+	if (!sp)
+		goto done;
+
+	sp->type = SRB_MB_IOCB;
+	sp->name = mb_to_str(mcp->mb[0]);
+	name = sp->name;
+
+	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
+	memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG);
+
+	c = &sp->u.iocb_cmd;
+	c->timeout = qla2x00_async_iocb_timeout;
+	init_completion(&c->u.mbx.comp);
+
+	sp->done = qla2x00_async_mb_sp_done;
+
+	rval = qla2x00_start_sp(sp);
+	if (rval != QLA_SUCCESS) {
+		ql_dbg(ql_dbg_mbx, vha, 0xffff,
+		    "%s: %s Failed submission. %x.\n",
+		    __func__, sp->name, rval);
+		goto done_free_sp;
+	}
+
+	ql_dbg(ql_dbg_mbx, vha, 0xffff, "MB:%s hndl %x submitted\n",
+	    sp->name, sp->handle);
+
+	wait_for_completion(&c->u.mbx.comp);
+	memcpy(mcp->mb, sp->u.iocb_cmd.u.mbx.in_mb, SIZEOF_IOCB_MB_REG);
+
+	rval = c->u.mbx.rc;
+	switch (rval) {
+	case QLA_FUNCTION_TIMEOUT:
+		ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %s Timeout. %x.\n",
+		    __func__, name, rval);
+		break;
+	case  QLA_SUCCESS:
+		ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %s done.\n",
+		    __func__, sp->name);
+		sp->free(sp);
+		break;
+	default:
+		ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %s Failed. %x.\n",
+		    __func__, sp->name, rval);
+		sp->free(sp);
+		break;
+	}
+
+	return rval;
+
+done_free_sp:
+	sp->free(sp);
+done:
+	return rval;
+}
+
+/*
+ * qla24xx_gpdb_wait
+ * NOTE: Do not call this routine from DPC thread
+ */
+int qla24xx_gpdb_wait(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
+{
+	int rval = QLA_FUNCTION_FAILED;
+	dma_addr_t pd_dma;
+	struct port_database_24xx *pd;
+	struct qla_hw_data *ha = vha->hw;
+	mbx_cmd_t mc;
+
+	if (!vha->hw->flags.fw_started)
+		goto done;
+
+	pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
+	if (pd  == NULL) {
+		ql_log(ql_log_warn, vha, 0xffff,
+			"Failed to allocate port database structure.\n");
+		goto done_free_sp;
+	}
+	memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
+
+	memset(&mc, 0, sizeof(mc));
+	mc.mb[0] = MBC_GET_PORT_DATABASE;
+	mc.mb[1] = cpu_to_le16(fcport->loop_id);
+	mc.mb[2] = MSW(pd_dma);
+	mc.mb[3] = LSW(pd_dma);
+	mc.mb[6] = MSW(MSD(pd_dma));
+	mc.mb[7] = LSW(MSD(pd_dma));
+	mc.mb[9] = cpu_to_le16(vha->vp_idx);
+	mc.mb[10] = cpu_to_le16((uint16_t)opt);
+
+	rval = qla24xx_send_mb_cmd(vha, &mc);
+	if (rval != QLA_SUCCESS) {
+		ql_dbg(ql_dbg_mbx, vha, 0xffff,
+		    "%s: %8phC fail\n", __func__, fcport->port_name);
+		goto done_free_sp;
+	}
+
+	rval = __qla24xx_parse_gpdb(vha, fcport, pd);
+
+	ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %8phC done\n",
+	    __func__, fcport->port_name);
+
+done_free_sp:
+	if (pd)
+		dma_pool_free(ha->s_dma_pool, pd, pd_dma);
+done:
+	return rval;
+}
+
+int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport,
+    struct port_database_24xx *pd)
+{
+	int rval = QLA_SUCCESS;
+	uint64_t zero = 0;
+
+	/* Check for logged in state. */
+	if (pd->current_login_state != PDS_PRLI_COMPLETE &&
+		pd->last_login_state != PDS_PRLI_COMPLETE) {
+		ql_dbg(ql_dbg_mbx, vha, 0xffff,
+			   "Unable to verify login-state (%x/%x) for "
+			   "loop_id %x.\n", pd->current_login_state,
+			   pd->last_login_state, fcport->loop_id);
+		rval = QLA_FUNCTION_FAILED;
+		goto gpd_error_out;
+	}
+
+	if (fcport->loop_id == FC_NO_LOOP_ID ||
+	    (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
+	     memcmp(fcport->port_name, pd->port_name, 8))) {
+		/* We lost the device mid way. */
+		rval = QLA_NOT_LOGGED_IN;
+		goto gpd_error_out;
+	}
+
+	/* Names are little-endian. */
+	memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
+	memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
+
+	/* Get port_id of device. */
+	fcport->d_id.b.domain = pd->port_id[0];
+	fcport->d_id.b.area = pd->port_id[1];
+	fcport->d_id.b.al_pa = pd->port_id[2];
+	fcport->d_id.b.rsvd_1 = 0;
+
+	/* If not target must be initiator or unknown type. */
+	if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
+		fcport->port_type = FCT_INITIATOR;
+	else
+		fcport->port_type = FCT_TARGET;
+
+	/* Passback COS information. */
+	fcport->supported_classes = (pd->flags & PDF_CLASS_2) ?
+		FC_COS_CLASS2 : FC_COS_CLASS3;
+
+	if (pd->prli_svc_param_word_3[0] & BIT_7) {
+		fcport->flags |= FCF_CONF_COMP_SUPPORTED;
+		fcport->conf_compl_supported = 1;
+	}
+
+gpd_error_out:
+	return rval;
+}
+
+/*
+ * qla24xx_gidlist__wait
+ * NOTE: don't call this routine from DPC thread.
+ */
+int qla24xx_gidlist_wait(struct scsi_qla_host *vha,
+	void *id_list, dma_addr_t id_list_dma, uint16_t *entries)
+{
+	int rval = QLA_FUNCTION_FAILED;
+	mbx_cmd_t mc;
+
+	if (!vha->hw->flags.fw_started)
+		goto done;
+
+	memset(&mc, 0, sizeof(mc));
+	mc.mb[0] = MBC_GET_ID_LIST;
+	mc.mb[2] = MSW(id_list_dma);
+	mc.mb[3] = LSW(id_list_dma);
+	mc.mb[6] = MSW(MSD(id_list_dma));
+	mc.mb[7] = LSW(MSD(id_list_dma));
+	mc.mb[8] = 0;
+	mc.mb[9] = cpu_to_le16(vha->vp_idx);
+
+	rval = qla24xx_send_mb_cmd(vha, &mc);
+	if (rval != QLA_SUCCESS) {
+		ql_dbg(ql_dbg_mbx, vha, 0xffff,
+			"%s:  fail\n", __func__);
+	} else {
+		*entries = mc.mb[1];
+		ql_dbg(ql_dbg_mbx, vha, 0xffff,
+			"%s:  done\n", __func__);
+	}
+done:
+	return rval;
+}
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 8d21c04..a4cc14b 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1217,7 +1217,7 @@ static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id,
 	}
 
 	/* Get list of logged in devices */
-	rc = qla2x00_get_id_list(vha, gid_list, gid_list_dma, &entries);
+	rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma, &entries);
 	if (rc != QLA_SUCCESS) {
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf045,
 		    "qla_target(%d): get_id_list() failed: %x\n",
@@ -5524,7 +5524,7 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha,
 
 	fcport->loop_id = loop_id;
 
-	rc = qla2x00_get_port_database(vha, fcport, 0);
+	rc = qla24xx_gpdb_wait(vha, fcport, 0);
 	if (rc != QLA_SUCCESS) {
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf070,
 		    "qla_target(%d): Failed to retrieve fcport "
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 05/14] qla2xxx: Add DebugFS node to display Port Database
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
                   ` (3 preceding siblings ...)
  2017-02-03 22:40 ` [PATCH v2 04/14] qla2xxx: Use IOCB interface to submit non-critical MBX Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-03 22:40 ` [PATCH v2 06/14] qla2xxx: Improve T10-DIF/PI handling in driver Himanshu Madhani
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Giridhar Malavali <giridhar.malavali@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h |  2 +
 drivers/scsi/qla2xxx/qla_dfs.c | 92 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 90 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index f92977b..8bc1111 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3278,6 +3278,8 @@ struct qlt_hw_data {
 	uint8_t tgt_node_name[WWN_SIZE];
 
 	struct dentry *dfs_tgt_sess;
+	struct dentry *dfs_tgt_port_database;
+
 	struct list_head q_full_list;
 	uint32_t num_pend_cmds;
 	uint32_t num_qfull_cmds_alloc;
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index b48cce6..0fb33e6 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -19,11 +19,11 @@
 	struct qla_hw_data *ha = vha->hw;
 	unsigned long flags;
 	struct fc_port *sess = NULL;
-	struct qla_tgt *tgt= vha->vha_tgt.qla_tgt;
+	struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
 
-	seq_printf(s, "%s\n",vha->host_str);
+	seq_printf(s, "%s\n", vha->host_str);
 	if (tgt) {
-		seq_printf(s, "Port ID   Port Name                Handle\n");
+		seq_puts(s, "Port ID   Port Name                Handle\n");
 
 		spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 		list_for_each_entry(sess, &vha->vp_fcports, list)
@@ -44,7 +44,6 @@
 	return single_open(file, qla2x00_dfs_tgt_sess_show, vha);
 }
 
-
 static const struct file_operations dfs_tgt_sess_ops = {
 	.open		= qla2x00_dfs_tgt_sess_open,
 	.read		= seq_read,
@@ -53,6 +52,78 @@
 };
 
 static int
+qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused)
+{
+	scsi_qla_host_t *vha = s->private;
+	struct qla_hw_data *ha = vha->hw;
+	struct gid_list_info *gid_list;
+	dma_addr_t gid_list_dma;
+	fc_port_t fc_port;
+	char *id_iter;
+	int rc, i;
+	uint16_t entries, loop_id;
+	struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
+
+	seq_printf(s, "%s\n", vha->host_str);
+	if (tgt) {
+		gid_list = dma_alloc_coherent(&ha->pdev->dev,
+		    qla2x00_gid_list_size(ha),
+		    &gid_list_dma, GFP_KERNEL);
+		if (!gid_list) {
+			ql_dbg(ql_dbg_user, vha, 0x705c,
+			    "DMA allocation failed for %u\n",
+			     qla2x00_gid_list_size(ha));
+			return 0;
+		}
+
+		rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma,
+		    &entries);
+		if (rc != QLA_SUCCESS)
+			goto out_free_id_list;
+
+		id_iter = (char *)gid_list;
+
+		seq_puts(s, "Port Name	Port ID 	Loop ID\n");
+
+		for (i = 0; i < entries; i++) {
+			struct gid_list_info *gid =
+			    (struct gid_list_info *)id_iter;
+			loop_id = le16_to_cpu(gid->loop_id);
+			memset(&fc_port, 0, sizeof(fc_port_t));
+
+			fc_port.loop_id = loop_id;
+
+			rc = qla24xx_gpdb_wait(vha, &fc_port, 0);
+			seq_printf(s, "%8phC  %02x%02x%02x  %d\n",
+				fc_port.port_name, fc_port.d_id.b.domain,
+				fc_port.d_id.b.area, fc_port.d_id.b.al_pa,
+				fc_port.loop_id);
+			id_iter += ha->gid_list_info_size;
+		}
+out_free_id_list:
+		dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha),
+		    gid_list, gid_list_dma);
+	}
+
+	return 0;
+}
+
+static int
+qla2x00_dfs_tgt_port_database_open(struct inode *inode, struct file *file)
+{
+	scsi_qla_host_t *vha = inode->i_private;
+
+	return single_open(file, qla2x00_dfs_tgt_port_database_show, vha);
+}
+
+static const struct file_operations dfs_tgt_port_database_ops = {
+	.open		= qla2x00_dfs_tgt_port_database_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int
 qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
 {
 	struct scsi_qla_host *vha = s->private;
@@ -281,6 +352,14 @@
 		goto out;
 	}
 
+	ha->tgt.dfs_tgt_port_database = debugfs_create_file("tgt_port_database",
+	    S_IRUSR,  ha->dfs_dir, vha, &dfs_tgt_port_database_ops);
+	if (!ha->tgt.dfs_tgt_port_database) {
+		ql_log(ql_log_warn, vha, 0xffff,
+		    "Unable to create debugFS tgt_port_database node.\n");
+		goto out;
+	}
+
 	ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
 	    &dfs_fce_ops);
 	if (!ha->dfs_fce) {
@@ -311,6 +390,11 @@
 		ha->tgt.dfs_tgt_sess = NULL;
 	}
 
+	if (ha->tgt.dfs_tgt_port_database) {
+		debugfs_remove(ha->tgt.dfs_tgt_port_database);
+		ha->tgt.dfs_tgt_port_database = NULL;
+	}
+
 	if (ha->dfs_fw_resource_cnt) {
 		debugfs_remove(ha->dfs_fw_resource_cnt);
 		ha->dfs_fw_resource_cnt = NULL;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 06/14] qla2xxx: Improve T10-DIF/PI handling in driver.
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
                   ` (4 preceding siblings ...)
  2017-02-03 22:40 ` [PATCH v2 05/14] qla2xxx: Add DebugFS node to display Port Database Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-08  4:13   ` Nicholas A. Bellinger
  2017-02-08 18:57   ` Bart Van Assche
  2017-02-03 22:40 ` [PATCH v2 07/14] qla2xxx: Export DIF stats via debugfs Himanshu Madhani
                   ` (8 subsequent siblings)
  14 siblings, 2 replies; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

From: Quinn Tran <quinn.tran@cavium.com>

Add routines to support T10 DIF tag.

Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Anil Gurumurthy <anil.gurumurthy@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
---
 drivers/scsi/qla2xxx/qla_dbg.h     |   1 +
 drivers/scsi/qla2xxx/qla_def.h     |  17 ++
 drivers/scsi/qla2xxx/qla_target.c  | 598 +++++++++++++++++++++----------------
 drivers/scsi/qla2xxx/qla_target.h  |  37 ++-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  84 +++++-
 5 files changed, 465 insertions(+), 272 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index e1fc4e6..c6bffe9 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -348,6 +348,7 @@ void __attribute__((format (printf, 4, 5)))
 #define ql_dbg_tgt	0x00004000 /* Target mode */
 #define ql_dbg_tgt_mgt	0x00002000 /* Target mode management */
 #define ql_dbg_tgt_tmr	0x00001000 /* Target mode task management */
+#define ql_dbg_tgt_dif  0x00000800 /* Target mode dif */
 
 extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *,
 	uint32_t, void **);
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 8bc1111..d6436fc 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2189,6 +2189,23 @@ struct qlt_plogi_ack_t {
 	void		*fcport;
 };
 
+enum qla_tgt_prot_op {
+	QLA_PROT_NORMAL  = 0,
+	QLA_PROT_DIN_INSERT,
+	QLA_PROT_DOUT_INSERT,
+	QLA_PROT_DIN_STRIP,
+	QLA_PROT_DOUT_STRIP,
+	QLA_PROT_DIN_PASS,
+	QLA_PROT_DOUT_PASS,
+};
+
+enum qla_tgt_prot_type {
+	QLA_TGT_PROT_TYPE0,
+	QLA_TGT_PROT_TYPE1,
+	QLA_TGT_PROT_TYPE2,
+	QLA_TGT_PROT_TYPE3,
+};
+
 struct ct_sns_desc {
 	struct ct_sns_pkt	*ct_sns;
 	dma_addr_t		ct_sns_dma;
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index a4cc14b..a36258d 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -36,8 +36,6 @@
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
-#include <target/target_core_base.h>
-#include <target/target_core_fabric.h>
 
 #include "qla_def.h"
 #include "qla_target.h"
@@ -140,6 +138,20 @@ static struct fc_port *qlt_create_sess(struct scsi_qla_host *vha,
 static DEFINE_MUTEX(qla_tgt_mutex);
 static LIST_HEAD(qla_tgt_glist);
 
+static char *prot_op_str(u32 prot_op)
+{
+	switch (prot_op) {
+	case QLA_PROT_NORMAL:		return "NORMAL";
+	case QLA_PROT_DIN_INSERT:	return "DIN_INSERT";
+	case QLA_PROT_DOUT_INSERT:	return "DOUT_INSERT";
+	case QLA_PROT_DIN_STRIP:	return "DIN_STRIP";
+	case QLA_PROT_DOUT_STRIP:	return "DOUT_STRIP";
+	case QLA_PROT_DIN_PASS:		return "DIN_PASS";
+	case QLA_PROT_DOUT_PASS:	return "DOUT_PASS";
+	default:			return "UNKNOWN";
+	}
+}
+
 /* This API intentionally takes dest as a parameter, rather than returning
  * int value to avoid caller forgetting to issue wmb() after the store */
 void qlt_do_generation_tick(struct scsi_qla_host *vha, int *dest)
@@ -1997,6 +2009,68 @@ void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd)
 }
 EXPORT_SYMBOL(qlt_free_mcmd);
 
+/*
+ * ha->hardware_lock supposed to be held on entry. Might drop it, then
+ * reacquire
+ */
+void qlt_send_resp_ctio(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
+    uint8_t scsi_status, uint8_t sense_key, uint8_t asc, uint8_t ascq)
+{
+	struct atio_from_isp *atio = &cmd->atio;
+	struct ctio7_to_24xx *ctio;
+	uint16_t temp;
+
+	ql_dbg(ql_dbg_tgt_dif, vha, 0x3066,
+	    "Sending response CTIO7 (vha=%p, atio=%p, scsi_status=%02x, "
+	    "sense_key=%02x, asc=%02x, ascq=%02x",
+	    vha, atio, scsi_status, sense_key, asc, ascq);
+
+	ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs(vha, NULL);
+	if (!ctio) {
+		ql_dbg(ql_dbg_async, vha, 0x3067,
+		    "qla2x00t(%ld): %s failed: unable to allocate request packet",
+		    vha->host_no, __func__);
+		goto out;
+	}
+
+	ctio->entry_type = CTIO_TYPE7;
+	ctio->entry_count = 1;
+	ctio->handle = QLA_TGT_SKIP_HANDLE;
+	ctio->nport_handle = cmd->sess->loop_id;
+	ctio->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
+	ctio->vp_index = vha->vp_idx;
+	ctio->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
+	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 = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
+	ctio->u.status1.ox_id = cpu_to_le16(temp);
+	ctio->u.status1.scsi_status =
+	    cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID | scsi_status);
+	ctio->u.status1.response_len = cpu_to_le16(18);
+	ctio->u.status1.residual = cpu_to_le32(get_datalen_for_atio(atio));
+
+	if (ctio->u.status1.residual != 0)
+		ctio->u.status1.scsi_status |=
+		    cpu_to_le16(SS_RESIDUAL_UNDER);
+	/* Response code and sense key */
+	((uint32_t *)ctio->u.status1.sense_data)[0] =
+	    cpu_to_le32((0x70 << 24) | (sense_key << 8));
+	/* Additional sense length */
+	((uint32_t *)ctio->u.status1.sense_data)[1] = cpu_to_le32(0x0a);
+	/* ASC and ASCQ */
+	((uint32_t *)ctio->u.status1.sense_data)[3] =
+	    cpu_to_le32((asc << 24) | (ascq << 16));
+
+	/* Memory Barrier */
+	wmb();
+	qla2x00_start_iocbs(vha, vha->req);
+out:
+	return;
+}
+
 /* callback from target fabric module code */
 void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
 {
@@ -2076,7 +2150,7 @@ static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm)
 
 	prm->cmd->sg_mapped = 1;
 
-	if (cmd->se_cmd.prot_op == TARGET_PROT_NORMAL) {
+	if (cmd->prot_op == QLA_PROT_NORMAL) {
 		/*
 		 * If greater than four sg entries then we need to allocate
 		 * the continuation entries
@@ -2087,8 +2161,8 @@ static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm)
 			prm->tgt->datasegs_per_cont);
 	} else {
 		/* DIF */
-		if ((cmd->se_cmd.prot_op == TARGET_PROT_DIN_INSERT) ||
-		    (cmd->se_cmd.prot_op == TARGET_PROT_DOUT_STRIP)) {
+		if ((cmd->prot_op == QLA_PROT_DIN_INSERT) ||
+		    (cmd->prot_op == QLA_PROT_DOUT_STRIP)) {
 			prm->seg_cnt = DIV_ROUND_UP(cmd->bufflen, cmd->blk_sz);
 			prm->tot_dsds = prm->seg_cnt;
 		} else
@@ -2102,8 +2176,8 @@ static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm)
 			if (unlikely(prm->prot_seg_cnt == 0))
 				goto out_err;
 
-			if ((cmd->se_cmd.prot_op == TARGET_PROT_DIN_INSERT) ||
-			    (cmd->se_cmd.prot_op == TARGET_PROT_DOUT_STRIP)) {
+			if ((cmd->prot_op == QLA_PROT_DIN_INSERT) ||
+			    (cmd->prot_op == QLA_PROT_DOUT_STRIP)) {
 				/* Dif Bundling not support here */
 				prm->prot_seg_cnt = DIV_ROUND_UP(cmd->bufflen,
 								cmd->blk_sz);
@@ -2247,7 +2321,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm,
 	} else
 		ha->tgt.cmds[h-1] = prm->cmd;
 
-	pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK;
+	pkt->handle = CTIO_COMPLETION_HANDLE_MARK;
 	pkt->nport_handle = prm->cmd->loop_id;
 	pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
 	pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
@@ -2375,6 +2449,50 @@ static inline int qlt_has_data(struct qla_tgt_cmd *cmd)
 	return cmd->bufflen > 0;
 }
 
+static void qlt_print_dif_err(struct qla_tgt_prm *prm)
+{
+	struct qla_tgt_cmd *cmd;
+	struct scsi_qla_host *vha;
+
+	/* asc 0x10=dif error */
+	if (prm->sense_buffer && (prm->sense_buffer[12] == 0x10)) {
+		cmd = prm->cmd;
+		vha = cmd->vha;
+		/* ASCQ */
+		switch (prm->sense_buffer[13]) {
+		case 1:
+			ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
+			    "BE detected Guard TAG ERR: lba[0x%llx|%lld] len[0x%x] "
+			    "se_cmd=%p tag[%x]",
+			    cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd,
+			    cmd->atio.u.isp24.exchange_addr);
+			break;
+		case 2:
+			ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
+			    "BE detected APP TAG ERR: lba[0x%llx|%lld] len[0x%x] "
+			    "se_cmd=%p tag[%x]",
+			    cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd,
+			    cmd->atio.u.isp24.exchange_addr);
+			break;
+		case 3:
+			ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
+			    "BE detected REF TAG ERR: lba[0x%llx|%lld] len[0x%x] "
+			    "se_cmd=%p tag[%x]",
+			    cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd,
+			    cmd->atio.u.isp24.exchange_addr);
+			break;
+		default:
+			ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
+			    "BE detected Dif ERR: lba[%llx|%lld] len[%x] "
+			    "se_cmd=%p tag[%x]",
+			    cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd,
+			    cmd->atio.u.isp24.exchange_addr);
+			break;
+		}
+		ql_dump_buffer(ql_dbg_tgt_dif, vha, 0xffff, cmd->cdb, 16);
+	}
+}
+
 /*
  * Called without ha->hardware_lock held
  */
@@ -2496,18 +2614,9 @@ static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
 		for (i = 0; i < prm->sense_buffer_len/4; i++)
 			((uint32_t *)ctio->u.status1.sense_data)[i] =
 				cpu_to_be32(((uint32_t *)prm->sense_buffer)[i]);
-#if 0
-		if (unlikely((prm->sense_buffer_len % 4) != 0)) {
-			static int q;
-			if (q < 10) {
-				ql_dbg(ql_dbg_tgt, vha, 0xe04f,
-				    "qla_target(%d): %d bytes of sense "
-				    "lost", prm->tgt->ha->vp_idx,
-				    prm->sense_buffer_len % 4);
-				q++;
-			}
-		}
-#endif
+
+		qlt_print_dif_err(prm);
+
 	} else {
 		ctio->u.status1.flags &=
 		    ~cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_0);
@@ -2521,32 +2630,22 @@ static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
 	/* Sense with len > 24, is it possible ??? */
 }
 
-
-
-/* diff  */
 static inline int
-qlt_hba_err_chk_enabled(struct se_cmd *se_cmd)
+qlt_hba_err_chk_enabled(struct qla_tgt_cmd *cmd)
 {
-	/*
-	 * Uncomment when corresponding SCSI changes are done.
-	 *
-	 if (!sp->cmd->prot_chk)
-	 return 0;
-	 *
-	 */
-	switch (se_cmd->prot_op) {
-	case TARGET_PROT_DOUT_INSERT:
-	case TARGET_PROT_DIN_STRIP:
+	switch (cmd->prot_op) {
+	case QLA_PROT_DOUT_INSERT:
+	case QLA_PROT_DIN_STRIP:
 		if (ql2xenablehba_err_chk >= 1)
 			return 1;
 		break;
-	case TARGET_PROT_DOUT_PASS:
-	case TARGET_PROT_DIN_PASS:
+	case QLA_PROT_DOUT_PASS:
+	case QLA_PROT_DIN_PASS:
 		if (ql2xenablehba_err_chk >= 2)
 			return 1;
 		break;
-	case TARGET_PROT_DIN_INSERT:
-	case TARGET_PROT_DOUT_STRIP:
+	case QLA_PROT_DIN_INSERT:
+	case QLA_PROT_DOUT_STRIP:
 		return 1;
 	default:
 		break;
@@ -2554,16 +2653,39 @@ static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
 	return 0;
 }
 
+static inline int
+qla_tgt_ref_mask_check(struct qla_tgt_cmd *cmd)
+{
+	switch (cmd->prot_op) {
+	case QLA_PROT_DIN_INSERT:
+	case QLA_PROT_DOUT_INSERT:
+	case QLA_PROT_DIN_STRIP:
+	case QLA_PROT_DOUT_STRIP:
+	case QLA_PROT_DIN_PASS:
+	case QLA_PROT_DOUT_PASS:
+	    return 1;
+	default:
+	    return 0;
+	}
+
+	return 0;
+}
+
 /*
- * qla24xx_set_t10dif_tags_from_cmd - Extract Ref and App tags from SCSI command
- *
+ * qla_tgt_set_dif_tags - Extract Ref and App tags from SCSI command
  */
-static inline void
-qlt_set_t10dif_tags(struct se_cmd *se_cmd, struct crc_context *ctx)
+static void
+qla_tgt_set_dif_tags(struct qla_tgt_cmd *cmd, struct crc_context *ctx,
+    uint16_t *pfw_prot_opts)
 {
+	struct se_cmd *se_cmd = &cmd->se_cmd;
 	uint32_t lba = 0xffffffff & se_cmd->t_task_lba;
+	scsi_qla_host_t *vha = cmd->tgt->vha;
+	struct qla_hw_data *ha = vha->hw;
+	uint32_t t32 = 0;
 
-	/* wait til Mode Sense/Select cmd, modepage Ah, subpage 2
+	/*
+	 * wait til Mode Sense/Select cmd, modepage Ah, subpage 2
 	 * have been immplemented by TCM, before AppTag is avail.
 	 * Look for modesense_handlers[]
 	 */
@@ -2571,65 +2693,73 @@ static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
 	ctx->app_tag_mask[0] = 0x0;
 	ctx->app_tag_mask[1] = 0x0;
 
-	switch (se_cmd->prot_type) {
-	case TARGET_DIF_TYPE0_PROT:
-		/*
-		 * No check for ql2xenablehba_err_chk, as it would be an
-		 * I/O error if hba tag generation is not done.
-		 */
-		ctx->ref_tag = cpu_to_le32(lba);
-
-		if (!qlt_hba_err_chk_enabled(se_cmd))
-			break;
-
-		/* enable ALL bytes of the ref tag */
-		ctx->ref_tag_mask[0] = 0xff;
-		ctx->ref_tag_mask[1] = 0xff;
-		ctx->ref_tag_mask[2] = 0xff;
-		ctx->ref_tag_mask[3] = 0xff;
-		break;
-	/*
-	 * For TYpe 1 protection: 16 bit GUARD tag, 32 bit REF tag, and
-	 * 16 bit app tag.
-	 */
-	case TARGET_DIF_TYPE1_PROT:
-		ctx->ref_tag = cpu_to_le32(lba);
+	if (IS_PI_UNINIT_CAPABLE(ha)) {
+		if ((cmd->prot_type == QLA_TGT_PROT_TYPE1) ||
+		    (cmd->prot_type == QLA_TGT_PROT_TYPE2))
+			*pfw_prot_opts |= PO_DIS_VALD_APP_ESC;
+		else if (cmd->prot_type == QLA_TGT_PROT_TYPE3)
+			*pfw_prot_opts |= PO_DIS_VALD_APP_REF_ESC;
+	}
 
-		if (!qlt_hba_err_chk_enabled(se_cmd))
-			break;
+	t32 = ha->tgt.tgt_ops->get_dif_tags(cmd, pfw_prot_opts);
 
-		/* enable ALL bytes of the ref tag */
-		ctx->ref_tag_mask[0] = 0xff;
-		ctx->ref_tag_mask[1] = 0xff;
-		ctx->ref_tag_mask[2] = 0xff;
-		ctx->ref_tag_mask[3] = 0xff;
-		break;
-	/*
-	 * For TYPE 2 protection: 16 bit GUARD + 32 bit REF tag has to
-	 * match LBA in CDB + N
-	 */
-	case TARGET_DIF_TYPE2_PROT:
+	switch (cmd->prot_type) {
+	case QLA_TGT_PROT_TYPE0:
+		/*
+		 * No check for ql2xenablehba_err_chk, as it
+		 * would be an I/O error if hba tag generation
+		 * is not done.
+		 */
 		ctx->ref_tag = cpu_to_le32(lba);
-
-		if (!qlt_hba_err_chk_enabled(se_cmd))
-			break;
-
 		/* enable ALL bytes of the ref tag */
 		ctx->ref_tag_mask[0] = 0xff;
 		ctx->ref_tag_mask[1] = 0xff;
 		ctx->ref_tag_mask[2] = 0xff;
 		ctx->ref_tag_mask[3] = 0xff;
 		break;
-
-	/* For Type 3 protection: 16 bit GUARD only */
-	case TARGET_DIF_TYPE3_PROT:
-		ctx->ref_tag_mask[0] = ctx->ref_tag_mask[1] =
-			ctx->ref_tag_mask[2] = ctx->ref_tag_mask[3] = 0x00;
-		break;
+	case QLA_TGT_PROT_TYPE1:
+	    /*
+	     * For TYPE 1 protection: 16 bit GUARD tag, 32 bit
+	     * REF tag, and 16 bit app tag.
+	     */
+	    ctx->ref_tag = cpu_to_le32(lba);
+	    if (!qla_tgt_ref_mask_check(cmd) ||
+		!(ha->tgt.tgt_ops->chk_dif_tags(t32))) {
+		    *pfw_prot_opts |= PO_DIS_REF_TAG_VALD;
+		    break;
+	    }
+	    /* enable ALL bytes of the ref tag */
+	    ctx->ref_tag_mask[0] = 0xff;
+	    ctx->ref_tag_mask[1] = 0xff;
+	    ctx->ref_tag_mask[2] = 0xff;
+	    ctx->ref_tag_mask[3] = 0xff;
+	    break;
+	case QLA_TGT_PROT_TYPE2:
+	    /*
+	     * For TYPE 2 protection: 16 bit GUARD + 32 bit REF
+	     * tag has to match LBA in CDB + N
+	     */
+	    ctx->ref_tag = cpu_to_le32(lba);
+	    if (!qla_tgt_ref_mask_check(cmd) ||
+		!(ha->tgt.tgt_ops->chk_dif_tags(t32))) {
+		    *pfw_prot_opts |= PO_DIS_REF_TAG_VALD;
+		    break;
+	    }
+	    /* enable ALL bytes of the ref tag */
+	    ctx->ref_tag_mask[0] = 0xff;
+	    ctx->ref_tag_mask[1] = 0xff;
+	    ctx->ref_tag_mask[2] = 0xff;
+	    ctx->ref_tag_mask[3] = 0xff;
+	    break;
+	case QLA_TGT_PROT_TYPE3:
+	    /* For TYPE 3 protection: 16 bit GUARD only */
+	    *pfw_prot_opts |= PO_DIS_REF_TAG_VALD;
+	    ctx->ref_tag_mask[0] = ctx->ref_tag_mask[1] =
+		ctx->ref_tag_mask[2] = ctx->ref_tag_mask[3] = 0x00;
+	    break;
 	}
 }
 
-
 static inline int
 qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha)
 {
@@ -2658,28 +2788,28 @@ static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
 
 	ql_dbg(ql_dbg_tgt, vha, 0xe071,
 		"qla_target(%d):%s: se_cmd[%p] CRC2 prot_op[0x%x] cmd prot sg:cnt[%p:%x] lba[%llu]\n",
-		vha->vp_idx, __func__, se_cmd, se_cmd->prot_op,
+		vha->vp_idx, __func__, se_cmd, cmd->prot_op,
 		prm->prot_sg, prm->prot_seg_cnt, se_cmd->t_task_lba);
 
-	if ((se_cmd->prot_op == TARGET_PROT_DIN_INSERT) ||
-	    (se_cmd->prot_op == TARGET_PROT_DOUT_STRIP))
+	if ((cmd->prot_op == QLA_PROT_DIN_INSERT) ||
+	    (cmd->prot_op == QLA_PROT_DOUT_STRIP))
 		bundling = 0;
 
 	/* Compute dif len and adjust data len to incude protection */
 	data_bytes = cmd->bufflen;
 	dif_bytes  = (data_bytes / cmd->blk_sz) * 8;
 
-	switch (se_cmd->prot_op) {
-	case TARGET_PROT_DIN_INSERT:
-	case TARGET_PROT_DOUT_STRIP:
+	switch (cmd->prot_op) {
+	case QLA_PROT_DIN_INSERT:
+	case QLA_PROT_DOUT_STRIP:
 		transfer_length = data_bytes;
 		data_bytes += dif_bytes;
 		break;
 
-	case TARGET_PROT_DIN_STRIP:
-	case TARGET_PROT_DOUT_INSERT:
-	case TARGET_PROT_DIN_PASS:
-	case TARGET_PROT_DOUT_PASS:
+	case QLA_PROT_DIN_STRIP:
+	case QLA_PROT_DOUT_INSERT:
+	case QLA_PROT_DIN_PASS:
+	case QLA_PROT_DOUT_PASS:
 		transfer_length = data_bytes + dif_bytes;
 		break;
 
@@ -2688,28 +2818,28 @@ static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
 		break;
 	}
 
-	if (!qlt_hba_err_chk_enabled(se_cmd))
+	if (!qlt_hba_err_chk_enabled(cmd))
 		fw_prot_opts |= 0x10; /* Disable Guard tag checking */
 	/* HBA error checking enabled */
 	else if (IS_PI_UNINIT_CAPABLE(ha)) {
-		if ((se_cmd->prot_type == TARGET_DIF_TYPE1_PROT) ||
-		    (se_cmd->prot_type == TARGET_DIF_TYPE2_PROT))
+		if ((cmd->prot_type == QLA_TGT_PROT_TYPE1) ||
+		    (cmd->prot_type == QLA_TGT_PROT_TYPE2))
 			fw_prot_opts |= PO_DIS_VALD_APP_ESC;
-		else if (se_cmd->prot_type == TARGET_DIF_TYPE3_PROT)
+		else if (cmd->prot_type == QLA_TGT_PROT_TYPE3)
 			fw_prot_opts |= PO_DIS_VALD_APP_REF_ESC;
 	}
 
-	switch (se_cmd->prot_op) {
-	case TARGET_PROT_DIN_INSERT:
-	case TARGET_PROT_DOUT_INSERT:
+	switch (cmd->prot_op) {
+	case QLA_PROT_DIN_INSERT:
+	case QLA_PROT_DOUT_INSERT:
 		fw_prot_opts |= PO_MODE_DIF_INSERT;
 		break;
-	case TARGET_PROT_DIN_STRIP:
-	case TARGET_PROT_DOUT_STRIP:
+	case QLA_PROT_DIN_STRIP:
+	case QLA_PROT_DOUT_STRIP:
 		fw_prot_opts |= PO_MODE_DIF_REMOVE;
 		break;
-	case TARGET_PROT_DIN_PASS:
-	case TARGET_PROT_DOUT_PASS:
+	case QLA_PROT_DIN_PASS:
+	case QLA_PROT_DOUT_PASS:
 		fw_prot_opts |= PO_MODE_DIF_PASS;
 		/* FUTURE: does tcm require T10CRC<->IPCKSUM conversion? */
 		break;
@@ -2784,7 +2914,7 @@ static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
 	/* Set handle */
 	crc_ctx_pkt->handle = pkt->handle;
 
-	qlt_set_t10dif_tags(se_cmd, crc_ctx_pkt);
+	qla_tgt_set_dif_tags(cmd, crc_ctx_pkt, &fw_prot_opts);
 
 	pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma));
 	pkt->crc_context_address[1] = cpu_to_le32(MSD(crc_ctx_dma));
@@ -2910,7 +3040,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
 	if (unlikely(res))
 		goto out_unmap_unlock;
 
-	if (cmd->se_cmd.prot_op && (xmit_type & QLA_TGT_XMIT_DATA))
+	if (cmd->prot_op && (xmit_type & QLA_TGT_XMIT_DATA))
 		res = qlt_build_ctio_crc2_pkt(&prm, vha);
 	else
 		res = qlt_24xx_build_ctio_pkt(&prm, vha);
@@ -2926,7 +3056,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
 		    cpu_to_le16(CTIO7_FLAGS_DATA_IN |
 			CTIO7_FLAGS_STATUS_MODE_0);
 
-		if (cmd->se_cmd.prot_op == TARGET_PROT_NORMAL)
+		if (cmd->prot_op == QLA_PROT_NORMAL)
 			qlt_load_data_segments(&prm, vha);
 
 		if (prm.add_status_pkt == 0) {
@@ -3051,7 +3181,7 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
 	res = qlt_check_reserve_free_req(vha, prm.req_cnt);
 	if (res != 0)
 		goto out_unlock_free_unmap;
-	if (cmd->se_cmd.prot_op)
+	if (cmd->prot_op)
 		res = qlt_build_ctio_crc2_pkt(&prm, vha);
 	else
 		res = qlt_24xx_build_ctio_pkt(&prm, vha);
@@ -3065,7 +3195,7 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
 	pkt->u.status0.flags |= cpu_to_le16(CTIO7_FLAGS_DATA_OUT |
 	    CTIO7_FLAGS_STATUS_MODE_0);
 
-	if (cmd->se_cmd.prot_op == TARGET_PROT_NORMAL)
+	if (cmd->prot_op == QLA_PROT_NORMAL)
 		qlt_load_data_segments(&prm, vha);
 
 	cmd->state = QLA_TGT_STATE_NEED_DATA;
@@ -3088,139 +3218,113 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
 
 
 /*
- * Checks the guard or meta-data for the type of error
- * detected by the HBA.
+ * it is assumed either hardware_lock or qpair lock is held.
  */
-static inline int
+static void
 qlt_handle_dif_error(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd,
-		struct ctio_crc_from_fw *sts)
+	struct ctio_crc_from_fw *sts)
 {
 	uint8_t		*ap = &sts->actual_dif[0];
 	uint8_t		*ep = &sts->expected_dif[0];
-	uint32_t	e_ref_tag, a_ref_tag;
-	uint16_t	e_app_tag, a_app_tag;
-	uint16_t	e_guard, a_guard;
 	uint64_t	lba = cmd->se_cmd.t_task_lba;
+	uint8_t scsi_status, sense_key, asc, ascq;
+	unsigned long flags;
 
-	a_guard   = be16_to_cpu(*(uint16_t *)(ap + 0));
-	a_app_tag = be16_to_cpu(*(uint16_t *)(ap + 2));
-	a_ref_tag = be32_to_cpu(*(uint32_t *)(ap + 4));
-
-	e_guard   = be16_to_cpu(*(uint16_t *)(ep + 0));
-	e_app_tag = be16_to_cpu(*(uint16_t *)(ep + 2));
-	e_ref_tag = be32_to_cpu(*(uint32_t *)(ep + 4));
-
-	ql_dbg(ql_dbg_tgt, vha, 0xe075,
-	    "iocb(s) %p Returned STATUS.\n", sts);
-
-	ql_dbg(ql_dbg_tgt, vha, 0xf075,
-	    "dif check TGT cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x]\n",
-	    cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba,
-	    a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, a_guard, e_guard);
-
-	/*
-	 * Ignore sector if:
-	 * For type     3: ref & app tag is all 'f's
-	 * For type 0,1,2: app tag is all 'f's
-	 */
-	if ((a_app_tag == 0xffff) &&
-	    ((cmd->se_cmd.prot_type != TARGET_DIF_TYPE3_PROT) ||
-	     (a_ref_tag == 0xffffffff))) {
-		uint32_t blocks_done;
-
-		/* 2TB boundary case covered automatically with this */
-		blocks_done = e_ref_tag - (uint32_t)lba + 1;
-		cmd->se_cmd.bad_sector = e_ref_tag;
-		cmd->se_cmd.pi_err = 0;
-		ql_dbg(ql_dbg_tgt, vha, 0xf074,
-			"need to return scsi good\n");
-
-		/* Update protection tag */
-		if (cmd->prot_sg_cnt) {
-			uint32_t i, k = 0, num_ent;
-			struct scatterlist *sg, *sgl;
-
-
-			sgl = cmd->prot_sg;
-
-			/* Patch the corresponding protection tags */
-			for_each_sg(sgl, sg, cmd->prot_sg_cnt, i) {
-				num_ent = sg_dma_len(sg) / 8;
-				if (k + num_ent < blocks_done) {
-					k += num_ent;
-					continue;
-				}
-				k = blocks_done;
-				break;
-			}
+	cmd->trc_flags |= TRC_DIF_ERR;
 
-			if (k != blocks_done) {
-				ql_log(ql_log_warn, vha, 0xf076,
-				    "unexpected tag values tag:lba=%u:%llu)\n",
-				    e_ref_tag, (unsigned long long)lba);
-				goto out;
-			}
+	cmd->a_guard   = be16_to_cpu(*(uint16_t *)(ap + 0));
+	cmd->a_app_tag = be16_to_cpu(*(uint16_t *)(ap + 2));
+	cmd->a_ref_tag = be32_to_cpu(*(uint32_t *)(ap + 4));
 
-#if 0
-			struct sd_dif_tuple *spt;
-			/* TODO:
-			 * This section came from initiator. Is it valid here?
-			 * should ulp be override with actual val???
-			 */
-			spt = page_address(sg_page(sg)) + sg->offset;
-			spt += j;
+	cmd->e_guard   = be16_to_cpu(*(uint16_t *)(ep + 0));
+	cmd->e_app_tag = be16_to_cpu(*(uint16_t *)(ep + 2));
+	cmd->e_ref_tag = be32_to_cpu(*(uint32_t *)(ep + 4));
 
-			spt->app_tag = 0xffff;
-			if (cmd->se_cmd.prot_type == SCSI_PROT_DIF_TYPE3)
-				spt->ref_tag = 0xffffffff;
-#endif
-		}
+	ql_dbg(ql_dbg_tgt_dif, vha, 0xf075,
+	    "%s: aborted %d state %d\n", __func__, cmd->aborted, cmd->state);
 
-		return 0;
-	}
+	scsi_status = sense_key = asc = ascq = 0;
 
-	/* check guard */
-	if (e_guard != a_guard) {
-		cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED;
-		cmd->se_cmd.bad_sector = cmd->se_cmd.t_task_lba;
-
-		ql_log(ql_log_warn, vha, 0xe076,
-		    "Guard ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n",
-		    cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba,
-		    a_ref_tag, e_ref_tag, a_app_tag, e_app_tag,
-		    a_guard, e_guard, cmd);
-		goto out;
+	/* check appl tag */
+	if (cmd->e_app_tag != cmd->a_app_tag) {
+		ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
+			"App Tag ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] "
+			"Ref[%x|%x], App[%x|%x], "
+			"Guard [%x|%x] cmd=%p ox_id[%04x]",
+			cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks,
+			cmd->a_ref_tag, cmd->e_ref_tag,
+			cmd->a_app_tag, cmd->e_app_tag,
+			cmd->a_guard, cmd->e_guard,
+			cmd, cmd->atio.u.isp24.fcp_hdr.ox_id);
+
+		cmd->dif_err_code = DIF_ERR_APP;
+		scsi_status = SAM_STAT_CHECK_CONDITION;
+		sense_key = ABORTED_COMMAND;
+		asc = 0x10;
+		ascq = 0x2;
 	}
 
 	/* check ref tag */
-	if (e_ref_tag != a_ref_tag) {
-		cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED;
-		cmd->se_cmd.bad_sector = e_ref_tag;
-
-		ql_log(ql_log_warn, vha, 0xe077,
-			"Ref Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n",
-			cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba,
-			a_ref_tag, e_ref_tag, a_app_tag, e_app_tag,
-			a_guard, e_guard, cmd);
+	if (cmd->e_ref_tag != cmd->a_ref_tag) {
+		ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
+			"Ref Tag ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] "
+			"Ref[%x|%x], App[%x|%x], "
+			"Guard[%x|%x] cmd=%p ox_id[%04x] ",
+			cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks,
+			cmd->a_ref_tag, cmd->e_ref_tag,
+			cmd->a_app_tag, cmd->e_app_tag,
+			cmd->a_guard, cmd->e_guard,
+			cmd, cmd->atio.u.isp24.fcp_hdr.ox_id);
+
+		cmd->dif_err_code = DIF_ERR_REF;
+		scsi_status = SAM_STAT_CHECK_CONDITION;
+		sense_key = ABORTED_COMMAND;
+		asc = 0x10;
+		ascq = 0x3;
 		goto out;
 	}
 
-	/* check appl tag */
-	if (e_app_tag != a_app_tag) {
-		cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED;
-		cmd->se_cmd.bad_sector = cmd->se_cmd.t_task_lba;
-
-		ql_log(ql_log_warn, vha, 0xe078,
-			"App Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n",
-			cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba,
-			a_ref_tag, e_ref_tag, a_app_tag, e_app_tag,
-			a_guard, e_guard, cmd);
-		goto out;
+	/* check guard */
+	if (cmd->e_guard != cmd->a_guard) {
+		ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
+			"Guard ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] "
+			"Ref[%x|%x], App[%x|%x], "
+			"Guard [%x|%x] cmd=%p ox_id[%04x]",
+			cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks,
+			cmd->a_ref_tag, cmd->e_ref_tag,
+			cmd->a_app_tag, cmd->e_app_tag,
+			cmd->a_guard, cmd->e_guard,
+			cmd, cmd->atio.u.isp24.fcp_hdr.ox_id);
+		cmd->dif_err_code = DIF_ERR_GRD;
+		scsi_status = SAM_STAT_CHECK_CONDITION;
+		sense_key = ABORTED_COMMAND;
+		asc = 0x10;
+		ascq = 0x1;
 	}
 out:
-	return 1;
-}
+	switch (cmd->state) {
+	case QLA_TGT_STATE_NEED_DATA:
+		/* handle_data will load DIF error code  */
+		cmd->state = QLA_TGT_STATE_DATA_IN;
+		vha->hw->tgt.tgt_ops->handle_data(cmd);
+		break;
+	default:
+		spin_lock_irqsave(&cmd->cmd_lock, flags);
+		if (cmd->aborted) {
+			spin_unlock_irqrestore(&cmd->cmd_lock, flags);
+			vha->hw->tgt.tgt_ops->free_cmd(cmd);
+			break;
+		}
+		spin_unlock_irqrestore(&cmd->cmd_lock, flags);
 
+		qlt_send_resp_ctio(vha, cmd, scsi_status, sense_key, asc, ascq);
+		/* assume scsi status gets out on the wire.
+		 * Will not wait for completion.
+		 */
+		vha->hw->tgt.tgt_ops->free_cmd(cmd);
+		break;
+	}
+}
 
 /* If hardware_lock held on entry, might drop it, then reaquire */
 /* This function sends the appropriate CTIO to ISP 2xxx or 24xx */
@@ -3527,6 +3631,16 @@ static int qlt_term_ctio_exchange(struct scsi_qla_host *vha, void *ctio,
 {
 	int term = 0;
 
+	if (cmd->prot_op)
+		ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
+		    "Term DIF cmd: lba[0x%llx|%lld] len[0x%x] "
+		    "se_cmd=%p tag[%x] op %#x/%s",
+		     cmd->lba, cmd->lba,
+		     cmd->num_blks, &cmd->se_cmd,
+		     cmd->atio.u.isp24.exchange_addr,
+		     cmd->prot_op,
+		     prot_op_str(cmd->prot_op));
+
 	if (ctio != NULL) {
 		struct ctio7_from_24xx *c = (struct ctio7_from_24xx *)ctio;
 		term = !(c->flags &
@@ -3744,32 +3858,15 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
 			struct ctio_crc_from_fw *crc =
 				(struct ctio_crc_from_fw *)ctio;
 			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf073,
-			    "qla_target(%d): CTIO with DIF_ERROR status %x received (state %x, se_cmd %p) actual_dif[0x%llx] expect_dif[0x%llx]\n",
+			    "qla_target(%d): CTIO with DIF_ERROR status %x "
+			    "received (state %x, ulp_cmd %p) actual_dif[0x%llx] "
+			    "expect_dif[0x%llx]\n",
 			    vha->vp_idx, status, cmd->state, se_cmd,
 			    *((u64 *)&crc->actual_dif[0]),
 			    *((u64 *)&crc->expected_dif[0]));
 
-			if (qlt_handle_dif_error(vha, cmd, ctio)) {
-				if (cmd->state == QLA_TGT_STATE_NEED_DATA) {
-					/* scsi Write/xfer rdy complete */
-					goto skip_term;
-				} else {
-					/* scsi read/xmit respond complete
-					 * call handle dif to send scsi status
-					 * rather than terminate exchange.
-					 */
-					cmd->state = QLA_TGT_STATE_PROCESSED;
-					ha->tgt.tgt_ops->handle_dif_err(cmd);
-					return;
-				}
-			} else {
-				/* Need to generate a SCSI good completion.
-				 * because FW did not send scsi status.
-				 */
-				status = 0;
-				goto skip_term;
-			}
-			break;
+			qlt_handle_dif_error(vha, cmd, ctio);
+			return;
 		}
 		default:
 			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b,
@@ -3792,7 +3889,6 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
 				return;
 		}
 	}
-skip_term:
 
 	if (cmd->state == QLA_TGT_STATE_PROCESSED) {
 		cmd->trc_flags |= TRC_CTIO_DONE;
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index bc9468f..82d53f3 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -378,6 +378,14 @@ static inline void adjust_corrupted_atio(struct atio_from_isp *atio)
 	atio->u.isp24.fcp_cmnd.add_cdb_len = 0;
 }
 
+static inline int get_datalen_for_atio(struct atio_from_isp *atio)
+{
+	int len = atio->u.isp24.fcp_cmnd.add_cdb_len;
+
+	return (be32_to_cpu(get_unaligned((uint32_t *)
+	    &atio->u.isp24.fcp_cmnd.add_cdb[len * 4])));
+}
+
 #define CTIO_TYPE7 0x12 /* Continue target I/O entry (for 24xx) */
 
 /*
@@ -667,7 +675,6 @@ struct qla_tgt_func_tmpl {
 	int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *,
 			unsigned char *, uint32_t, int, int, int);
 	void (*handle_data)(struct qla_tgt_cmd *);
-	void (*handle_dif_err)(struct qla_tgt_cmd *);
 	int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint16_t,
 			  uint32_t, bool);
 	void (*free_cmd)(struct qla_tgt_cmd *);
@@ -684,6 +691,8 @@ struct qla_tgt_func_tmpl {
 	void (*clear_nacl_from_fcport_map)(struct fc_port *);
 	void (*put_sess)(struct fc_port *);
 	void (*shutdown_sess)(struct fc_port *);
+	int (*get_dif_tags)(struct qla_tgt_cmd *cmd, uint16_t *pfw_prot_opts);
+	int (*chk_dif_tags)(uint32_t tag);
 };
 
 int qla2x00_wait_for_hba_online(struct scsi_qla_host *);
@@ -720,8 +729,8 @@ struct qla_tgt_func_tmpl {
 #define QLA_TGT_ABORT_ALL               0xFFFE
 #define QLA_TGT_NEXUS_LOSS_SESS         0xFFFD
 #define QLA_TGT_NEXUS_LOSS              0xFFFC
-#define QLA_TGT_ABTS					0xFFFB
-#define QLA_TGT_2G_ABORT_TASK			0xFFFA
+#define QLA_TGT_ABTS			0xFFFB
+#define QLA_TGT_2G_ABORT_TASK		0xFFFA
 
 /* Notify Acknowledge flags */
 #define NOTIFY_ACK_RES_COUNT        BIT_8
@@ -845,6 +854,7 @@ enum trace_flags {
 	TRC_CMD_FREE = BIT_17,
 	TRC_DATA_IN = BIT_18,
 	TRC_ABORT = BIT_19,
+	TRC_DIF_ERR = BIT_20,
 };
 
 struct qla_tgt_cmd {
@@ -885,11 +895,25 @@ struct qla_tgt_cmd {
 	struct list_head cmd_list;
 
 	struct atio_from_isp atio;
-	/* t10dif */
+
+	/* T10-DIF */
+#define DIF_ERR_NONE 0
+#define DIF_ERR_GRD 1
+#define DIF_ERR_REF 2
+#define DIF_ERR_APP 3
+	int8_t dif_err_code;
 	struct scatterlist *prot_sg;
 	uint32_t prot_sg_cnt;
-	uint32_t blk_sz;
+	uint32_t blk_sz, num_blks;
+	uint8_t scsi_status, sense_key, asc, ascq;
+
 	struct crc_context *ctx;
+	uint32_t	prot_op;
+	uint32_t	prot_type;
+	uint8_t		*cdb;
+	uint64_t	lba;
+	uint16_t	a_guard, e_guard, a_app_tag, e_app_tag;
+	uint32_t	a_ref_tag, e_ref_tag;
 
 	uint64_t jiffies_at_alloc;
 	uint64_t jiffies_at_free;
@@ -1053,4 +1077,7 @@ extern void qlt_modify_vp_config(struct scsi_qla_host *,
 extern void qlt_logo_completion_handler(fc_port_t *, int);
 extern void qlt_do_generation_tick(struct scsi_qla_host *, int *);
 
+void qlt_send_resp_ctio(scsi_qla_host_t *, struct qla_tgt_cmd *, uint8_t,
+    uint8_t, uint8_t, uint8_t);
+
 #endif /* __QLA_TARGET_H */
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 9a188b5..3618056 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -376,6 +376,38 @@ static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess)
 	return 0;
 }
 
+static void tcm_qla2xxx_prot_op(struct qla_tgt_cmd *cmd)
+{
+	switch (cmd->se_cmd.prot_op) {
+	case TARGET_PROT_NORMAL:
+		cmd->prot_op = QLA_PROT_NORMAL;
+		break;
+	case TARGET_PROT_DIN_INSERT:
+		cmd->prot_op = QLA_PROT_DIN_INSERT;
+		break;
+	case TARGET_PROT_DOUT_INSERT:
+		cmd->prot_op = QLA_PROT_DOUT_INSERT;
+		break;
+	case TARGET_PROT_DIN_STRIP:
+		cmd->prot_op = QLA_PROT_DIN_STRIP;
+		break;
+	case TARGET_PROT_DOUT_STRIP:
+		cmd->prot_op = QLA_PROT_DOUT_STRIP;
+		break;
+	case TARGET_PROT_DIN_PASS:
+		cmd->prot_op = QLA_PROT_DIN_PASS;
+		break;
+	case TARGET_PROT_DOUT_PASS:
+		cmd->prot_op = QLA_PROT_DOUT_PASS;
+		break;
+	}
+}
+
+static void tcm_qla2xxx_prot_type(struct qla_tgt_cmd *cmd)
+{
+	cmd->prot_type = cmd->se_cmd.prot_type;
+}
+
 static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
 {
 	struct qla_tgt_cmd *cmd = container_of(se_cmd,
@@ -405,6 +437,8 @@ static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
 	cmd->prot_sg = se_cmd->t_prot_sg;
 	cmd->blk_sz  = se_cmd->se_dev->dev_attrib.block_size;
 	se_cmd->pi_err = 0;
+	tcm_qla2xxx_prot_op(cmd);
+	tcm_qla2xxx_prot_type(cmd);
 
 	/*
 	 * qla_target.c:qlt_rdy_to_xfer() will call pci_map_sg() to setup
@@ -505,6 +539,24 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
 		if (cmd->se_cmd.transport_state & CMD_T_ABORTED)
 			return;
 
+		switch (cmd->dif_err_code) {
+		case DIF_ERR_GRD:
+			cmd->se_cmd.pi_err =
+			    TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED;
+			break;
+		case DIF_ERR_REF:
+			cmd->se_cmd.pi_err =
+			    TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED;
+			break;
+		case DIF_ERR_APP:
+			cmd->se_cmd.pi_err =
+			    TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED;
+			break;
+		case DIF_ERR_NONE:
+		default:
+			break;
+		}
+
 		if (cmd->se_cmd.pi_err)
 			transport_generic_request_failure(&cmd->se_cmd,
 				cmd->se_cmd.pi_err);
@@ -529,25 +581,23 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
 	queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
 }
 
-static void tcm_qla2xxx_handle_dif_work(struct work_struct *work)
+static int tcm_qla2xxx_chk_dif_tags(uint32_t tag)
 {
-	struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
-
-	/* take an extra kref to prevent cmd free too early.
-	 * need to wait for SCSI status/check condition to
-	 * finish responding generate by transport_generic_request_failure.
-	 */
-	kref_get(&cmd->se_cmd.cmd_kref);
-	transport_generic_request_failure(&cmd->se_cmd, cmd->se_cmd.pi_err);
+	return 0;
 }
 
-/*
- * Called from qla_target.c:qlt_do_ctio_completion()
- */
-static void tcm_qla2xxx_handle_dif_err(struct qla_tgt_cmd *cmd)
+static int tcm_qla2xxx_dif_tags(struct qla_tgt_cmd *cmd,
+    uint16_t *pfw_prot_opts)
 {
-	INIT_WORK(&cmd->work, tcm_qla2xxx_handle_dif_work);
-	queue_work(tcm_qla2xxx_free_wq, &cmd->work);
+	struct se_cmd *se_cmd = &cmd->se_cmd;
+
+	if (!(se_cmd->prot_checks & TARGET_DIF_CHECK_GUARD))
+		*pfw_prot_opts |= PO_DISABLE_GUARD_CHECK;
+
+	if (!(se_cmd->prot_checks & TARGET_DIF_CHECK_APPTAG))
+		*pfw_prot_opts |= PO_DIS_APP_TAG_VALD;
+
+	return 0;
 }
 
 /*
@@ -634,6 +684,7 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
 	cmd->prot_sg = se_cmd->t_prot_sg;
 	cmd->blk_sz  = se_cmd->se_dev->dev_attrib.block_size;
 	se_cmd->pi_err = 0;
+	tcm_qla2xxx_prot_op(cmd);
 
 	/*
 	 * Now queue completed DATA_IN the qla2xxx LLD and response ring
@@ -1588,7 +1639,6 @@ static void tcm_qla2xxx_update_sess(struct fc_port *sess, port_id_t s_id,
 static struct qla_tgt_func_tmpl tcm_qla2xxx_template = {
 	.handle_cmd		= tcm_qla2xxx_handle_cmd,
 	.handle_data		= tcm_qla2xxx_handle_data,
-	.handle_dif_err		= tcm_qla2xxx_handle_dif_err,
 	.handle_tmr		= tcm_qla2xxx_handle_tmr,
 	.free_cmd		= tcm_qla2xxx_free_cmd,
 	.free_mcmd		= tcm_qla2xxx_free_mcmd,
@@ -1600,6 +1650,8 @@ static void tcm_qla2xxx_update_sess(struct fc_port *sess, port_id_t s_id,
 	.clear_nacl_from_fcport_map = tcm_qla2xxx_clear_nacl_from_fcport_map,
 	.put_sess		= tcm_qla2xxx_put_sess,
 	.shutdown_sess		= tcm_qla2xxx_shutdown_sess,
+	.get_dif_tags		= tcm_qla2xxx_dif_tags,
+	.chk_dif_tags		= tcm_qla2xxx_chk_dif_tags,
 };
 
 static int tcm_qla2xxx_init_lport(struct tcm_qla2xxx_lport *lport)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 07/14] qla2xxx: Export DIF stats via debugfs
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
                   ` (5 preceding siblings ...)
  2017-02-03 22:40 ` [PATCH v2 06/14] qla2xxx: Improve T10-DIF/PI handling in driver Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-03 22:40 ` [PATCH v2 08/14] qla2xxx: Change scsi host lookup method Himanshu Madhani
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

From: Anil Gurumurthy <anil.gurumurthy@cavium.com>

Signed-off-by: Anil Gurumurthy <anil.gurumurthy@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
---
 drivers/scsi/qla2xxx/qla_def.h | 12 ++++++++++++
 drivers/scsi/qla2xxx/qla_dfs.c | 15 +++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index d6436fc..a15614d 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3129,6 +3129,16 @@ struct qla_chip_state_84xx {
 	uint32_t gold_fw_version;
 };
 
+struct qla_dif_statistics {
+	uint64_t dif_input_bytes;
+	uint64_t dif_output_bytes;
+	uint64_t dif_input_requests;
+	uint64_t dif_output_requests;
+	uint32_t dif_guard_err;
+	uint32_t dif_ref_tag_err;
+	uint32_t dif_app_tag_err;
+};
+
 struct qla_statistics {
 	uint32_t total_isp_aborts;
 	uint64_t input_bytes;
@@ -3141,6 +3151,8 @@ struct qla_statistics {
 	uint32_t stat_max_pend_cmds;
 	uint32_t stat_max_qfull_cmds_alloc;
 	uint32_t stat_max_qfull_cmds_dropped;
+
+	struct qla_dif_statistics qla_dif_stats;
 };
 
 struct bidi_statistics {
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 0fb33e6..989e17b 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -185,6 +185,21 @@
 	seq_printf(s, "num Q full sent = %lld\n",
 		vha->tgt_counters.num_q_full_sent);
 
+	/* DIF stats */
+	seq_printf(s, "DIF Inp Bytes = %lld\n",
+		vha->qla_stats.qla_dif_stats.dif_input_bytes);
+	seq_printf(s, "DIF Outp Bytes = %lld\n",
+		vha->qla_stats.qla_dif_stats.dif_output_bytes);
+	seq_printf(s, "DIF Inp Req = %lld\n",
+		vha->qla_stats.qla_dif_stats.dif_input_requests);
+	seq_printf(s, "DIF Outp Req = %lld\n",
+		vha->qla_stats.qla_dif_stats.dif_output_requests);
+	seq_printf(s, "DIF Guard err = %d\n",
+		vha->qla_stats.qla_dif_stats.dif_guard_err);
+	seq_printf(s, "DIF Ref tag err = %d\n",
+		vha->qla_stats.qla_dif_stats.dif_ref_tag_err);
+	seq_printf(s, "DIF App tag err = %d\n",
+		vha->qla_stats.qla_dif_stats.dif_app_tag_err);
 	return 0;
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 08/14] qla2xxx: Change scsi host lookup method
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
                   ` (6 preceding siblings ...)
  2017-02-03 22:40 ` [PATCH v2 07/14] qla2xxx: Export DIF stats via debugfs Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-03 22:40 ` [PATCH v2 09/14] qla2xxx: Fix memory leak for abts processing Himanshu Madhani
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

From: Quinn Tran <quinn.tran@cavium.com>

For target mode, when new scsi command arrive, driver first performs
a look up of the SCSI Host. The current look up method is based on
the ALPA portion of the NPort ID. For Cisco switch, the ALPA can
not be used as the index. Instead, the new search method is based
on the full value of the Nport_ID via btree lib.

Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
---
 drivers/scsi/qla2xxx/Kconfig      |  1 +
 drivers/scsi/qla2xxx/qla_def.h    |  2 +
 drivers/scsi/qla2xxx/qla_gbl.h    |  2 +
 drivers/scsi/qla2xxx/qla_init.c   | 14 +++---
 drivers/scsi/qla2xxx/qla_mbx.c    | 28 ++++--------
 drivers/scsi/qla2xxx/qla_os.c     |  1 +
 drivers/scsi/qla2xxx/qla_target.c | 90 +++++++++++++++++++++++++++++++++------
 7 files changed, 98 insertions(+), 40 deletions(-)

diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig
index 67c0d5a..de95293 100644
--- a/drivers/scsi/qla2xxx/Kconfig
+++ b/drivers/scsi/qla2xxx/Kconfig
@@ -3,6 +3,7 @@ config SCSI_QLA_FC
 	depends on PCI && SCSI
 	depends on SCSI_FC_ATTRS
 	select FW_LOADER
+	select BTREE
 	---help---
 	This qla2xxx driver supports all QLogic Fibre Channel
 	PCI and PCIe host adapters.
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index a15614d..160d74c 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -25,6 +25,7 @@
 #include <linux/firmware.h>
 #include <linux/aer.h>
 #include <linux/mutex.h>
+#include <linux/btree.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
@@ -3318,6 +3319,7 @@ struct qlt_hw_data {
 	spinlock_t sess_lock;
 	int rspq_vector_cpuid;
 	spinlock_t atio_lock ____cacheline_aligned;
+	struct btree_head32 host_map;
 };
 
 #define MAX_QFULL_CMDS_ALLOC	8192
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 48a1190..b1e7b82 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -855,5 +855,7 @@ extern struct fc_port *qlt_find_sess_invalidate_other(scsi_qla_host_t *,
 	uint64_t wwn, port_id_t port_id, uint16_t loop_id, struct fc_port **);
 void qla24xx_delete_sess_fn(struct work_struct *);
 void qlt_unknown_atio_work_fn(struct work_struct *);
+void qlt_update_host_map(struct scsi_qla_host *, port_id_t);
+void qlt_remove_target_resources(struct qla_hw_data *);
 
 #endif /* _QLA_GBL_H */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 5aca3df..ea6ddcf 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3345,8 +3345,8 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
 	uint8_t       domain;
 	char		connect_type[22];
 	struct qla_hw_data *ha = vha->hw;
-	unsigned long flags;
 	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+	port_id_t id;
 
 	/* Get host addresses. */
 	rval = qla2x00_get_adapter_id(vha,
@@ -3424,13 +3424,11 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
 
 	/* Save Host port and loop ID. */
 	/* byte order - Big Endian */
-	vha->d_id.b.domain = domain;
-	vha->d_id.b.area = area;
-	vha->d_id.b.al_pa = al_pa;
-
-	spin_lock_irqsave(&ha->vport_slock, flags);
-	qlt_update_vp_map(vha, SET_AL_PA);
-	spin_unlock_irqrestore(&ha->vport_slock, flags);
+	id.b.domain = domain;
+	id.b.area = area;
+	id.b.al_pa = al_pa;
+	id.b.rsvd_1 = 0;
+	qlt_update_host_map(vha, id);
 
 	if (!vha->flags.init_done)
 		ql_log(ql_log_info, vha, 0x2010,
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 4225256..f352889 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -3624,6 +3624,7 @@ struct tsk_mgmt_cmd {
 	scsi_qla_host_t *vp = NULL;
 	unsigned long   flags;
 	int found;
+	port_id_t id;
 
 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,
 	    "Entered %s.\n", __func__);
@@ -3631,6 +3632,11 @@ struct tsk_mgmt_cmd {
 	if (rptid_entry->entry_status != 0)
 		return;
 
+	id.b.domain = rptid_entry->port_id[2];
+	id.b.area   = rptid_entry->port_id[1];
+	id.b.al_pa  = rptid_entry->port_id[0];
+	id.b.rsvd_1 = 0;
+
 	if (rptid_entry->format == 0) {
 		/* loop */
 		ql_dbg(ql_dbg_async, vha, 0x10b7,
@@ -3642,13 +3648,7 @@ struct tsk_mgmt_cmd {
 		    rptid_entry->port_id[2], rptid_entry->port_id[1],
 		    rptid_entry->port_id[0]);
 
-		vha->d_id.b.domain = rptid_entry->port_id[2];
-		vha->d_id.b.area = rptid_entry->port_id[1];
-		vha->d_id.b.al_pa = rptid_entry->port_id[0];
-
-		spin_lock_irqsave(&ha->vport_slock, flags);
-		qlt_update_vp_map(vha, SET_AL_PA);
-		spin_unlock_irqrestore(&ha->vport_slock, flags);
+		qlt_update_host_map(vha, id);
 
 	} else if (rptid_entry->format == 1) {
 		/* fabric */
@@ -3674,12 +3674,7 @@ struct tsk_mgmt_cmd {
 					    WWN_SIZE);
 				}
 
-				vha->d_id.b.domain = rptid_entry->port_id[2];
-				vha->d_id.b.area = rptid_entry->port_id[1];
-				vha->d_id.b.al_pa = rptid_entry->port_id[0];
-				spin_lock_irqsave(&ha->vport_slock, flags);
-				qlt_update_vp_map(vha, SET_AL_PA);
-				spin_unlock_irqrestore(&ha->vport_slock, flags);
+				qlt_update_host_map(vha, id);
 			}
 
 			fc_host_port_name(vha->host) =
@@ -3715,12 +3710,7 @@ struct tsk_mgmt_cmd {
 			if (!found)
 				return;
 
-			vp->d_id.b.domain = rptid_entry->port_id[2];
-			vp->d_id.b.area =  rptid_entry->port_id[1];
-			vp->d_id.b.al_pa = rptid_entry->port_id[0];
-			spin_lock_irqsave(&ha->vport_slock, flags);
-			qlt_update_vp_map(vp, SET_AL_PA);
-			spin_unlock_irqrestore(&ha->vport_slock, flags);
+			qlt_update_host_map(vp, id);
 
 			/*
 			 * Cannot configure here as we are still sitting on the
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 10cb4990..ee0f4fa 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3474,6 +3474,7 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 	qla2x00_free_sysfs_attr(base_vha, true);
 
 	fc_remove_host(base_vha->host);
+	qlt_remove_target_resources(ha);
 
 	scsi_remove_host(base_vha->host);
 
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index a36258d..359a79d 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -182,21 +182,23 @@ static inline int qlt_issue_marker(struct scsi_qla_host *vha, int vha_locked)
 struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha,
 	uint8_t *d_id)
 {
-	struct qla_hw_data *ha = vha->hw;
-	uint8_t vp_idx;
-
-	if ((vha->d_id.b.area != d_id[1]) || (vha->d_id.b.domain != d_id[0]))
-		return NULL;
+	struct scsi_qla_host *host;
+	uint32_t key = 0;
 
-	if (vha->d_id.b.al_pa == d_id[2])
+	if ((vha->d_id.b.area == d_id[1]) && (vha->d_id.b.domain == d_id[0]) &&
+	    (vha->d_id.b.al_pa == d_id[2]))
 		return vha;
 
-	BUG_ON(ha->tgt.tgt_vp_map == NULL);
-	vp_idx = ha->tgt.tgt_vp_map[d_id[2]].idx;
-	if (likely(test_bit(vp_idx, ha->vp_idx_map)))
-		return ha->tgt.tgt_vp_map[vp_idx].vha;
+	key  = (uint32_t)d_id[0] << 16;
+	key |= (uint32_t)d_id[1] <<  8;
+	key |= (uint32_t)d_id[2];
 
-	return NULL;
+	host = btree_lookup32(&vha->hw->tgt.host_map, key);
+	if (!host)
+		ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
+			   "Unable to find host %06x\n", key);
+
+	return host;
 }
 
 static inline
@@ -6017,6 +6019,17 @@ int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha)
 	return 0;
 }
 
+void qlt_remove_target_resources(struct qla_hw_data *ha)
+{
+	struct scsi_qla_host *node;
+	u32 key = 0;
+
+	btree_for_each_safe32(&ha->tgt.host_map, key, node)
+		btree_remove32(&ha->tgt.host_map, key);
+
+	btree_destroy32(&ha->tgt.host_map);
+}
+
 static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn,
 	unsigned char *b)
 {
@@ -6670,6 +6683,8 @@ static void qlt_disable_vha(struct scsi_qla_host *vha)
 void
 qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha)
 {
+	int rc;
+
 	if (!QLA_TGT_MODE_ENABLED())
 		return;
 
@@ -6689,6 +6704,13 @@ static void qlt_disable_vha(struct scsi_qla_host *vha)
 	    qlt_unknown_atio_work_fn);
 
 	qlt_clear_mode(base_vha);
+
+	rc = btree_init32(&ha->tgt.host_map);
+	if (rc)
+		ql_log(ql_log_info, base_vha, 0xffff,
+		    "Unable to initialize ha->host_map btree\n");
+
+	qlt_update_vp_map(base_vha, SET_VP_IDX);
 }
 
 irqreturn_t
@@ -6795,25 +6817,67 @@ static void qlt_disable_vha(struct scsi_qla_host *vha)
 void
 qlt_update_vp_map(struct scsi_qla_host *vha, int cmd)
 {
+	void *slot;
+	u32 key;
+	int rc;
+
 	if (!QLA_TGT_MODE_ENABLED())
 		return;
 
+	key = vha->d_id.b24;
+
 	switch (cmd) {
 	case SET_VP_IDX:
 		vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = vha;
 		break;
 	case SET_AL_PA:
-		vha->hw->tgt.tgt_vp_map[vha->d_id.b.al_pa].idx = vha->vp_idx;
+		slot = btree_lookup32(&vha->hw->tgt.host_map, key);
+		if (!slot) {
+			ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
+			    "Save vha in host_map %p %06x\n", vha, key);
+			rc = btree_insert32(&vha->hw->tgt.host_map,
+				key, vha, GFP_ATOMIC);
+			if (rc)
+				ql_log(ql_log_info, vha, 0xffff,
+				    "Unable to insert s_id into host_map: %06x\n",
+				    key);
+			return;
+		}
+		ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
+			"replace existing vha in host_map %p %06x\n", vha, key);
+		btree_update32(&vha->hw->tgt.host_map, key, vha);
 		break;
 	case RESET_VP_IDX:
 		vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = NULL;
 		break;
 	case RESET_AL_PA:
-		vha->hw->tgt.tgt_vp_map[vha->d_id.b.al_pa].idx = 0;
+		ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
+		   "clear vha in host_map %p %06x\n", vha, key);
+		btree_remove32(&vha->hw->tgt.host_map, key);
+		vha->d_id.b24 = 0;
 		break;
 	}
 }
 
+void qlt_update_host_map(struct scsi_qla_host *vha, port_id_t id)
+{
+	unsigned long flags;
+	struct qla_hw_data *ha = vha->hw;
+
+	if (!vha->d_id.b24) {
+		spin_lock_irqsave(&ha->vport_slock, flags);
+		vha->d_id = id;
+		qlt_update_vp_map(vha, SET_AL_PA);
+		spin_unlock_irqrestore(&ha->vport_slock, flags);
+	} else if (vha->d_id.b24 != id.b24) {
+		spin_lock_irqsave(&ha->vport_slock, flags);
+		qlt_update_vp_map(vha, RESET_AL_PA);
+		vha->d_id = id;
+		qlt_update_vp_map(vha, SET_AL_PA);
+		spin_unlock_irqrestore(&ha->vport_slock, flags);
+	}
+}
+
 static int __init qlt_parse_ini_mode(void)
 {
 	if (strcasecmp(qlini_mode, QLA2XXX_INI_MODE_STR_EXCLUSIVE) == 0)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 09/14] qla2xxx: Fix memory leak for abts processing
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
                   ` (7 preceding siblings ...)
  2017-02-03 22:40 ` [PATCH v2 08/14] qla2xxx: Change scsi host lookup method Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-03 22:40 ` [PATCH v2 10/14] qla2xxx: Fix request queue corruption Himanshu Madhani
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

From: Quinn Tran <quinn.tran@cavium.com>

Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 359a79d..b61cbb8 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -6753,6 +6753,8 @@ static void qlt_disable_vha(struct scsi_qla_host *vha)
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 	qlt_response_pkt_all_vps(vha, (response_t *)&op->atio);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+	kfree(op);
 }
 
 void
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 10/14] qla2xxx: Fix request queue corruption.
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
                   ` (8 preceding siblings ...)
  2017-02-03 22:40 ` [PATCH v2 09/14] qla2xxx: Fix memory leak for abts processing Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-08 19:22   ` Bart Van Assche
  2017-02-03 22:40 ` [PATCH v2 11/14] qla2xxx: Fix inadequate lock protection for ABTS Himanshu Madhani
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

From: Quinn Tran <quinn.tran@cavium.com>

When FW notify driver or driver detects low FW resource,
driver tries to send out Busy SCSI Status to tell Initiator
side to back off. During the send process, the lock was not held.

Signed-off-by: Quinn Tran <quinn.tran@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index b61cbb8..b5fb9c55 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -5170,16 +5170,22 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
 
 static int
 qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha,
-	struct atio_from_isp *atio)
+	struct atio_from_isp *atio, uint8_t ha_locked)
 {
 	struct qla_hw_data *ha = vha->hw;
 	uint16_t status;
+	unsigned long flags;
 
 	if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha))
 		return 0;
 
+	if (!ha_locked)
+		spin_lock_irqsave(&ha->hardware_lock, flags);
 	status = temp_sam_status;
 	qlt_send_busy(vha, atio, status);
+	if (!ha_locked)
+		spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
 	return 1;
 }
 
@@ -5224,7 +5230,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
 
 
 		if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) {
-			rc = qlt_chk_qfull_thresh_hold(vha, atio);
+			rc = qlt_chk_qfull_thresh_hold(vha, atio, ha_locked);
 			if (rc != 0) {
 				tgt->atio_irq_cmd_count--;
 				return;
@@ -5347,7 +5353,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
 			break;
 		}
 
-		rc = qlt_chk_qfull_thresh_hold(vha, atio);
+		rc = qlt_chk_qfull_thresh_hold(vha, atio, 1);
 		if (rc != 0) {
 			tgt->irq_cmd_count--;
 			return;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 11/14] qla2xxx: Fix inadequate lock protection for ABTS.
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
                   ` (9 preceding siblings ...)
  2017-02-03 22:40 ` [PATCH v2 10/14] qla2xxx: Fix request queue corruption Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-03 22:40 ` [PATCH v2 12/14] qla2xxx: Add async new target notification Himanshu Madhani
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

From: Quinn Tran <quinn.tran@cavium.com>

Normally, ABTS is sent to Target Core as Task MGMT command.
In the case of error, qla2xxx needs to send response, hardware_lock
is required to prevent request queue corruption.

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

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index b5fb9c55..8b372b2 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -128,6 +128,9 @@ static void qlt_send_term_imm_notif(struct scsi_qla_host *vha,
 static struct fc_port *qlt_create_sess(struct scsi_qla_host *vha,
 	fc_port_t *fcport, bool local);
 void qlt_unreg_sess(struct fc_port *sess);
+static void qlt_24xx_handle_abts(struct scsi_qla_host *,
+	struct abts_recv_from_24xx *);
+
 /*
  * Global Variables
  */
@@ -403,6 +406,8 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
 			(struct abts_recv_from_24xx *)atio;
 		struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha,
 			entry->vp_index);
+		unsigned long flags;
+
 		if (unlikely(!host)) {
 			ql_dbg(ql_dbg_tgt, vha, 0xffff,
 			    "qla_target(%d): Response pkt (ABTS_RECV_24XX) "
@@ -410,9 +415,12 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
 			    vha->vp_idx, entry->vp_index);
 			break;
 		}
-		qlt_response_pkt(host, (response_t *)atio);
+		if (!ha_locked)
+			spin_lock_irqsave(&host->hw->hardware_lock, flags);
+		qlt_24xx_handle_abts(host, (struct abts_recv_from_24xx *)atio);
+		if (!ha_locked)
+			spin_unlock_irqrestore(&host->hw->hardware_lock, flags);
 		break;
-
 	}
 
 	/* case PUREX_IOCB_TYPE: ql2xmvasynctoatio */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 12/14] qla2xxx: Add async new target notification
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
                   ` (10 preceding siblings ...)
  2017-02-03 22:40 ` [PATCH v2 11/14] qla2xxx: Fix inadequate lock protection for ABTS Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-03 22:40 ` [PATCH v2 13/14] qla2xxx: Fix sess_lock & hardware_lock lock order problem Himanshu Madhani
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

From: Quinn Tran <quinn.tran@cavium.com>

Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 6 +++---
 drivers/scsi/qla2xxx/qla_target.h | 1 +
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 8b372b2..2909b7b 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -5998,13 +5998,13 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha)
 	tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX;
 	tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX;
 
-	if (base_vha->fc_vport)
-		return 0;
-
 	mutex_lock(&qla_tgt_mutex);
 	list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist);
 	mutex_unlock(&qla_tgt_mutex);
 
+	if (ha->tgt.tgt_ops && ha->tgt.tgt_ops->add_target)
+		ha->tgt.tgt_ops->add_target(base_vha);
+
 	return 0;
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 82d53f3..20e25e5 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -693,6 +693,7 @@ struct qla_tgt_func_tmpl {
 	void (*shutdown_sess)(struct fc_port *);
 	int (*get_dif_tags)(struct qla_tgt_cmd *cmd, uint16_t *pfw_prot_opts);
 	int (*chk_dif_tags)(uint32_t tag);
+	void (*add_target)(struct scsi_qla_host *);
 };
 
 int qla2x00_wait_for_hba_online(struct scsi_qla_host *);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 13/14] qla2xxx: Fix sess_lock & hardware_lock lock order problem.
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
                   ` (11 preceding siblings ...)
  2017-02-03 22:40 ` [PATCH v2 12/14] qla2xxx: Add async new target notification Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-03 22:40 ` [PATCH v2 14/14] qla2xxx: Update driver version to 9.00.00.00-k Himanshu Madhani
  2017-02-08 15:02 ` [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Bart Van Assche
  14 siblings, 0 replies; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

From: Quinn Tran <quinn.tran@cavium.com>

The main lock that needs to be held for CMD or TMR submission
to upper layer is the sess_lock. The sess_lock is used to
serialize cmd submission and session deletion. The addition
of hardware_lock being held is not necessary. This patch removes
hardware_lock dependency from CMD/TMR submission.

Use hardware_lock only for error response in this case.

Path1
       CPU0                    CPU1
       ----                    ----
  lock(&(&ha->tgt.sess_lock)->rlock);
                               lock(&(&ha->hardware_lock)->rlock);
                               lock(&(&ha->tgt.sess_lock)->rlock);
  lock(&(&ha->hardware_lock)->rlock);

Path2/deadlock
*** DEADLOCK ***
Call Trace:
dump_stack+0x85/0xc2
print_circular_bug+0x1e3/0x250
__lock_acquire+0x1425/0x1620
lock_acquire+0xbf/0x210
_raw_spin_lock_irqsave+0x53/0x70
qlt_sess_work_fn+0x21d/0x480 [qla2xxx]
process_one_work+0x1f4/0x6e0

Cc: <stable@vger.kernel.org>
Cc: Bart Van Assche <Bart.VanAssche@sandisk.com>
Reported-by: Bart Van Assche <Bart.VanAssche@sandisk.com>
Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
---
 drivers/scsi/qla2xxx/qla_target.c | 41 +++++++++++++++++----------------------
 1 file changed, 18 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 2909b7b..fb7156c 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -5818,30 +5818,23 @@ static void qlt_abort_work(struct qla_tgt *tgt,
 		}
 	}
 
-	spin_lock_irqsave(&ha->hardware_lock, flags);
-
-	if (tgt->tgt_stop)
-		goto out_term;
-
 	rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess);
+	ha->tgt.tgt_ops->put_sess(sess);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
+
 	if (rc != 0)
 		goto out_term;
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
-	if (sess)
-		ha->tgt.tgt_ops->put_sess(sess);
-	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
 	return;
 
 out_term2:
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	if (sess)
+		ha->tgt.tgt_ops->put_sess(sess);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
 
 out_term:
+	spin_lock_irqsave(&ha->hardware_lock, flags);
 	qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
-	if (sess)
-		ha->tgt.tgt_ops->put_sess(sess);
-	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
 }
 
 static void qlt_tmr_work(struct qla_tgt *tgt,
@@ -5861,7 +5854,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
 	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 
 	if (tgt->tgt_stop)
-		goto out_term;
+		goto out_term2;
 
 	s_id = prm->tm_iocb2.u.isp24.fcp_hdr.s_id;
 	sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id);
@@ -5873,11 +5866,11 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
 
 		spin_lock_irqsave(&ha->tgt.sess_lock, flags);
 		if (!sess)
-			goto out_term;
+			goto out_term2;
 	} else {
 		if (sess->deleted) {
 			sess = NULL;
-			goto out_term;
+			goto out_term2;
 		}
 
 		if (!kref_get_unless_zero(&sess->sess_kref)) {
@@ -5885,7 +5878,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
 			    "%s: kref_get fail %8phC\n",
 			     __func__, sess->port_name);
 			sess = NULL;
-			goto out_term;
+			goto out_term2;
 		}
 	}
 
@@ -5895,17 +5888,19 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
 	unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun);
 
 	rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0);
-	if (rc != 0)
-		goto out_term;
-
 	ha->tgt.tgt_ops->put_sess(sess);
 	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
+
+	if (rc != 0)
+		goto out_term;
 	return;
 
+out_term2:
+	if (sess)
+		ha->tgt.tgt_ops->put_sess(sess);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 out_term:
 	qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1, 0);
-	ha->tgt.tgt_ops->put_sess(sess);
-	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 }
 
 static void qlt_sess_work_fn(struct work_struct *work)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 14/14] qla2xxx: Update driver version to 9.00.00.00-k
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
                   ` (12 preceding siblings ...)
  2017-02-03 22:40 ` [PATCH v2 13/14] qla2xxx: Fix sess_lock & hardware_lock lock order problem Himanshu Madhani
@ 2017-02-03 22:40 ` Himanshu Madhani
  2017-02-08 15:02 ` [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Bart Van Assche
  14 siblings, 0 replies; 30+ messages in thread
From: Himanshu Madhani @ 2017-02-03 22:40 UTC (permalink / raw)
  To: target-devel, Bart.VanAssche, hch, nab
  Cc: giridhar.malavali, linux-scsi, himanshu.madhani

Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
signed-off-by: Giridhar Malavali <giridhar.malavali@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 3cb1964..45bc84e 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,9 +7,9 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.07.00.38-k"
+#define QLA2XXX_VERSION      "9.00.00.00-k"
 
-#define QLA_DRIVER_MAJOR_VER	8
-#define QLA_DRIVER_MINOR_VER	7
+#define QLA_DRIVER_MAJOR_VER	9
+#define QLA_DRIVER_MINOR_VER	0
 #define QLA_DRIVER_PATCH_VER	0
 #define QLA_DRIVER_BETA_VER	0
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 06/14] qla2xxx: Improve T10-DIF/PI handling in driver.
  2017-02-03 22:40 ` [PATCH v2 06/14] qla2xxx: Improve T10-DIF/PI handling in driver Himanshu Madhani
@ 2017-02-08  4:13   ` Nicholas A. Bellinger
  2017-02-08 19:12     ` Madhani, Himanshu
  2017-02-08 18:57   ` Bart Van Assche
  1 sibling, 1 reply; 30+ messages in thread
From: Nicholas A. Bellinger @ 2017-02-08  4:13 UTC (permalink / raw)
  To: Himanshu Madhani
  Cc: target-devel, Bart.VanAssche, hch, giridhar.malavali, linux-scsi

On Fri, 2017-02-03 at 14:40 -0800, Himanshu Madhani wrote:
> From: Quinn Tran <quinn.tran@cavium.com>
> 
> Add routines to support T10 DIF tag.
> 
> Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
> Signed-off-by: Anil Gurumurthy <anil.gurumurthy@cavium.com>
> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
> ---
>  drivers/scsi/qla2xxx/qla_dbg.h     |   1 +
>  drivers/scsi/qla2xxx/qla_def.h     |  17 ++
>  drivers/scsi/qla2xxx/qla_target.c  | 598 +++++++++++++++++++++----------------
>  drivers/scsi/qla2xxx/qla_target.h  |  37 ++-
>  drivers/scsi/qla2xxx/tcm_qla2xxx.c |  84 +++++-
>  5 files changed, 465 insertions(+), 272 deletions(-)
> 
> diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
> index e1fc4e6..c6bffe9 100644
> --- a/drivers/scsi/qla2xxx/qla_dbg.h
> +++ b/drivers/scsi/qla2xxx/qla_dbg.h
> @@ -348,6 +348,7 @@ void __attribute__((format (printf, 4, 5)))
>  #define ql_dbg_tgt	0x00004000 /* Target mode */
>  #define ql_dbg_tgt_mgt	0x00002000 /* Target mode management */
>  #define ql_dbg_tgt_tmr	0x00001000 /* Target mode task management */
> +#define ql_dbg_tgt_dif  0x00000800 /* Target mode dif */
>  
>  extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *,
>  	uint32_t, void **);
> diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
> index 8bc1111..d6436fc 100644
> --- a/drivers/scsi/qla2xxx/qla_def.h
> +++ b/drivers/scsi/qla2xxx/qla_def.h
> @@ -2189,6 +2189,23 @@ struct qlt_plogi_ack_t {
>  	void		*fcport;
>  };
>  
> +enum qla_tgt_prot_op {
> +	QLA_PROT_NORMAL  = 0,
> +	QLA_PROT_DIN_INSERT,
> +	QLA_PROT_DOUT_INSERT,
> +	QLA_PROT_DIN_STRIP,
> +	QLA_PROT_DOUT_STRIP,
> +	QLA_PROT_DIN_PASS,
> +	QLA_PROT_DOUT_PASS,
> +};
> +
> +enum qla_tgt_prot_type {
> +	QLA_TGT_PROT_TYPE0,
> +	QLA_TGT_PROT_TYPE1,
> +	QLA_TGT_PROT_TYPE2,
> +	QLA_TGT_PROT_TYPE3,
> +};
> +

I don't get it, why are you duplicating target_prot_op and
target_prot_type..?

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 03/14] qla2xxx: Allow vref count to timeout on vport delete.
  2017-02-03 22:40 ` [PATCH v2 03/14] qla2xxx: Allow vref count to timeout on vport delete Himanshu Madhani
@ 2017-02-08 13:03   ` Christoph Hellwig
  2017-02-08 18:25     ` Madhani, Himanshu
  0 siblings, 1 reply; 30+ messages in thread
From: Christoph Hellwig @ 2017-02-08 13:03 UTC (permalink / raw)
  To: Himanshu Madhani
  Cc: target-devel, Bart.VanAssche, hch, nab, giridhar.malavali, linux-scsi

On Fri, Feb 03, 2017 at 02:40:44PM -0800, Himanshu Madhani wrote:
> -	spin_lock_irqsave(&ha->vport_slock, flags);
> -	while (atomic_read(&vha->vref_count)) {
> -		spin_unlock_irqrestore(&ha->vport_slock, flags);
> -
> +	while (count-- && atomic_read(&vha->vref_count))
>  		msleep(500);

Please add a wait queue to skeep on while waiting for vref_count to
drop to zero.  

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target.
  2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
                   ` (13 preceding siblings ...)
  2017-02-03 22:40 ` [PATCH v2 14/14] qla2xxx: Update driver version to 9.00.00.00-k Himanshu Madhani
@ 2017-02-08 15:02 ` Bart Van Assche
  2017-02-08 17:11   ` Madhani, Himanshu
  14 siblings, 1 reply; 30+ messages in thread
From: Bart Van Assche @ 2017-02-08 15:02 UTC (permalink / raw)
  To: hch, himanshu.madhani, target-devel, nab; +Cc: linux-scsi, giridhar.malavali

On Fri, 2017-02-03 at 14:40 -0800, Himanshu Madhani wrote:
> Please consider this series for inclusion in target-pending.

Hello Himanshu,

I gave this patch series a try on a system equipped with two QLogic FC HBAs
where an FC cable connects both HBAs to each other. qlini_mode has been set
to "dual" such that both ports support initiator and target mode. Without this
patch series both ports log in to each other and lsscsi shows several LUNs.
With this patch series applied the two ports do not log in to each other
anymore and strange messages appear in the kernel log:

------------[ cut here ]------------
WARNING: CPU: 0 PID: 5 at lib/kobject.c:244 kobject_add_internal+0x118/0x350
kobject_add_internal failed for 3:0:0:0 (error: -2 parent: target3:0:0)
Modules linked in: target_core_pscsi target_core_iblock target_core_file tcm_qla2xxx target_core_mod fcoe libfcoe libfc qla2xxx scsi_transport_fc netconsole af_packet hid_generic usbhid hid sg virtio_balloon i2c_piix4 acpi_cpufreq button ib_iser rdma_cm iw_cm ib_cm ib_core configfs iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi autofs4 ext4 crc16 jbd2 mbcache sr_mod cdrom ata_generic pata_acpi virtio_net virtio_blk virtio_gpu drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm i2c_core ata_piix xhci_pci libata xhci_hcd intel_agp usbcore intel_gtt virtio_pci scsi_mod virtio_ring usb_common agpgart virtio
CPU: 0 PID: 5 Comm: kworker/u16:0 Not tainted 4.10.0-rc6-dbg+ #1
Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
Workqueue: scsi_wq_3 fc_scsi_scan_rport [scsi_transport_fc]
Call Trace:
 dump_stack+0x85/0xc2
 __warn+0xcb/0xf0
 warn_slowpath_fmt+0x4f/0x60
 kobject_add_internal+0x118/0x350
 kobject_add+0x68/0xb0
 device_add+0xfa/0x600
 scsi_sysfs_add_sdev+0x8e/0x270 [scsi_mod]
 scsi_probe_and_add_lun+0xca1/0xe30 [scsi_mod]
 __scsi_scan_target+0xd3/0x5f0 [scsi_mod]
 scsi_scan_target+0xf1/0x100 [scsi_mod]
 fc_scsi_scan_rport+0xc0/0xd0 [scsi_transport_fc]
 process_one_work+0x1f4/0x6e0
 worker_thread+0x4e/0x4a0
 kthread+0x10c/0x140
 ret_from_fork+0x31/0x40
---[ end trace 86f40b52873f9529 ]---
scsi 3:0:0:0: failed to add device: -2

Bart.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target.
  2017-02-08 15:02 ` [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Bart Van Assche
@ 2017-02-08 17:11   ` Madhani, Himanshu
  0 siblings, 0 replies; 30+ messages in thread
From: Madhani, Himanshu @ 2017-02-08 17:11 UTC (permalink / raw)
  To: Bart Van Assche, hch, target-devel, nab; +Cc: linux-scsi, Malavali, Giridhar

Hi Bart, 



On 2/8/17, 7:02 AM, "Bart Van Assche" <Bart.VanAssche@sandisk.com> wrote:

>On Fri, 2017-02-03 at 14:40 -0800, Himanshu Madhani wrote:
>> Please consider this series for inclusion in target-pending.
>
>Hello Himanshu,
>
>I gave this patch series a try on a system equipped with two QLogic FC HBAs
>where an FC cable connects both HBAs to each other. qlini_mode has been set
>to "dual" such that both ports support initiator and target mode. Without this
>patch series both ports log in to each other and lsscsi shows several LUNs.
>With this patch series applied the two ports do not log in to each other
>anymore and strange messages appear in the kernel log:
>
>------------[ cut here ]------------
>WARNING: CPU: 0 PID: 5 at lib/kobject.c:244 kobject_add_internal+0x118/0x350
>kobject_add_internal failed for 3:0:0:0 (error: -2 parent: target3:0:0)
>Modules linked in: target_core_pscsi target_core_iblock target_core_file tcm_qla2xxx target_core_mod fcoe libfcoe libfc qla2xxx scsi_transport_fc netconsole af_packet hid_generic usbhid hid sg virtio_balloon i2c_piix4 acpi_cpufreq button ib_iser rdma_cm iw_cm ib_cm ib_core configfs iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi autofs4 ext4 crc16 jbd2 mbcache sr_mod cdrom ata_generic pata_acpi virtio_net virtio_blk virtio_gpu drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm i2c_core ata_piix xhci_pci libata xhci_hcd intel_agp usbcore intel_gtt virtio_pci scsi_mod virtio_ring usb_common agpgart virtio
>CPU: 0 PID: 5 Comm: kworker/u16:0 Not tainted 4.10.0-rc6-dbg+ #1
>Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
>Workqueue: scsi_wq_3 fc_scsi_scan_rport [scsi_transport_fc]
>Call Trace:
> dump_stack+0x85/0xc2
> __warn+0xcb/0xf0
> warn_slowpath_fmt+0x4f/0x60
> kobject_add_internal+0x118/0x350
> kobject_add+0x68/0xb0
> device_add+0xfa/0x600
> scsi_sysfs_add_sdev+0x8e/0x270 [scsi_mod]
> scsi_probe_and_add_lun+0xca1/0xe30 [scsi_mod]
> __scsi_scan_target+0xd3/0x5f0 [scsi_mod]
> scsi_scan_target+0xf1/0x100 [scsi_mod]
> fc_scsi_scan_rport+0xc0/0xd0 [scsi_transport_fc]
> process_one_work+0x1f4/0x6e0
> worker_thread+0x4e/0x4a0
> kthread+0x10c/0x140
> ret_from_fork+0x31/0x40
>---[ end trace 86f40b52873f9529 ]---
>scsi 3:0:0:0: failed to add device: -2

I’ll try to reproduce this. We have not see this issue in our testing and post update. 

Thanks,
Himanshu

>
>Bart.
>Western Digital Corporation (and its subsidiaries) E-mail Confidentiality Notice & Disclaimer:
>
>This e-mail and any files transmitted with it may contain confidential or legally privileged information of WDC and/or its affiliates, and are intended solely for the use of the individual or entity to which they are addressed. If you are not the intended recipient, any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it, is prohibited. If you have received this e-mail in error, please notify the sender immediately and delete the e-mail in its entirety from your system.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 03/14] qla2xxx: Allow vref count to timeout on vport delete.
  2017-02-08 13:03   ` Christoph Hellwig
@ 2017-02-08 18:25     ` Madhani, Himanshu
  0 siblings, 0 replies; 30+ messages in thread
From: Madhani, Himanshu @ 2017-02-08 18:25 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: target-devel, Bart.VanAssche, nab, Malavali, Giridhar, linux-scsi


On 2/8/17, 5:03 AM, "Christoph Hellwig" <hch@infradead.org> wrote:

>On Fri, Feb 03, 2017 at 02:40:44PM -0800, Himanshu Madhani wrote:
>> -	spin_lock_irqsave(&ha->vport_slock, flags);
>> -	while (atomic_read(&vha->vref_count)) {
>> -		spin_unlock_irqrestore(&ha->vport_slock, flags);
>> -
>> +	while (count-- && atomic_read(&vha->vref_count))
>>  		msleep(500);
>
>Please add a wait queue to skeep on while waiting for vref_count to
>drop to zero.  

Thanks for the review. Will update patch and resend series.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 01/14] qla2xxx: Fix delayed response to command for loop mode/direct connect.
  2017-02-03 22:40 ` [PATCH v2 01/14] qla2xxx: Fix delayed response to command for loop mode/direct connect Himanshu Madhani
@ 2017-02-08 18:35   ` Bart Van Assche
  0 siblings, 0 replies; 30+ messages in thread
From: Bart Van Assche @ 2017-02-08 18:35 UTC (permalink / raw)
  To: hch, himanshu.madhani, target-devel, nab; +Cc: linux-scsi, giridhar.malavali

On Fri, 2017-02-03 at 14:40 -0800, Himanshu Madhani wrote:
> +static void qla2x00_iocb_work_fn(struct work_struct *work)
> +{
> +	struct scsi_qla_host *vha = container_of(work,
> +		struct scsi_qla_host, iocb_work);
> +	unsigned long flags;
> +	int cnt = 0;
> +
> +	while (!list_empty(&vha->work_list)) {
> +		qla2x00_do_work(vha);
> +		cnt++;
> +		if (cnt > 10)
> +			break;
> +	}
> +
> +	spin_lock_irqsave(&vha->work_lock, flags);
> +	vha->flags.iocb_work_sheduled = 0;
> +	spin_unlock_irqrestore(&vha->work_lock, flags);
> +}
> +
> +void qla2x00_schedule_work(struct scsi_qla_host *vha)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&vha->work_lock, flags);
> +	if (vha->flags.iocb_work_sheduled) {
> +		spin_unlock_irqrestore(&vha->work_lock, flags);
> +		return;
> +	}
> +	vha->flags.iocb_work_sheduled = 1;
> +	spin_unlock_irqrestore(&vha->work_lock, flags);
> +
> +	/*
> +	 * We're in the middle of bringing up the adapter.
> +	 * the scheduled work need to go out now.
> +	 */
> +	INIT_WORK(&vha->iocb_work, qla2x00_iocb_work_fn);
> +	schedule_work(&vha->iocb_work);
> +}

Please move the INIT_WORK() call to an initialization function such that
is executed once instead of during every qla2x00_schedule_work() call. Please
also remove the iocb_work_sheduled variable and all code that tests and sets
it. schedule_work() already checks whether or not a work item has been
scheduled.

> @@ -4564,7 +4568,8 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
>  		}
>  
>  		if (sess != NULL) {
> -			if (sess->fw_login_state == DSC_LS_PLOGI_PEND) {
> +			if ((sess->fw_login_state != DSC_LS_PLOGI_PEND) &&
> +			    (sess->fw_login_state != DSC_LS_PLOGI_COMP)) {

The != operator has a higher precedence than the && operator so the parentheses
around the inequality test are not needed.

Bart.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 02/14] qla2xxx: Allow relogin to proceed if remote login did not finish
  2017-02-03 22:40 ` [PATCH v2 02/14] qla2xxx: Allow relogin to proceed if remote login did not finish Himanshu Madhani
@ 2017-02-08 18:42   ` Bart Van Assche
  2017-02-08 19:16     ` Madhani, Himanshu
  0 siblings, 1 reply; 30+ messages in thread
From: Bart Van Assche @ 2017-02-08 18:42 UTC (permalink / raw)
  To: hch, himanshu.madhani, target-devel, nab; +Cc: linux-scsi, giridhar.malavali

On Fri, 2017-02-03 at 14:40 -0800, Himanshu Madhani wrote:
> +	if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
> +		unsigned long t = fcport->plogi_nack_done_jiff + HZ;
> +
> +		if (time_before_eq(jiffies, t))
> +			return;
> +	}

The above code occurs two times in this patch. We try to avoid duplicating
code in the Linux kernel, especially code that contains hardcoded constants.
Have you considered to change the name of plogi_nack_done_jiff into e.g.
plogi_done_deadline and to assign jiffies + HZ to that variable instead of
jiffies?

Bart.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 04/14] qla2xxx: Use IOCB interface to submit non-critical MBX.
  2017-02-03 22:40 ` [PATCH v2 04/14] qla2xxx: Use IOCB interface to submit non-critical MBX Himanshu Madhani
@ 2017-02-08 18:48   ` Bart Van Assche
  2017-02-08 19:15     ` Madhani, Himanshu
  0 siblings, 1 reply; 30+ messages in thread
From: Bart Van Assche @ 2017-02-08 18:48 UTC (permalink / raw)
  To: hch, himanshu.madhani, target-devel, nab; +Cc: linux-scsi, giridhar.malavali

On Fri, 2017-02-03 at 14:40 -0800, Himanshu Madhani wrote:
> diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
> index db6bd92..4225256 100644
> --- a/drivers/scsi/qla2xxx/qla_mbx.c
> +++ b/drivers/scsi/qla2xxx/qla_mbx.c
> @@ -10,6 +10,29 @@
>  #include <linux/delay.h>
>  #include <linux/gfp.h>
>  
> +static struct mb_cmd_name {
> +	uint16_t cmd;
> +	char *str;
> +} mb_str[] = {
> +	{0xffff,		"unknown"},
> +	{MBC_GET_PORT_DATABASE,	"GPDB"},
> +	{MBC_GET_ID_LIST,	"GIDList"},
> +	{MBC_GET_LINK_PRIV_STATS, "Stats"},
> +};
> +
> +static char *mb_to_str(uint16_t cmd)
> +{
> +	int i;
> +	struct mb_cmd_name *e;
> +
> +	for (i = 0; i < ARRAY_SIZE(mb_str); i++) {
> +		e = mb_str + i;
> +		if (cmd == e->cmd)
> +			return e->str;
> +	}
> +	return mb_str[0].str; /* unknown */
> +}

Please use const char * instead of char * in the struct definition and for
the mb_to_str() function return type. Please also leave out the element with
index 0xffff from the mb_str[] array and make mb_to_str() return "unknown"
instead of mb_str[0].str if lookup fails.

Bart.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 06/14] qla2xxx: Improve T10-DIF/PI handling in driver.
  2017-02-03 22:40 ` [PATCH v2 06/14] qla2xxx: Improve T10-DIF/PI handling in driver Himanshu Madhani
  2017-02-08  4:13   ` Nicholas A. Bellinger
@ 2017-02-08 18:57   ` Bart Van Assche
  2017-02-08 19:11     ` Madhani, Himanshu
  1 sibling, 1 reply; 30+ messages in thread
From: Bart Van Assche @ 2017-02-08 18:57 UTC (permalink / raw)
  To: hch, himanshu.madhani, target-devel, nab; +Cc: linux-scsi, giridhar.malavali

On Fri, 2017-02-03 at 14:40 -0800, Himanshu Madhani wrote:
> +	/* Response code and sense key */
> +	((uint32_t *)ctio->u.status1.sense_data)[0] =
> +	    cpu_to_le32((0x70 << 24) | (sense_key << 8));
> +	/* Additional sense length */
> +	((uint32_t *)ctio->u.status1.sense_data)[1] = cpu_to_le32(0x0a);
> +	/* ASC and ASCQ */
> +	((uint32_t *)ctio->u.status1.sense_data)[3] =
> +	    cpu_to_le32((asc << 24) | (ascq << 16));

Please use put_unaligned_le32() instead of open-coding it.

>  struct qla_tgt_cmd {
> @@ -885,11 +895,25 @@ struct qla_tgt_cmd {
>  	struct list_head cmd_list;
>  
>  	struct atio_from_isp atio;
> -	/* t10dif */
> +
> +	/* T10-DIF */
> +#define DIF_ERR_NONE 0
> +#define DIF_ERR_GRD 1
> +#define DIF_ERR_REF 2
> +#define DIF_ERR_APP 3
> +	int8_t dif_err_code;
>  	struct scatterlist *prot_sg;
>  	uint32_t prot_sg_cnt;
> -	uint32_t blk_sz;
> +	uint32_t blk_sz, num_blks;
> +	uint8_t scsi_status, sense_key, asc, ascq;
> +
>  	struct crc_context *ctx;
> +	uint32_t	prot_op;
> +	uint32_t	prot_type;
> +	uint8_t		*cdb;
> +	uint64_t	lba;
> +	uint16_t	a_guard, e_guard, a_app_tag, e_app_tag;
> +	uint32_t	a_ref_tag, e_ref_tag;
>  
>  	uint64_t jiffies_at_alloc;
>  	uint64_t jiffies_at_free;

There are already equivalents of prot_op, prot_type, cdb and lba in struct
se_cmd. I think a few weeks ago Christoph had asked you not to duplicate
se_cmd fields into struct qla_tgt_cmd?

Bart.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 06/14] qla2xxx: Improve T10-DIF/PI handling in driver.
  2017-02-08 18:57   ` Bart Van Assche
@ 2017-02-08 19:11     ` Madhani, Himanshu
  0 siblings, 0 replies; 30+ messages in thread
From: Madhani, Himanshu @ 2017-02-08 19:11 UTC (permalink / raw)
  To: Bart Van Assche, hch, target-devel, nab; +Cc: linux-scsi, Malavali, Giridhar

Hi Bart, 



On 2/8/17, 10:57 AM, "Bart Van Assche" <Bart.VanAssche@sandisk.com> wrote:

>On Fri, 2017-02-03 at 14:40 -0800, Himanshu Madhani wrote:
>> +	/* Response code and sense key */
>> +	((uint32_t *)ctio->u.status1.sense_data)[0] =
>> +	    cpu_to_le32((0x70 << 24) | (sense_key << 8));
>> +	/* Additional sense length */
>> +	((uint32_t *)ctio->u.status1.sense_data)[1] = cpu_to_le32(0x0a);
>> +	/* ASC and ASCQ */
>> +	((uint32_t *)ctio->u.status1.sense_data)[3] =
>> +	    cpu_to_le32((asc << 24) | (ascq << 16));
>
>Please use put_unaligned_le32() instead of open-coding it.
>
>>  struct qla_tgt_cmd {
>> @@ -885,11 +895,25 @@ struct qla_tgt_cmd {
>>  	struct list_head cmd_list;
>>  
>>  	struct atio_from_isp atio;
>> -	/* t10dif */
>> +
>> +	/* T10-DIF */
>> +#define DIF_ERR_NONE 0
>> +#define DIF_ERR_GRD 1
>> +#define DIF_ERR_REF 2
>> +#define DIF_ERR_APP 3
>> +	int8_t dif_err_code;
>>  	struct scatterlist *prot_sg;
>>  	uint32_t prot_sg_cnt;
>> -	uint32_t blk_sz;
>> +	uint32_t blk_sz, num_blks;
>> +	uint8_t scsi_status, sense_key, asc, ascq;
>> +
>>  	struct crc_context *ctx;
>> +	uint32_t	prot_op;
>> +	uint32_t	prot_type;
>> +	uint8_t		*cdb;
>> +	uint64_t	lba;
>> +	uint16_t	a_guard, e_guard, a_app_tag, e_app_tag;
>> +	uint32_t	a_ref_tag, e_ref_tag;
>>  
>>  	uint64_t jiffies_at_alloc;
>>  	uint64_t jiffies_at_free;
>
>There are already equivalents of prot_op, prot_type, cdb and lba in struct
>se_cmd. I think a few weeks ago Christoph had asked you not to duplicate
>se_cmd fields into struct qla_tgt_cmd?

Thanks for the review comments.  Looks like that was a miss in rebasing with latest patch. 

Will fix up patch and resend. 

>
>Bart.
>Western Digital Corporation (and its subsidiaries) E-mail Confidentiality Notice & Disclaimer:
>
>This e-mail and any files transmitted with it may contain confidential or legally privileged information of WDC and/or its affiliates, and are intended solely for the use of the individual or entity to which they are addressed. If you are not the intended recipient, any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it, is prohibited. If you have received this e-mail in error, please notify the sender immediately and delete the e-mail in its entirety from your system.
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 06/14] qla2xxx: Improve T10-DIF/PI handling in driver.
  2017-02-08  4:13   ` Nicholas A. Bellinger
@ 2017-02-08 19:12     ` Madhani, Himanshu
  0 siblings, 0 replies; 30+ messages in thread
From: Madhani, Himanshu @ 2017-02-08 19:12 UTC (permalink / raw)
  To: Nicholas A. Bellinger
  Cc: target-devel, Bart.VanAssche, hch, Malavali, Giridhar, linux-scsi

Hi Nic,



On 2/7/17, 8:13 PM, "Nicholas A. Bellinger" <nab@linux-iscsi.org> wrote:

>On Fri, 2017-02-03 at 14:40 -0800, Himanshu Madhani wrote:
>> From: Quinn Tran <quinn.tran@cavium.com>
>> 
>> Add routines to support T10 DIF tag.
>> 
>> Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
>> Signed-off-by: Anil Gurumurthy <anil.gurumurthy@cavium.com>
>> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
>> ---
>>  drivers/scsi/qla2xxx/qla_dbg.h     |   1 +
>>  drivers/scsi/qla2xxx/qla_def.h     |  17 ++
>>  drivers/scsi/qla2xxx/qla_target.c  | 598 +++++++++++++++++++++----------------
>>  drivers/scsi/qla2xxx/qla_target.h  |  37 ++-
>>  drivers/scsi/qla2xxx/tcm_qla2xxx.c |  84 +++++-
>>  5 files changed, 465 insertions(+), 272 deletions(-)
>> 
>> diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
>> index e1fc4e6..c6bffe9 100644
>> --- a/drivers/scsi/qla2xxx/qla_dbg.h
>> +++ b/drivers/scsi/qla2xxx/qla_dbg.h
>> @@ -348,6 +348,7 @@ void __attribute__((format (printf, 4, 5)))
>>  #define ql_dbg_tgt	0x00004000 /* Target mode */
>>  #define ql_dbg_tgt_mgt	0x00002000 /* Target mode management */
>>  #define ql_dbg_tgt_tmr	0x00001000 /* Target mode task management */
>> +#define ql_dbg_tgt_dif  0x00000800 /* Target mode dif */
>>  
>>  extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *,
>>  	uint32_t, void **);
>> diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
>> index 8bc1111..d6436fc 100644
>> --- a/drivers/scsi/qla2xxx/qla_def.h
>> +++ b/drivers/scsi/qla2xxx/qla_def.h
>> @@ -2189,6 +2189,23 @@ struct qlt_plogi_ack_t {
>>  	void		*fcport;
>>  };
>>  
>> +enum qla_tgt_prot_op {
>> +	QLA_PROT_NORMAL  = 0,
>> +	QLA_PROT_DIN_INSERT,
>> +	QLA_PROT_DOUT_INSERT,
>> +	QLA_PROT_DIN_STRIP,
>> +	QLA_PROT_DOUT_STRIP,
>> +	QLA_PROT_DIN_PASS,
>> +	QLA_PROT_DOUT_PASS,
>> +};
>> +
>> +enum qla_tgt_prot_type {
>> +	QLA_TGT_PROT_TYPE0,
>> +	QLA_TGT_PROT_TYPE1,
>> +	QLA_TGT_PROT_TYPE2,
>> +	QLA_TGT_PROT_TYPE3,
>> +};
>> +
>
>I don't get it, why are you duplicating target_prot_op and
>target_prot_type..?

We will fix it and resubmit this. 

Thanks,
Himanshu

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 04/14] qla2xxx: Use IOCB interface to submit non-critical MBX.
  2017-02-08 18:48   ` Bart Van Assche
@ 2017-02-08 19:15     ` Madhani, Himanshu
  0 siblings, 0 replies; 30+ messages in thread
From: Madhani, Himanshu @ 2017-02-08 19:15 UTC (permalink / raw)
  To: Bart Van Assche, hch, target-devel, nab; +Cc: linux-scsi, Malavali, Giridhar


On 2/8/17, 10:48 AM, "Bart Van Assche" <Bart.VanAssche@sandisk.com> wrote:

>On Fri, 2017-02-03 at 14:40 -0800, Himanshu Madhani wrote:
>> diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
>> index db6bd92..4225256 100644
>> --- a/drivers/scsi/qla2xxx/qla_mbx.c
>> +++ b/drivers/scsi/qla2xxx/qla_mbx.c
>> @@ -10,6 +10,29 @@
>>  #include <linux/delay.h>
>>  #include <linux/gfp.h>
>>  
>> +static struct mb_cmd_name {
>> +	uint16_t cmd;
>> +	char *str;
>> +} mb_str[] = {
>> +	{0xffff,		"unknown"},
>> +	{MBC_GET_PORT_DATABASE,	"GPDB"},
>> +	{MBC_GET_ID_LIST,	"GIDList"},
>> +	{MBC_GET_LINK_PRIV_STATS, "Stats"},
>> +};
>> +
>> +static char *mb_to_str(uint16_t cmd)
>> +{
>> +	int i;
>> +	struct mb_cmd_name *e;
>> +
>> +	for (i = 0; i < ARRAY_SIZE(mb_str); i++) {
>> +		e = mb_str + i;
>> +		if (cmd == e->cmd)
>> +			return e->str;
>> +	}
>> +	return mb_str[0].str; /* unknown */
>> +}
>
>Please use const char * instead of char * in the struct definition and for
>the mb_to_str() function return type. Please also leave out the element with
>index 0xffff from the mb_str[] array and make mb_to_str() return "unknown"
>instead of mb_str[0].str if lookup fails.

Will update patch and resend. 

>
>Bart.
>Western Digital Corporation (and its subsidiaries) E-mail Confidentiality Notice & Disclaimer:
>
>This e-mail and any files transmitted with it may contain confidential or legally privileged information of WDC and/or its affiliates, and are intended solely for the use of the individual or entity to which they are addressed. If you are not the intended recipient, any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it, is prohibited. If you have received this e-mail in error, please notify the sender immediately and delete the e-mail in its entirety from your system.
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 02/14] qla2xxx: Allow relogin to proceed if remote login did not finish
  2017-02-08 18:42   ` Bart Van Assche
@ 2017-02-08 19:16     ` Madhani, Himanshu
  0 siblings, 0 replies; 30+ messages in thread
From: Madhani, Himanshu @ 2017-02-08 19:16 UTC (permalink / raw)
  To: Bart Van Assche, hch, target-devel, nab; +Cc: linux-scsi, Malavali, Giridhar



On 2/8/17, 10:42 AM, "Bart Van Assche" <Bart.VanAssche@sandisk.com> wrote:

>The above code occurs two times in this patch. We try to avoid duplicating
>code in the Linux kernel, especially code that contains hardcoded constants.
>Have you considered to change the name of plogi_nack_done_jiff into e.g.
>plogi_done_deadline and to assign jiffies + HZ to that variable instead of
>jiffies?

Thanks for the review. Will update patch and resend series. 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 10/14] qla2xxx: Fix request queue corruption.
  2017-02-03 22:40 ` [PATCH v2 10/14] qla2xxx: Fix request queue corruption Himanshu Madhani
@ 2017-02-08 19:22   ` Bart Van Assche
  2017-02-09 21:34     ` Tran, Quinn
  0 siblings, 1 reply; 30+ messages in thread
From: Bart Van Assche @ 2017-02-08 19:22 UTC (permalink / raw)
  To: hch, himanshu.madhani, target-devel, nab; +Cc: linux-scsi, giridhar.malavali

On Fri, 2017-02-03 at 14:40 -0800, Himanshu Madhani wrote:
> From: Quinn Tran <quinn.tran@cavium.com>
> 
> When FW notify driver or driver detects low FW resource,
> driver tries to send out Busy SCSI Status to tell Initiator
> side to back off. During the send process, the lock was not held.
> 
> Signed-off-by: Quinn Tran <quinn.tran@qlogic.com>
> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
> ---
>  drivers/scsi/qla2xxx/qla_target.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
> index b61cbb8..b5fb9c55 100644
> --- a/drivers/scsi/qla2xxx/qla_target.c
> +++ b/drivers/scsi/qla2xxx/qla_target.c
> @@ -5170,16 +5170,22 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
>  
>  static int
>  qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha,
> -	struct atio_from_isp *atio)
> +	struct atio_from_isp *atio, uint8_t ha_locked)
>  {
>  	struct qla_hw_data *ha = vha->hw;
>  	uint16_t status;
> +	unsigned long flags;
>  
>  	if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha))
>  		return 0;
>  
> +	if (!ha_locked)
> +		spin_lock_irqsave(&ha->hardware_lock, flags);
>  	status = temp_sam_status;
>  	qlt_send_busy(vha, atio, status);
> +	if (!ha_locked)
> +		spin_unlock_irqrestore(&ha->hardware_lock, flags);
> +
>  	return 1;
>  }
>  
> @@ -5224,7 +5230,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
>  
>  
>  		if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) {
> -			rc = qlt_chk_qfull_thresh_hold(vha, atio);
> +			rc = qlt_chk_qfull_thresh_hold(vha, atio, ha_locked);
>  			if (rc != 0) {
>  				tgt->atio_irq_cmd_count--;
>  				return;
> @@ -5347,7 +5353,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
>  			break;
>  		}
>  
> -		rc = qlt_chk_qfull_thresh_hold(vha, atio);
> +		rc = qlt_chk_qfull_thresh_hold(vha, atio, 1);
>  		if (rc != 0) {
>  			tgt->irq_cmd_count--;
>  			return;

Hello Quinn,

Please consider to use bool instead of uint8_t for ha_locked and true /
false instead of 1 / 0.

Bart.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 10/14] qla2xxx: Fix request queue corruption.
  2017-02-08 19:22   ` Bart Van Assche
@ 2017-02-09 21:34     ` Tran, Quinn
  0 siblings, 0 replies; 30+ messages in thread
From: Tran, Quinn @ 2017-02-09 21:34 UTC (permalink / raw)
  To: Bart Van Assche, hch, Madhani, Himanshu, target-devel, nab
  Cc: linux-scsi, Malavali, Giridhar

Bart, thanks for reviewing.  Will clean it up.

Regards,
Quinn Tran

-----Original Message-----
From: <linux-scsi-owner@vger.kernel.org> on behalf of Bart Van Assche <Bart.VanAssche@sandisk.com>
Date: Wednesday, February 8, 2017 at 11:22 AM
To: "hch@infradead.org" <hch@infradead.org>, "Madhani, Himanshu" <Himanshu.Madhani@cavium.com>, target-devel <target-devel@vger.kernel.org>, Nicholas Bellinger <nab@linux-iscsi.org>
Cc: "linux-scsi@vger.kernel.org" <linux-scsi@vger.kernel.org>, "Malavali, Giridhar" <Giridhar.Malavali@cavium.com>
Subject: Re: [PATCH v2 10/14] qla2xxx: Fix request queue corruption.
Resent-From: <quinn.tran@qlogic.com>

    On Fri, 2017-02-03 at 14:40 -0800, Himanshu Madhani wrote:
    > From: Quinn Tran <quinn.tran@cavium.com>
    > 
    > When FW notify driver or driver detects low FW resource,
    > driver tries to send out Busy SCSI Status to tell Initiator
    > side to back off. During the send process, the lock was not held.
    > 
    > Signed-off-by: Quinn Tran <quinn.tran@qlogic.com>
    > Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
    > ---
    >  drivers/scsi/qla2xxx/qla_target.c | 12 +++++++++---
    >  1 file changed, 9 insertions(+), 3 deletions(-)
    > 
    > diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
    > index b61cbb8..b5fb9c55 100644
    > --- a/drivers/scsi/qla2xxx/qla_target.c
    > +++ b/drivers/scsi/qla2xxx/qla_target.c
    > @@ -5170,16 +5170,22 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
    >  
    >  static int
    >  qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha,
    > -	struct atio_from_isp *atio)
    > +	struct atio_from_isp *atio, uint8_t ha_locked)
    >  {
    >  	struct qla_hw_data *ha = vha->hw;
    >  	uint16_t status;
    > +	unsigned long flags;
    >  
    >  	if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha))
    >  		return 0;
    >  
    > +	if (!ha_locked)
    > +		spin_lock_irqsave(&ha->hardware_lock, flags);
    >  	status = temp_sam_status;
    >  	qlt_send_busy(vha, atio, status);
    > +	if (!ha_locked)
    > +		spin_unlock_irqrestore(&ha->hardware_lock, flags);
    > +
    >  	return 1;
    >  }
    >  
    > @@ -5224,7 +5230,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
    >  
    >  
    >  		if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) {
    > -			rc = qlt_chk_qfull_thresh_hold(vha, atio);
    > +			rc = qlt_chk_qfull_thresh_hold(vha, atio, ha_locked);
    >  			if (rc != 0) {
    >  				tgt->atio_irq_cmd_count--;
    >  				return;
    > @@ -5347,7 +5353,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
    >  			break;
    >  		}
    >  
    > -		rc = qlt_chk_qfull_thresh_hold(vha, atio);
    > +		rc = qlt_chk_qfull_thresh_hold(vha, atio, 1);
    >  		if (rc != 0) {
    >  			tgt->irq_cmd_count--;
    >  			return;
    
    Hello Quinn,
    
    Please consider to use bool instead of uint8_t for ha_locked and true /
    false instead of 1 / 0.
    
    Bart.
    


^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2017-02-09 21:34 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-03 22:40 [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Himanshu Madhani
2017-02-03 22:40 ` [PATCH v2 01/14] qla2xxx: Fix delayed response to command for loop mode/direct connect Himanshu Madhani
2017-02-08 18:35   ` Bart Van Assche
2017-02-03 22:40 ` [PATCH v2 02/14] qla2xxx: Allow relogin to proceed if remote login did not finish Himanshu Madhani
2017-02-08 18:42   ` Bart Van Assche
2017-02-08 19:16     ` Madhani, Himanshu
2017-02-03 22:40 ` [PATCH v2 03/14] qla2xxx: Allow vref count to timeout on vport delete Himanshu Madhani
2017-02-08 13:03   ` Christoph Hellwig
2017-02-08 18:25     ` Madhani, Himanshu
2017-02-03 22:40 ` [PATCH v2 04/14] qla2xxx: Use IOCB interface to submit non-critical MBX Himanshu Madhani
2017-02-08 18:48   ` Bart Van Assche
2017-02-08 19:15     ` Madhani, Himanshu
2017-02-03 22:40 ` [PATCH v2 05/14] qla2xxx: Add DebugFS node to display Port Database Himanshu Madhani
2017-02-03 22:40 ` [PATCH v2 06/14] qla2xxx: Improve T10-DIF/PI handling in driver Himanshu Madhani
2017-02-08  4:13   ` Nicholas A. Bellinger
2017-02-08 19:12     ` Madhani, Himanshu
2017-02-08 18:57   ` Bart Van Assche
2017-02-08 19:11     ` Madhani, Himanshu
2017-02-03 22:40 ` [PATCH v2 07/14] qla2xxx: Export DIF stats via debugfs Himanshu Madhani
2017-02-03 22:40 ` [PATCH v2 08/14] qla2xxx: Change scsi host lookup method Himanshu Madhani
2017-02-03 22:40 ` [PATCH v2 09/14] qla2xxx: Fix memory leak for abts processing Himanshu Madhani
2017-02-03 22:40 ` [PATCH v2 10/14] qla2xxx: Fix request queue corruption Himanshu Madhani
2017-02-08 19:22   ` Bart Van Assche
2017-02-09 21:34     ` Tran, Quinn
2017-02-03 22:40 ` [PATCH v2 11/14] qla2xxx: Fix inadequate lock protection for ABTS Himanshu Madhani
2017-02-03 22:40 ` [PATCH v2 12/14] qla2xxx: Add async new target notification Himanshu Madhani
2017-02-03 22:40 ` [PATCH v2 13/14] qla2xxx: Fix sess_lock & hardware_lock lock order problem Himanshu Madhani
2017-02-03 22:40 ` [PATCH v2 14/14] qla2xxx: Update driver version to 9.00.00.00-k Himanshu Madhani
2017-02-08 15:02 ` [PATCH v2 00/14] qla2xxx: Bug Fixes and updates for target Bart Van Assche
2017-02-08 17:11   ` Madhani, Himanshu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.