diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index eb2ec1fb07cbe7a6f2118b0504e2e3bde76374ae..5a1900ec808d16805b19b79488381e9e2738a495 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2346,6 +2346,7 @@ typedef struct fc_port { unsigned int login_succ:1; unsigned int query:1; unsigned int id_changed:1; + unsigned int rscn_rcvd:1; struct work_struct nvme_del_work; struct completion nvme_del_done; diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 05abe5aaab7f5024ee4d4b2dea1d849eec7c655f..939ac8435f1973f1c7cf425d20341049bbd2aeaf 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -3862,6 +3862,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) bool found; struct fab_scan_rp *rp; unsigned long flags; + u8 recheck = 0; ql_dbg(ql_dbg_disc, vha, 0xffff, "%s enter\n", __func__); @@ -3914,6 +3915,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) list_for_each_entry(fcport, &vha->vp_fcports, list) { if (memcmp(rp->port_name, fcport->port_name, WWN_SIZE)) continue; + fcport->rscn_rcvd = 0; fcport->scan_state = QLA_FCPORT_FOUND; found = true; /* @@ -3942,10 +3944,13 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) * Logout all previous fabric dev marked lost, except FCP2 devices. */ list_for_each_entry(fcport, &vha->vp_fcports, list) { - if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) + if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) { + fcport->rscn_rcvd = 0; continue; + } if (fcport->scan_state != QLA_FCPORT_FOUND) { + fcport->rscn_rcvd = 0; if ((qla_dual_mode_enabled(vha) || qla_ini_mode_enabled(vha)) && atomic_read(&fcport->state) == FCS_ONLINE) { @@ -3963,15 +3968,31 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) continue; } } - } else - qla24xx_fcport_handle_login(vha, fcport); + } else { + if (fcport->rscn_rcvd || + fcport->disc_state != DSC_LOGIN_COMPLETE) { + fcport->rscn_rcvd = 0; + qla24xx_fcport_handle_login(vha, fcport); + } + } } + recheck = 1; out: qla24xx_sp_unmap(vha, sp); spin_lock_irqsave(&vha->work_lock, flags); vha->scan.scan_flags &= ~SF_SCANNING; spin_unlock_irqrestore(&vha->work_lock, flags); + + if (recheck) { + list_for_each_entry(fcport, &vha->vp_fcports, list) { + if (fcport->rscn_rcvd) { + set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); + set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); + break; + } + } + } } static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha, diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index b9050cb52c0eca8d40be22cfcd68df6c67d15b31..98d4b315d66a3a37586567918977cc462c3d8569 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1348,6 +1348,7 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea) fc_port_t *f, *tf; uint32_t id = 0, mask, rid; unsigned long flags; + fc_port_t *fcport; switch (ea->event) { case FCME_RSCN: @@ -1375,6 +1376,11 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea) return; switch (ea->id.b.rsvd_1) { case RSCN_PORT_ADDR: + fcport = qla2x00_find_fcport_by_nportid + (vha, &ea->id, 1); + if (fcport) + fcport->rscn_rcvd = 1; + spin_lock_irqsave(&vha->work_lock, flags); if (vha->scan.scan_flags == 0) { ql_dbg(ql_dbg_disc, vha, 0xffff,