diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 4127f35b669c0884d1795137bfaa38ff47f7e274..51b262b236b4cd25e10b53665212b8c76e651741 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -252,6 +252,8 @@ #define NPH_F_PORT 0x7fe /* FFFFFE */ #define NPH_IP_BROADCAST 0x7ff /* FFFFFF */ +#define NPH_SNS_LID(ha) (IS_FWI2_CAPABLE(ha) ? NPH_SNS : SIMPLE_NAME_SERVER) + #define MAX_CMDSZ 16 /* SCSI maximum CDB size. */ #include "qla_fw.h" diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 5acebaf57796a24179f25f9cf0f2efceec44bf6d..ef8e8891d54ff225dd806403d29a82cf954cec4c 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -124,6 +124,7 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt, int rval; uint16_t comp_status; struct qla_hw_data *ha = vha->hw; + bool lid_is_sns = false; rval = QLA_FUNCTION_FAILED; if (ms_pkt->entry_status != 0) { @@ -155,6 +156,25 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt, } else rval = QLA_SUCCESS; break; + case CS_PORT_LOGGED_OUT: + if (IS_FWI2_CAPABLE(ha)) { + if (le16_to_cpu(ms_pkt->loop_id.extended) == + NPH_SNS) + lid_is_sns = true; + } else { + if (le16_to_cpu(ms_pkt->loop_id.extended) == + SIMPLE_NAME_SERVER) + lid_is_sns = true; + } + if (lid_is_sns) { + ql_dbg(ql_dbg_async, vha, 0x502b, + "%s failed, Name server has logged out", + routine); + rval = QLA_NOT_LOGGED_IN; + set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); + set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); + } + break; default: ql_dbg(ql_dbg_disc, vha, 0x2033, "%s failed, completion status (%x) on port_id: " diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index e4876f4220e448881fde0b5a247e19436e3a074f..4ea4aa5bddaa19abb94d7abbf98cb96a8bbffe2f 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1039,6 +1039,20 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea) uint32_t id = 0, mask, rid; int rc; + switch (ea->event) { + case FCME_RELOGIN: + case FCME_RSCN: + case FCME_GIDPN_DONE: + case FCME_GPSC_DONE: + case FCME_GPNID_DONE: + if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) || + test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags)) + return; + break; + default: + break; + } + switch (ea->event) { case FCME_RELOGIN: if (test_bit(UNLOADING, &vha->dpc_flags)) @@ -4451,20 +4465,31 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) /* EMPTY */ ql_dbg(ql_dbg_disc, vha, 0x2045, "Register FC-4 TYPE failed.\n"); + if (test_bit(LOOP_RESYNC_NEEDED, + &vha->dpc_flags)) + break; } if (qla2x00_rff_id(vha)) { /* EMPTY */ ql_dbg(ql_dbg_disc, vha, 0x2049, "Register FC-4 Features failed.\n"); + if (test_bit(LOOP_RESYNC_NEEDED, + &vha->dpc_flags)) + break; } if (qla2x00_rnn_id(vha)) { /* EMPTY */ ql_dbg(ql_dbg_disc, vha, 0x204f, "Register Node Name failed.\n"); + if (test_bit(LOOP_RESYNC_NEEDED, + &vha->dpc_flags)) + break; } else if (qla2x00_rsnn_nn(vha)) { /* EMPTY */ ql_dbg(ql_dbg_disc, vha, 0x2053, "Register Symobilic Node Name failed.\n"); + if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) + break; } } @@ -4536,17 +4561,28 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) memset(swl, 0, ha->max_fibre_devices * sizeof(sw_info_t)); if (qla2x00_gid_pt(vha, swl) != QLA_SUCCESS) { swl = NULL; + if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) + return rval; } else if (qla2x00_gpn_id(vha, swl) != QLA_SUCCESS) { swl = NULL; + if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) + return rval; } else if (qla2x00_gnn_id(vha, swl) != QLA_SUCCESS) { swl = NULL; + if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) + return rval; } else if (qla2x00_gfpn_id(vha, swl) != QLA_SUCCESS) { swl = NULL; + if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) + return rval; } /* If other queries succeeded probe for FC-4 type */ - if (swl) + if (swl) { qla2x00_gff_id(vha, swl); + if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) + return rval; + } } swl_idx = 0; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 2572121b765b488b4ee5dbec726e9240e0df25a9..1eb46eb450050e36ec23c98ac085b503fad178df 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -973,6 +973,23 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) if (mb[1] == 0xffff) goto global_port_update; + if (mb[1] == NPH_SNS_LID(ha)) { + set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); + set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); + break; + } + + /* use handle_cnt for loop id/nport handle */ + if (IS_FWI2_CAPABLE(ha)) + handle_cnt = NPH_SNS; + else + handle_cnt = SIMPLE_NAME_SERVER; + if (mb[1] == handle_cnt) { + set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); + set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); + break; + } + /* Port logout */ fcport = qla2x00_find_fcport_by_loopid(vha, mb[1]); if (!fcport)