[SCSI] lpfc 8.3.33: Fix error when remote port switches address
authorJames Smart <james.smart@emulex.com>
Fri, 3 Aug 2012 16:35:03 +0000 (12:35 -0400)
committerJames Bottomley <JBottomley@Parallels.com>
Fri, 14 Sep 2012 13:34:46 +0000 (14:34 +0100)
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c

index d54ae199979710c11f59a1ce34e5e8271460ba6e..3c624a5494afde79b3185c44cb6e29adbc7d2a98 100644 (file)
@@ -1476,6 +1476,10 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
                return ndlp;
        memset(&rrq.xri_bitmap, 0, sizeof(new_ndlp->active_rrqs.xri_bitmap));
 
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                "3178 PLOGI confirm: ndlp %p x%x: new_ndlp %p\n",
+                ndlp, ndlp->nlp_DID, new_ndlp);
+
        if (!new_ndlp) {
                rc = memcmp(&ndlp->nlp_portname, name,
                            sizeof(struct lpfc_name));
@@ -1527,6 +1531,9 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
                /* The new_ndlp is replacing ndlp totally, so we need
                 * to put ndlp on UNUSED list and try to free it.
                 */
+               lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                        "3179 PLOGI confirm NEW: %x %x\n",
+                        new_ndlp->nlp_DID, keepDID);
 
                /* Fix up the rport accordingly */
                rport =  ndlp->rport;
@@ -1559,23 +1566,34 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
                lpfc_drop_node(vport, ndlp);
        }
        else {
+               lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                        "3180 PLOGI confirm SWAP: %x %x\n",
+                        new_ndlp->nlp_DID, keepDID);
+
                lpfc_unreg_rpi(vport, ndlp);
+
                /* Two ndlps cannot have the same did */
                ndlp->nlp_DID = keepDID;
                if (phba->sli_rev == LPFC_SLI_REV4)
                        memcpy(&ndlp->active_rrqs.xri_bitmap,
                                &rrq.xri_bitmap,
                                sizeof(ndlp->active_rrqs.xri_bitmap));
+
                /* Since we are swapping the ndlp passed in with the new one
-                * and the did has already been swapped, copy over the
-                * state and names.
+                * and the did has already been swapped, copy over state.
+                * The new WWNs are already in new_ndlp since thats what
+                * we looked it up by in the begining of this routine.
                 */
-               memcpy(&new_ndlp->nlp_portname, &ndlp->nlp_portname,
-                       sizeof(struct lpfc_name));
-               memcpy(&new_ndlp->nlp_nodename, &ndlp->nlp_nodename,
-                       sizeof(struct lpfc_name));
                new_ndlp->nlp_state = ndlp->nlp_state;
-               lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+
+               /* Since we are switching over to the new_ndlp, the old
+                * ndlp should be put in the NPR state, unless we have
+                * already started re-discovery on it.
+                */
+               if ((ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) ||
+                   (ndlp->nlp_state == NLP_STE_MAPPED_NODE))
+                       lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+
                /* Fix up the rport accordingly */
                rport = ndlp->rport;
                if (rport) {
index 9b4f92941dce585aaddbfaa401d9e3ae5d7f7312..6b36d95668c08c3a35bb64709d9b081f61b83226 100644 (file)
@@ -123,6 +123,10 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
                "rport devlosscb: sid:x%x did:x%x flg:x%x",
                ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag);
 
+       lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
+                        "3181 dev_loss_callbk x%06x, rport %p flg x%x\n",
+                        ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag);
+
        /* Don't defer this if we are in the process of deleting the vport
         * or unloading the driver. The unload will cleanup the node
         * appropriately we just need to cleanup the ndlp rport info here.
@@ -142,6 +146,15 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
        if (ndlp->nlp_state == NLP_STE_MAPPED_NODE)
                return;
 
+       if (ndlp->nlp_type & NLP_FABRIC) {
+
+               /* If the WWPN of the rport and ndlp don't match, ignore it */
+               if (rport->port_name != wwn_to_u64(ndlp->nlp_portname.u.wwn)) {
+                       put_device(&rport->dev);
+                       return;
+               }
+       }
+
        evtp = &ndlp->dev_loss_evt;
 
        if (!list_empty(&evtp->evt_listp))
@@ -202,6 +215,10 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
                "rport devlosstmo:did:x%x type:x%x id:x%x",
                ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id);
 
+       lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
+                        "3182 dev_loss_tmo_handler x%06x, rport %p flg x%x\n",
+                        ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag);
+
        /* Don't defer this if we are in the process of deleting the vport
         * or unloading the driver. The unload will cleanup the node
         * appropriately we just need to cleanup the ndlp rport info here.
@@ -3834,6 +3851,10 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
        if (rport_ids.roles !=  FC_RPORT_ROLE_UNKNOWN)
                fc_remote_port_rolechg(rport, rport_ids.roles);
 
+       lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
+                        "3183 rport register x%06x, rport %p role x%x\n",
+                        ndlp->nlp_DID, rport, rport_ids.roles);
+
        if ((rport->scsi_target_id != -1) &&
            (rport->scsi_target_id < LPFC_MAX_TARGET)) {
                ndlp->nlp_sid = rport->scsi_target_id;
@@ -3850,6 +3871,10 @@ lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp)
                "rport delete:    did:x%x flg:x%x type x%x",
                ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);
 
+       lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
+                        "3184 rport unregister x%06x, rport %p\n",
+                        ndlp->nlp_DID, rport);
+
        fc_remote_port_delete(rport);
 
        return;
@@ -5365,9 +5390,17 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
        struct lpfc_nodelist *ndlp;
 
        list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
-               if (filter(ndlp, param))
+               if (filter(ndlp, param)) {
+                       lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+                                        "3185 FIND node filter %p DID "
+                                        "Data: x%p x%x x%x\n",
+                                        filter, ndlp, ndlp->nlp_DID,
+                                        ndlp->nlp_flag);
                        return ndlp;
+               }
        }
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+                        "3186 FIND node filter %p NOT FOUND.\n", filter);
        return NULL;
 }