scsi: qla2xxx: Fix name server relogin
authorQuinn Tran <quinn.tran@cavium.com>
Fri, 2 Jun 2017 16:12:00 +0000 (09:12 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 13 Jun 2017 00:48:07 +0000 (20:48 -0400)
Name server login is normally handle by FW. In some rare case where one
of the switches is being updated, name server login could get
affected. Trigger relogin to name server when driver detects this
condition.

Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_isr.c

index 4127f35b669c0884d1795137bfaa38ff47f7e274..51b262b236b4cd25e10b53665212b8c76e651741 100644 (file)
 #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"
 
index 5acebaf57796a24179f25f9cf0f2efceec44bf6d..ef8e8891d54ff225dd806403d29a82cf954cec4c 100644 (file)
@@ -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: "
index e4876f4220e448881fde0b5a247e19436e3a074f..4ea4aa5bddaa19abb94d7abbf98cb96a8bbffe2f 100644 (file)
@@ -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;
 
index 2572121b765b488b4ee5dbec726e9240e0df25a9..1eb46eb450050e36ec23c98ac085b503fad178df 100644 (file)
@@ -973,6 +973,23 @@ skip_rio:
                        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)