[PATCH 1/8] qla2xxx: Retry PLOGI on FC-NVMe PRLI failure

Himanshu Madhani
2019-11-05T15:07:08Z

From: Quinn Tran <qutran@marvell.com>

Current code will send PRLI with FC-NVMe bit set for the
targets which supports only FCP. This may result into issue
with targets which do not understand NVMe and will go into
strange state. This patch would restart the login process
by going back to PLOGI state. The PLOGI state will force the
target to respond to correct PRLI request.

Fixes: c76ae845ea836 ("scsi: qla2xxx: Add error handling for PLOGI ELS passthrough")
Cc: stable@vger.kernel.org # 5.4
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
---
drivers/scsi/qla2xxx/qla_init.c | 37 ++++++++-----------------------------
drivers/scsi/qla2xxx/qla_iocb.c | 6 +++++-
2 files changed, 13 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 7cb7545de962..5db8ad832893 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1864,42 +1864,21 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
* FCP/NVMe port
*/
if (NVME_FCP_TARGET(ea->fcport)) {
- if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
- ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
- else
- ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
ql_dbg(ql_dbg_disc, vha, 0x2118,
"%s %d %8phC post %s prli\n",
__func__, __LINE__, ea->fcport->port_name,
(ea->fcport->fc4_type & FS_FC4TYPE_NVME) ?
"NVMe" : "FCP");
- qla24xx_post_prli_work(vha, ea->fcport);
- break;
+ if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
+ ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
+ else
+ ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
}

- /* at this point both PRLI NVME & PRLI FCP failed */
- if (N2N_TOPO(vha->hw)) {
- if (ea->fcport->n2n_link_reset_cnt < 3) {
- ea->fcport->n2n_link_reset_cnt++;
- /*
- * remote port is not sending Plogi. Reset
- * link to kick start his state machine
- */
- set_bit(N2N_LINK_RESET, &vha->dpc_flags);
- } else {
- ql_log(ql_log_warn, vha, 0x2119,
- "%s %d %8phC Unable to reconnect\n",
- __func__, __LINE__, ea->fcport->port_name);
- }
- } else {
- /*
- * switch connect. login failed. Take connection
- * down and allow relogin to retrigger
- */
- ea->fcport->flags &= ~FCF_ASYNC_SENT;
- ea->fcport->keep_nport_handle = 0;
- qlt_schedule_sess_for_deletion(ea->fcport);
- }
+ ea->fcport->flags &= ~FCF_ASYNC_SENT;
+ ea->fcport->keep_nport_handle = 0;
+ ea->fcport->logout_on_delete = 1;
+ qlt_schedule_sess_for_deletion(ea->fcport);
break;
}
}
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index eeb526411536..2b675da34bda 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -2764,6 +2764,7 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
ea.sp = sp;
qla24xx_handle_plogi_done_event(vha, &ea);
break;
+
case CS_IOCB_ERROR:
switch (fw_status[1]) {
case LSC_SCODE_PORTID_USED:
@@ -2834,6 +2835,7 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
fw_status[0], fw_status[1], fw_status[2]);

fcport->flags &= ~FCF_ASYNC_SENT;
+ fcport->disc_state = DSC_LOGIN_FAILED;
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
break;
}
@@ -2846,6 +2848,7 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
fw_status[0], fw_status[1], fw_status[2]);

sp->fcport->flags &= ~FCF_ASYNC_SENT;
+ sp->fcport->disc_state = DSC_LOGIN_FAILED;
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
break;
}
@@ -2881,11 +2884,12 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
return -ENOMEM;
}

+ fcport->flags |= FCF_ASYNC_SENT;
+ fcport->disc_state = DSC_LOGIN_PEND;
elsio = &sp->u.iocb_cmd;
ql_dbg(ql_dbg_io, vha, 0x3073,
"Enter: PLOGI portid=%06x\n", fcport->d_id.b24);

- fcport->flags |= FCF_ASYNC_SENT;
sp->type = SRB_ELS_DCMD;
sp->name = "ELS_DCMD";
sp->fcport = fcport;
--
2.12.0