@@ -2352,6 +2352,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;
@@ -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,
@@ -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,