Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 23dd98a6 authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: Fix login retry count



Login retry count was not properly decrementing which lead to endless
retry.

Signed-off-by: default avatarQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 48acad09
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -3475,6 +3475,14 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
			fcport->rscn_gen++;
			fcport->scan_state = QLA_FCPORT_FOUND;
			fcport->flags |= FCF_FABRIC_DEVICE;
			if (fcport->login_retry == 0) {
				fcport->login_retry =
					vha->hw->login_retry_count;
				ql_dbg(ql_dbg_disc, vha, 0xffff,
				    "Port login retry %8phN, lid 0x%04x cnt=%d.\n",
				    fcport->port_name, fcport->loop_id,
				    fcport->login_retry);
			}
			switch (fcport->disc_state) {
			case DSC_LOGIN_COMPLETE:
				/* recheck session is still intact. */
@@ -3967,6 +3975,14 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
		} else {
			if (fcport->rscn_rcvd ||
			    fcport->disc_state != DSC_LOGIN_COMPLETE) {
				if (fcport->login_retry == 0) {
					fcport->login_retry =
						vha->hw->login_retry_count;
					ql_dbg(ql_dbg_disc, vha, 0x20a3,
					    "Port login retry %8phN, lid 0x%04x retry cnt=%d.\n",
					    fcport->port_name, fcport->loop_id,
					    fcport->login_retry);
				}
				fcport->rscn_rcvd = 0;
				qla24xx_fcport_handle_login(vha, fcport);
			}
+5 −18
Original line number Diff line number Diff line
@@ -213,8 +213,6 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
		if (fcport->fc4f_nvme)
			lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI;

		if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
			lio->u.logio.flags |= SRB_LOGIN_RETRIED;
	}

	rval = qla2x00_start_sp(sp);
@@ -485,7 +483,6 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,

	if (ea->rc) { /* rval */
		if (fcport->login_retry == 0) {
			fcport->login_retry = vha->hw->login_retry_count;
			ql_dbg(ql_dbg_disc, vha, 0x20de,
			    "GNL failed Port login retry %8phN, retry cnt=%d.\n",
			    fcport->port_name, fcport->login_retry);
@@ -1256,11 +1253,10 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
		return 0;
	}

	if (fcport->login_retry > 0)
		fcport->login_retry--;

	switch (fcport->disc_state) {
	case DSC_DELETED:
		fcport->login_retry--;
		wwn = wwn_to_u64(fcport->node_name);
		if (wwn == 0) {
			ql_dbg(ql_dbg_disc, vha, 0xffff,
@@ -1273,6 +1269,7 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
			    __func__, __LINE__, fcport->port_name);
			qla24xx_post_gnl_work(vha, fcport);
		} else {
			fcport->login_retry--;
			qla_chk_n2n_b4_login(vha, fcport);
		}
		break;
@@ -1289,6 +1286,7 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
		break;

	case DSC_LOGIN_FAILED:
		fcport->login_retry--;
		ql_dbg(ql_dbg_disc, vha, 0x20d0,
		    "%s %d %8phC post gidpn\n",
		    __func__, __LINE__, fcport->port_name);
@@ -1303,6 +1301,7 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
		ql_dbg(ql_dbg_disc, vha, 0x20d1,
		    "%s %d %8phC post adisc\n",
		    __func__, __LINE__, fcport->port_name);
		fcport->login_retry--;
		data[0] = data[1] = 0;
		qla2x00_post_async_adisc_work(vha, fcport, data);
		break;
@@ -1386,17 +1385,6 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
		}
	}

	if (fcport->flags & FCF_ASYNC_SENT) {
		fcport->login_retry++;
		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
		return;
	}

	if (fcport->disc_state == DSC_DELETE_PEND) {
		fcport->login_retry++;
		return;
	}

	if (fcport->last_rscn_gen != fcport->rscn_gen) {
		ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gidpn\n",
		    __func__, __LINE__, fcport->port_name);
@@ -1882,7 +1870,6 @@ void
qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport,
    uint16_t *data)
{
	qla2x00_mark_device_lost(vha, fcport, 1, 0);
	qlt_logo_completion_handler(fcport, data[0]);
	fcport->login_gen++;
	fcport->flags &= ~FCF_ASYNC_ACTIVE;
@@ -5076,11 +5063,11 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
	if (IS_QLAFX00(vha->hw)) {
		qla2x00_set_fcport_state(fcport, FCS_ONLINE);
	} else {
		fcport->login_retry = 0;
		fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
		fcport->disc_state = DSC_LOGIN_COMPLETE;
		fcport->deleted = 0;
		fcport->logout_on_delete = 1;
		fcport->login_retry = vha->hw->login_retry_count;
		qla2x00_set_fcport_state(fcport, FCS_ONLINE);
	}

+1 −0
Original line number Diff line number Diff line
@@ -3912,6 +3912,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
		    rptid_entry->u.f2.port_name, 1);

		if (fcport) {
			fcport->login_retry = vha->hw->login_retry_count;
			fcport->plogi_nack_done_deadline = jiffies + HZ;
			fcport->scan_state = QLA_FCPORT_FOUND;
		}
+47 −43
Original line number Diff line number Diff line
@@ -3838,14 +3838,6 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport,
		return;

	set_bit(RELOGIN_NEEDED, &vha->dpc_flags);

	if (fcport->login_retry == 0) {
		fcport->login_retry = vha->hw->login_retry_count;

		ql_dbg(ql_dbg_disc, vha, 0x20a3,
		    "Port login retry %8phN, lid 0x%04x retry cnt=%d.\n",
		    fcport->port_name, fcport->loop_id, fcport->login_retry);
	}
}

/*
@@ -5098,7 +5090,7 @@ int qla24xx_post_relogin_work(struct scsi_qla_host *vha)
void qla2x00_relogin(struct scsi_qla_host *vha)
{
	fc_port_t       *fcport;
	int status;
	int status, relogin_needed = 0;
	struct event_arg ea;

	list_for_each_entry(fcport, &vha->vp_fcports, list) {
@@ -5107,29 +5099,37 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
		 * to it if we haven't run out of retries.
		 */
		if (atomic_read(&fcport->state) != FCS_ONLINE &&
		    fcport->login_retry &&
		    !(fcport->flags & (FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE))) {
		    fcport->login_retry) {
			if (fcport->scan_state != QLA_FCPORT_FOUND ||
			    fcport->disc_state == DSC_LOGIN_COMPLETE)
				continue;

			if (fcport->flags & (FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE) ||
				fcport->disc_state == DSC_DELETE_PEND) {
				relogin_needed = 1;
			} else {
				if (vha->hw->current_topology != ISP_CFG_NL) {
				ql_dbg(ql_dbg_disc, fcport->vha, 0x2108,
				    "%s %8phC DS %d LS %d\n", __func__,
				    fcport->port_name, fcport->disc_state,
				    fcport->fw_login_state);
					memset(&ea, 0, sizeof(ea));
					ea.event = FCME_RELOGIN;
					ea.fcport = fcport;
					qla2x00_fcport_event_handler(vha, &ea);
			} else if (vha->hw->current_topology == ISP_CFG_NL) {
				} else if (vha->hw->current_topology ==
				    ISP_CFG_NL) {
					fcport->login_retry--;
				status = qla2x00_local_device_login(vha,
					status =
					    qla2x00_local_device_login(vha,
						fcport);
					if (status == QLA_SUCCESS) {
					fcport->old_loop_id = fcport->loop_id;
						fcport->old_loop_id =
						    fcport->loop_id;
						ql_dbg(ql_dbg_disc, vha, 0x2003,
						    "Port login OK: logged in ID 0x%x.\n",
						    fcport->loop_id);
					qla2x00_update_fcport(vha, fcport);
						qla2x00_update_fcport
							(vha, fcport);
					} else if (status == 1) {
					set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
						set_bit(RELOGIN_NEEDED,
						    &vha->dpc_flags);
						/* retry the login again */
						ql_dbg(ql_dbg_disc, vha, 0x2007,
						    "Retrying %d login again loop_id 0x%x.\n",
@@ -5144,10 +5144,14 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
						qla2x00_clear_loop_id(fcport);
				}
			}
		}
		if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
			break;
	}

	if (relogin_needed)
		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);

	ql_dbg(ql_dbg_disc, vha, 0x400e,
	    "Relogin end.\n");
}
+1 −2
Original line number Diff line number Diff line
@@ -1057,7 +1057,6 @@ void qlt_free_session_done(struct work_struct *work)
	sess->disc_state = DSC_DELETED;
	sess->fw_login_state = DSC_LS_PORT_UNAVAIL;
	sess->deleted = QLA_SESS_DELETED;
	sess->login_retry = vha->hw->login_retry_count;

	if (sess->login_succ && !IS_SW_RESV_ADDR(sess->d_id)) {
		vha->fcport_count--;
@@ -1161,7 +1160,7 @@ void qlt_unreg_sess(struct fc_port *sess)
	if (sess->se_sess)
		vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess);

	qla2x00_mark_device_lost(vha, sess, 1, 1);
	qla2x00_mark_device_lost(vha, sess, 0, 0);

	sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
	sess->disc_state = DSC_DELETE_PEND;