]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
scsi: qla2xxx: Fix name server relogin
authorQuinn Tran <quinn.tran@cavium.com>
Fri, 2 Jun 2017 16:12:00 +0000 (09:12 -0700)
committerSomasundaram Krishnasamy <somasundaram.krishnasamy@oracle.com>
Fri, 5 Jan 2018 21:05:15 +0000 (13:05 -0800)
Orabug: 27235104

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>
[ Upstream commit b98ae0d748dbc80016c5cc2e926f33648d83353d ]
Signed-off-by: Somasundaram Krishnasamy <somasundaram.krishnasamy@oracle.com>
Reviewed-by: Jack Vogel <jack.vogel@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 0b9f2914461d2d9072e0796bca36fde7614a00eb..3176de4256a23299df50088c885b402b79e28ad6 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 7da60d9d13d4f43c36aa5e361af54f2a5a0a490a..f04c80e372aebf3ade17592c7b267233ef1349c3 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 1d77d9db8714131b2240dba31ecf74c7ecff1b55..7623b84545809f48dc08a62c74e44b6604f59263 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))
@@ -4417,20 +4431,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;
                        }
                }
 
@@ -4502,17 +4527,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 d6527bfdf8194b5236102a57aee7910687eeeb8d..d3ea6e341109a34cd050ce65f4b6933fd9bd004f 100644 (file)
@@ -976,6 +976,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)