scsi: qla2xxx: Fix N2N stuck connection
authorQuinn Tran <qutran@marvell.com>
Tue, 27 Feb 2024 16:41:18 +0000 (22:11 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Sun, 10 Mar 2024 22:44:43 +0000 (18:44 -0400)
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>
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_os.c

index 09cb9413670a5e4034ea13792d8806fdab6cbc73..7309310d2ab94368fcda24f5fc9812aeaafa9397 100644 (file)
@@ -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);
 
index 0228c90b9fe817a10135321d870634c990c10518..892a27afb4624beeabf1bf5c269b22cd6a012789 100644 (file)
@@ -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;
 }
 
index dd674378f2f392216334f7adb90129f2753e8c2a..b3bb974ae7978251f57acba099103af5925abe18 100644 (file)
@@ -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);