mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
scsi: qla2xxx: Fix N2N stuck connection
commit 881eb861ca3877300570db10abbf11494e48548d upstream. 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: Quinn Tran <qutran@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Link: https://lore.kernel.org/r/20240227164127.36465-3-njavali@marvell.com Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
3b9d72442a
commit
3cd58084e4
@@ -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 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_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,
|
extern void qla2x00_els_dcmd2_free(scsi_qla_host_t *vha,
|
||||||
struct els_plogi *els_plogi);
|
struct els_plogi *els_plogi);
|
||||||
|
|
||||||
|
|||||||
@@ -3042,7 +3042,7 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
|
|||||||
|
|
||||||
int
|
int
|
||||||
qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
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;
|
srb_t *sp;
|
||||||
struct srb_iocb *elsio = NULL;
|
struct srb_iocb *elsio = NULL;
|
||||||
@@ -3057,8 +3057,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
|||||||
if (!sp) {
|
if (!sp) {
|
||||||
ql_log(ql_log_info, vha, 0x70e6,
|
ql_log(ql_log_info, vha, 0x70e6,
|
||||||
"SRB allocation failed\n");
|
"SRB allocation failed\n");
|
||||||
fcport->flags &= ~FCF_ASYNC_ACTIVE;
|
goto done;
|
||||||
return -ENOMEM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fcport->flags |= FCF_ASYNC_SENT;
|
fcport->flags |= FCF_ASYNC_SENT;
|
||||||
@@ -3067,9 +3066,6 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
|||||||
ql_dbg(ql_dbg_io, vha, 0x3073,
|
ql_dbg(ql_dbg_io, vha, 0x3073,
|
||||||
"%s Enter: PLOGI portid=%06x\n", __func__, fcport->d_id.b24);
|
"%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->type = SRB_ELS_DCMD;
|
||||||
sp->name = "ELS_DCMD";
|
sp->name = "ELS_DCMD";
|
||||||
sp->fcport = fcport;
|
sp->fcport = fcport;
|
||||||
@@ -3085,7 +3081,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
|||||||
|
|
||||||
if (!elsio->u.els_plogi.els_plogi_pyld) {
|
if (!elsio->u.els_plogi.els_plogi_pyld) {
|
||||||
rval = QLA_FUNCTION_FAILED;
|
rval = QLA_FUNCTION_FAILED;
|
||||||
goto out;
|
goto done_free_sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
resp_ptr = elsio->u.els_plogi.els_resp_pyld =
|
resp_ptr = elsio->u.els_plogi.els_resp_pyld =
|
||||||
@@ -3094,7 +3090,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
|||||||
|
|
||||||
if (!elsio->u.els_plogi.els_resp_pyld) {
|
if (!elsio->u.els_plogi.els_resp_pyld) {
|
||||||
rval = QLA_FUNCTION_FAILED;
|
rval = QLA_FUNCTION_FAILED;
|
||||||
goto out;
|
goto done_free_sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
ql_dbg(ql_dbg_io, vha, 0x3073, "PLOGI %p %p\n", ptr, resp_ptr);
|
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)) {
|
if (els_opcode == ELS_DCMD_PLOGI && DBELL_ACTIVE(vha)) {
|
||||||
struct fc_els_flogi *p = ptr;
|
struct fc_els_flogi *p = ptr;
|
||||||
|
|
||||||
p->fl_csp.sp_features |= cpu_to_be16(FC_SP_FT_SEC);
|
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,
|
(uint8_t *)elsio->u.els_plogi.els_plogi_pyld,
|
||||||
sizeof(*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);
|
rval = qla2x00_start_sp(sp);
|
||||||
if (rval != QLA_SUCCESS) {
|
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 {
|
} else {
|
||||||
ql_dbg(ql_dbg_disc, vha, 0x3074,
|
ql_dbg(ql_dbg_disc, vha, 0x3074,
|
||||||
"%s PLOGI sent, hdl=%x, loopid=%x, to port_id %06x from port_id %06x\n",
|
"%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);
|
fcport->d_id.b24, vha->d_id.b24);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait) {
|
return rval;
|
||||||
wait_for_completion(&elsio->u.els_plogi.comp);
|
|
||||||
|
|
||||||
if (elsio->u.els_plogi.comp_status != CS_COMPLETE)
|
done_free_sp:
|
||||||
rval = QLA_FUNCTION_FAILED;
|
|
||||||
} else {
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
|
|
||||||
qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi);
|
qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi);
|
||||||
/* ref: INIT */
|
/* ref: INIT */
|
||||||
kref_put(&sp->cmd_kref, qla2x00_sp_release);
|
kref_put(&sp->cmd_kref, qla2x00_sp_release);
|
||||||
done:
|
done:
|
||||||
|
fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
|
||||||
|
qla2x00_set_fcport_disc_state(fcport, DSC_DELETED);
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5562,7 +5562,7 @@ qla2x00_do_work(struct scsi_qla_host *vha)
|
|||||||
break;
|
break;
|
||||||
case QLA_EVT_ELS_PLOGI:
|
case QLA_EVT_ELS_PLOGI:
|
||||||
qla24xx_els_dcmd2_iocb(vha, ELS_DCMD_PLOGI,
|
qla24xx_els_dcmd2_iocb(vha, ELS_DCMD_PLOGI,
|
||||||
e->u.fcport.fcport, false);
|
e->u.fcport.fcport);
|
||||||
break;
|
break;
|
||||||
case QLA_EVT_SA_REPLACE:
|
case QLA_EVT_SA_REPLACE:
|
||||||
rc = qla24xx_issue_sa_replace_iocb(vha, e);
|
rc = qla24xx_issue_sa_replace_iocb(vha, e);
|
||||||
|
|||||||
Reference in New Issue
Block a user