Commit 5b33469a authored by Quinn Tran's avatar Quinn Tran Committed by Nicholas Bellinger

qla2xxx: Allow relogin to proceed if remote login did not finish

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: default avatarQuinn Tran <quinn.tran@qlogic.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent f159b3c7
...@@ -2300,6 +2300,8 @@ typedef struct fc_port { ...@@ -2300,6 +2300,8 @@ typedef struct fc_port {
struct ct_sns_desc ct_desc; struct ct_sns_desc ct_desc;
enum discovery_state disc_state; enum discovery_state disc_state;
enum login_state fw_login_state; enum login_state fw_login_state;
unsigned long plogi_nack_done_deadline;
u32 login_gen, last_login_gen; u32 login_gen, last_login_gen;
u32 rscn_gen, last_rscn_gen; u32 rscn_gen, last_rscn_gen;
u32 chip_reset; u32 chip_reset;
......
...@@ -876,10 +876,14 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) ...@@ -876,10 +876,14 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
fcport->login_retry--; fcport->login_retry--;
if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || 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)) (fcport->fw_login_state == DSC_LS_PRLI_PEND))
return 0; return 0;
if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline))
return 0;
}
/* for pure Target Mode. Login will not be initiated */ /* for pure Target Mode. Login will not be initiated */
if (vha->host->active_mode == MODE_TARGET) if (vha->host->active_mode == MODE_TARGET)
return 0; return 0;
...@@ -1041,10 +1045,14 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, ...@@ -1041,10 +1045,14 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
fcport->flags); fcport->flags);
if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || 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)) (fcport->fw_login_state == DSC_LS_PRLI_PEND))
return; return;
if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline))
return;
}
if (fcport->flags & FCF_ASYNC_SENT) { if (fcport->flags & FCF_ASYNC_SENT) {
fcport->login_retry++; fcport->login_retry++;
set_bit(RELOGIN_NEEDED, &vha->dpc_flags); set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
......
...@@ -1620,9 +1620,9 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1620,9 +1620,9 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
QLA_LOGIO_LOGIN_RETRIED : 0; QLA_LOGIO_LOGIN_RETRIED : 0;
if (logio->entry_status) { if (logio->entry_status) {
ql_log(ql_log_warn, fcport->vha, 0x5034, 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", "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, fcport->d_id.b.area, fcport->d_id.b.al_pa,
logio->entry_status); logio->entry_status);
ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x504d, ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x504d,
...@@ -1633,8 +1633,9 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1633,8 +1633,9 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) { if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) {
ql_dbg(ql_dbg_async, fcport->vha, 0x5036, ql_dbg(ql_dbg_async, fcport->vha, 0x5036,
"Async-%s complete - hdl=%x portid=%02x%02x%02x " "Async-%s complete - %8phC hdl=%x portid=%02x%02x%02x "
"iop0=%x.\n", type, sp->handle, fcport->d_id.b.domain, "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, fcport->d_id.b.area, fcport->d_id.b.al_pa,
le32_to_cpu(logio->io_parameter[0])); le32_to_cpu(logio->io_parameter[0]));
...@@ -1674,6 +1675,17 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1674,6 +1675,17 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
case LSC_SCODE_NPORT_USED: case LSC_SCODE_NPORT_USED:
data[0] = MBS_LOOP_ID_USED; data[0] = MBS_LOOP_ID_USED;
break; 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: case LSC_SCODE_NOXCB:
vha->hw->exch_starvation++; vha->hw->exch_starvation++;
if (vha->hw->exch_starvation > 5) { if (vha->hw->exch_starvation > 5) {
...@@ -1695,8 +1707,9 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1695,8 +1707,9 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
} }
ql_dbg(ql_dbg_async, fcport->vha, 0x5037, ql_dbg(ql_dbg_async, fcport->vha, 0x5037,
"Async-%s failed - hdl=%x portid=%02x%02x%02x comp=%x " "Async-%s failed - %8phC hdl=%x portid=%02x%02x%02x comp=%x "
"iop0=%x iop1=%x.\n", type, sp->handle, fcport->d_id.b.domain, "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, fcport->d_id.b.area, fcport->d_id.b.al_pa,
le16_to_cpu(logio->comp_status), le16_to_cpu(logio->comp_status),
le32_to_cpu(logio->io_parameter[0]), le32_to_cpu(logio->io_parameter[0]),
......
...@@ -562,6 +562,7 @@ void qla2x00_async_nack_sp_done(void *s, int res) ...@@ -562,6 +562,7 @@ void qla2x00_async_nack_sp_done(void *s, int res)
sp->fcport->login_gen++; sp->fcport->login_gen++;
sp->fcport->fw_login_state = DSC_LS_PLOGI_COMP; sp->fcport->fw_login_state = DSC_LS_PLOGI_COMP;
sp->fcport->logout_on_delete = 1; sp->fcport->logout_on_delete = 1;
sp->fcport->plogi_nack_done_deadline = jiffies + HZ;
break; break;
case SRB_NACK_PRLI: case SRB_NACK_PRLI:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment