Commit 881eb861 authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: Fix N2N stuck connection



Disk failed to rediscover after chip reset error injection. The chip reset
happens at the time when a PLOGI is being sent. This causes a flag to be
left on which blocks the retry. Clear the blocking flag.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarQuinn Tran <qutran@marvell.com>
Signed-off-by: default avatarNilesh Javali <njavali@marvell.com>
Link: https://lore.kernel.org/r/20240227164127.36465-3-njavali@marvell.com


Reviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 4895009c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);

extern int qla24xx_els_dcmd_iocb(scsi_qla_host_t *, int, port_id_t);
extern int qla24xx_els_dcmd2_iocb(scsi_qla_host_t *, int, fc_port_t *, bool);
extern int qla24xx_els_dcmd2_iocb(scsi_qla_host_t *, int, fc_port_t *);
extern void qla2x00_els_dcmd2_free(scsi_qla_host_t *vha,
				   struct els_plogi *els_plogi);

+11 −21
Original line number Diff line number Diff line
@@ -3041,7 +3041,7 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)

int
qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
    fc_port_t *fcport, bool wait)
			fc_port_t *fcport)
{
	srb_t *sp;
	struct srb_iocb *elsio = NULL;
@@ -3056,8 +3056,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
	if (!sp) {
		ql_log(ql_log_info, vha, 0x70e6,
		 "SRB allocation failed\n");
		fcport->flags &= ~FCF_ASYNC_ACTIVE;
		return -ENOMEM;
		goto done;
	}

	fcport->flags |= FCF_ASYNC_SENT;
@@ -3066,9 +3065,6 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
	ql_dbg(ql_dbg_io, vha, 0x3073,
	       "%s Enter: PLOGI portid=%06x\n", __func__, fcport->d_id.b24);

	if (wait)
		sp->flags = SRB_WAKEUP_ON_COMP;

	sp->type = SRB_ELS_DCMD;
	sp->name = "ELS_DCMD";
	sp->fcport = fcport;
@@ -3084,7 +3080,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,

	if (!elsio->u.els_plogi.els_plogi_pyld) {
		rval = QLA_FUNCTION_FAILED;
		goto out;
		goto done_free_sp;
	}

	resp_ptr = elsio->u.els_plogi.els_resp_pyld =
@@ -3093,7 +3089,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,

	if (!elsio->u.els_plogi.els_resp_pyld) {
		rval = QLA_FUNCTION_FAILED;
		goto out;
		goto done_free_sp;
	}

	ql_dbg(ql_dbg_io, vha, 0x3073, "PLOGI %p %p\n", ptr, resp_ptr);
@@ -3109,7 +3105,6 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,

	if (els_opcode == ELS_DCMD_PLOGI && DBELL_ACTIVE(vha)) {
		struct fc_els_flogi *p = ptr;

		p->fl_csp.sp_features |= cpu_to_be16(FC_SP_FT_SEC);
	}

@@ -3118,10 +3113,11 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
	    (uint8_t *)elsio->u.els_plogi.els_plogi_pyld,
	    sizeof(*elsio->u.els_plogi.els_plogi_pyld));

	init_completion(&elsio->u.els_plogi.comp);
	rval = qla2x00_start_sp(sp);
	if (rval != QLA_SUCCESS) {
		rval = QLA_FUNCTION_FAILED;
		fcport->flags |= FCF_LOGIN_NEEDED;
		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
		goto done_free_sp;
	} else {
		ql_dbg(ql_dbg_disc, vha, 0x3074,
		    "%s PLOGI sent, hdl=%x, loopid=%x, to port_id %06x from port_id %06x\n",
@@ -3129,21 +3125,15 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
		    fcport->d_id.b24, vha->d_id.b24);
	}

	if (wait) {
		wait_for_completion(&elsio->u.els_plogi.comp);

		if (elsio->u.els_plogi.comp_status != CS_COMPLETE)
			rval = QLA_FUNCTION_FAILED;
	} else {
		goto done;
	}
	return rval;

out:
	fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
done_free_sp:
	qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi);
	/* ref: INIT */
	kref_put(&sp->cmd_kref, qla2x00_sp_release);
done:
	fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
	qla2x00_set_fcport_disc_state(fcport, DSC_DELETED);
	return rval;
}

+1 −1
Original line number Diff line number Diff line
@@ -5583,7 +5583,7 @@ qla2x00_do_work(struct scsi_qla_host *vha)
			break;
		case QLA_EVT_ELS_PLOGI:
			qla24xx_els_dcmd2_iocb(vha, ELS_DCMD_PLOGI,
			    e->u.fcport.fcport, false);
			    e->u.fcport.fcport);
			break;
		case QLA_EVT_SA_REPLACE:
			rc = qla24xx_issue_sa_replace_iocb(vha, e);