linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / scsi / lpfc / lpfc_els.c
index 3567de6..20f1a07 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2006 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -92,14 +92,15 @@ lpfc_els_chk_latt(struct lpfc_hba * phba)
                }
        }
 
-       return 1;
+       return (1);
 
 }
 
 static struct lpfc_iocbq *
-lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp,
-                  uint16_t cmdSize, uint8_t retry, struct lpfc_nodelist * ndlp,
-                  uint32_t did, uint32_t elscmd)
+lpfc_prep_els_iocb(struct lpfc_hba * phba,
+                  uint8_t expectRsp,
+                  uint16_t cmdSize,
+                  uint8_t retry, struct lpfc_nodelist * ndlp, uint32_t elscmd)
 {
        struct lpfc_sli_ring *pring;
        struct lpfc_iocbq *elsiocb;
@@ -180,7 +181,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp,
        icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL;
        if (expectRsp) {
                icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64));
-               icmd->un.elsreq64.remoteID = did;       /* DID */
+               icmd->un.elsreq64.remoteID = ndlp->nlp_DID;     /* DID */
                icmd->ulpCommand = CMD_ELS_REQUEST64_CR;
        } else {
                icmd->un.elsreq64.bdl.bdeSize = sizeof (struct ulp_bde64);
@@ -224,7 +225,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp,
                                "%d:0116 Xmit ELS command x%x to remote "
                                "NPORT x%x Data: x%x x%x\n",
                                phba->brd_no, elscmd,
-                               did, icmd->ulpIoTag, phba->hba_state);
+                               ndlp->nlp_DID, icmd->ulpIoTag, phba->hba_state);
        } else {
                /* Xmit ELS response <elsCmd> to remote NPORT <did> */
                lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
@@ -234,7 +235,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp,
                                ndlp->nlp_DID, icmd->ulpIoTag, cmdSize);
        }
 
-       return elsiocb;
+       return (elsiocb);
 }
 
 
@@ -302,6 +303,10 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
        if (lpfc_reg_login(phba, Fabric_DID, (uint8_t *) sp, mbox, 0))
                goto fail_free_mbox;
 
+       /*
+        * set_slim mailbox command needs to execute first,
+        * queue this command to be processed later.
+        */
        mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login;
        mbox->context2 = ndlp;
 
@@ -441,10 +446,9 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba,
                lpfc_printf_log(phba,
                                KERN_INFO,
                                LOG_ELS,
-                               "%d:0100 FLOGI failure Data: x%x x%x x%x\n",
+                               "%d:0100 FLOGI failure Data: x%x x%x\n",
                                phba->brd_no,
-                               irsp->ulpStatus, irsp->un.ulpWord[4],
-                               irsp->ulpTimeout);
+                               irsp->ulpStatus, irsp->un.ulpWord[4]);
                goto flogifail;
        }
 
@@ -511,10 +515,10 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
        pring = &phba->sli.ring[LPFC_ELS_RING];
 
        cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm));
-       elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp,
-                                                ndlp->nlp_DID, ELS_CMD_FLOGI);
-       if (!elsiocb)
-               return 1;
+       if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry,
+                                         ndlp, ELS_CMD_FLOGI)) == 0) {
+               return (1);
+       }
 
        icmd = &elsiocb->iocb;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
@@ -548,9 +552,9 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
        spin_unlock_irq(phba->host->host_lock);
        if (rc == IOCB_ERROR) {
                lpfc_els_free_iocb(phba, elsiocb);
-               return 1;
+               return (1);
        }
-       return 0;
+       return (0);
 }
 
 int
@@ -607,21 +611,29 @@ lpfc_initial_flogi(struct lpfc_hba * phba)
 {
        struct lpfc_nodelist *ndlp;
 
-       /* First look for the Fabric ndlp */
-       ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, Fabric_DID);
-       if (!ndlp) {
+       /* First look for Fabric ndlp on the unmapped list */
+
+       if ((ndlp =
+            lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED,
+                              Fabric_DID)) == 0) {
                /* Cannot find existing Fabric ndlp, so allocate a new one */
-               ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
-               if (!ndlp)
-                       return 0;
+               if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL))
+                   == 0) {
+                       return (0);
+               }
                lpfc_nlp_init(phba, ndlp, Fabric_DID);
-       } else {
-               lpfc_nlp_list(phba, ndlp, NLP_JUST_DQ);
+       }
+       else {
+               phba->fc_unmap_cnt--;
+               list_del(&ndlp->nlp_listp);
+               spin_lock_irq(phba->host->host_lock);
+               ndlp->nlp_flag &= ~NLP_LIST_MASK;
+               spin_unlock_irq(phba->host->host_lock);
        }
        if (lpfc_issue_els_flogi(phba, ndlp, 0)) {
                mempool_free( ndlp, phba->nlp_mem_pool);
        }
-       return 1;
+       return (1);
 }
 
 static void
@@ -647,94 +659,38 @@ lpfc_more_plogi(struct lpfc_hba * phba)
        return;
 }
 
-static struct lpfc_nodelist *
-lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp,
-                        struct lpfc_nodelist *ndlp)
-{
-       struct lpfc_nodelist *new_ndlp;
-       uint32_t *lp;
-       struct serv_parm *sp;
-       uint8_t name[sizeof (struct lpfc_name)];
-       uint32_t rc;
-
-       lp = (uint32_t *) prsp->virt;
-       sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
-       memset(name, 0, sizeof (struct lpfc_name));
-
-       /* Now we to find out if the NPort we are logging into, matches the WWPN
-        * we have for that ndlp. If not, we have some work to do.
-        */
-       new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName);
-
-       if (new_ndlp == ndlp)
-               return ndlp;
-
-       if (!new_ndlp) {
-               rc =
-                  memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name));
-               if (!rc)
-                       return ndlp;
-               new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
-               if (!new_ndlp)
-                       return ndlp;
-
-               lpfc_nlp_init(phba, new_ndlp, ndlp->nlp_DID);
-       }
-
-       lpfc_unreg_rpi(phba, new_ndlp);
-       new_ndlp->nlp_DID = ndlp->nlp_DID;
-       new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
-       new_ndlp->nlp_state = ndlp->nlp_state;
-       lpfc_nlp_list(phba, new_ndlp, ndlp->nlp_flag & NLP_LIST_MASK);
-
-       /* Move this back to NPR list */
-       if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) {
-               lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
-       }
-       else {
-               lpfc_unreg_rpi(phba, ndlp);
-               ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
-               ndlp->nlp_state = NLP_STE_NPR_NODE;
-               lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
-       }
-       return new_ndlp;
-}
-
 static void
 lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                    struct lpfc_iocbq * rspiocb)
 {
        IOCB_t *irsp;
+       struct lpfc_sli *psli;
        struct lpfc_nodelist *ndlp;
-       struct lpfc_dmabuf *prsp;
        int disc, rc, did, type;
 
+       psli = &phba->sli;
 
        /* we pass cmdiocb to state machine which needs rspiocb as well */
        cmdiocb->context_un.rsp_iocb = rspiocb;
 
        irsp = &rspiocb->iocb;
-       ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL,
-                                               irsp->un.elsreq64.remoteID);
-       if (!ndlp)
-               goto out;
+       ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
+       spin_lock_irq(phba->host->host_lock);
+       ndlp->nlp_flag &= ~NLP_PLOGI_SND;
+       spin_unlock_irq(phba->host->host_lock);
 
        /* Since ndlp can be freed in the disc state machine, note if this node
         * is being used during discovery.
         */
        disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
-       spin_lock_irq(phba->host->host_lock);
-       ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
-       spin_unlock_irq(phba->host->host_lock);
        rc   = 0;
 
        /* PLOGI completes to NPort <nlp_DID> */
        lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
                        "%d:0102 PLOGI completes to NPort x%x "
-                       "Data: x%x x%x x%x x%x x%x\n",
+                       "Data: x%x x%x x%x x%x\n",
                        phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus,
-                       irsp->un.ulpWord[4], irsp->ulpTimeout, disc,
-                       phba->num_disc_nodes);
+                       irsp->un.ulpWord[4], disc, phba->num_disc_nodes);
 
        /* Check to see if link went down during discovery */
        if (lpfc_els_chk_latt(phba)) {
@@ -766,44 +722,55 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
                   (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
                   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
-                       rc = NLP_STE_FREED_NODE;
-               } else {
+                       disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
+               }
+               else {
                        rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb,
                                        NLP_EVT_CMPL_PLOGI);
                }
        } else {
                /* Good status, call state machine */
-               prsp = list_entry(((struct lpfc_dmabuf *)
-                       cmdiocb->context2)->list.next,
-                       struct lpfc_dmabuf, list);
-               ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp);
                rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb,
                                        NLP_EVT_CMPL_PLOGI);
        }
 
+       if (type & NLP_FABRIC) {
+               /* If we cannot login to Nameserver, kick off discovery now */
+               if ((did == NameServer_DID) && (rc == NLP_STE_FREED_NODE)) {
+                       lpfc_disc_start(phba);
+               }
+               goto out;
+       }
+
        if (disc && phba->num_disc_nodes) {
                /* Check to see if there are more PLOGIs to be sent */
                lpfc_more_plogi(phba);
+       }
 
-               if (phba->num_disc_nodes == 0) {
+       if (rc != NLP_STE_FREED_NODE) {
+               spin_lock_irq(phba->host->host_lock);
+               ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+               spin_unlock_irq(phba->host->host_lock);
+       }
+
+       if (phba->num_disc_nodes == 0) {
+               if(disc) {
                        spin_lock_irq(phba->host->host_lock);
                        phba->fc_flag &= ~FC_NDISC_ACTIVE;
                        spin_unlock_irq(phba->host->host_lock);
-
-                       lpfc_can_disctmo(phba);
-                       if (phba->fc_flag & FC_RSCN_MODE) {
-                               /*
-                                * Check to see if more RSCNs came in while
-                                * we were processing this one.
-                                */
-                               if ((phba->fc_rscn_id_cnt == 0) &&
-                               (!(phba->fc_flag & FC_RSCN_DISCOVERY))) {
-                                       spin_lock_irq(phba->host->host_lock);
-                                       phba->fc_flag &= ~FC_RSCN_MODE;
-                                       spin_unlock_irq(phba->host->host_lock);
-                               } else {
-                                       lpfc_els_handle_rscn(phba);
-                               }
+               }
+               lpfc_can_disctmo(phba);
+               if (phba->fc_flag & FC_RSCN_MODE) {
+                       /* Check to see if more RSCNs came in while we were
+                        * processing this one.
+                        */
+                       if ((phba->fc_rscn_id_cnt == 0) &&
+                           (!(phba->fc_flag & FC_RSCN_DISCOVERY))) {
+                               spin_lock_irq(phba->host->host_lock);
+                               phba->fc_flag &= ~FC_RSCN_MODE;
+                               spin_unlock_irq(phba->host->host_lock);
+                       } else {
+                               lpfc_els_handle_rscn(phba);
                        }
                }
        }
@@ -814,7 +781,8 @@ out:
 }
 
 int
-lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry)
+lpfc_issue_els_plogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
+                    uint8_t retry)
 {
        struct serv_parm *sp;
        IOCB_t *icmd;
@@ -828,10 +796,10 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry)
        pring = &psli->ring[LPFC_ELS_RING];     /* ELS ring */
 
        cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm));
-       elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, NULL, did,
-                                                               ELS_CMD_PLOGI);
-       if (!elsiocb)
-               return 1;
+       if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry,
+                                         ndlp, ELS_CMD_PLOGI)) == 0) {
+               return (1);
+       }
 
        icmd = &elsiocb->iocb;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
@@ -851,13 +819,15 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry)
        phba->fc_stat.elsXmitPLOGI++;
        elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi;
        spin_lock_irq(phba->host->host_lock);
+       ndlp->nlp_flag |= NLP_PLOGI_SND;
        if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
+               ndlp->nlp_flag &= ~NLP_PLOGI_SND;
                spin_unlock_irq(phba->host->host_lock);
                lpfc_els_free_iocb(phba, elsiocb);
-               return 1;
+               return (1);
        }
        spin_unlock_irq(phba->host->host_lock);
-       return 0;
+       return (0);
 }
 
 static void
@@ -881,10 +851,9 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
        /* PRLI completes to NPort <nlp_DID> */
        lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
                        "%d:0103 PRLI completes to NPort x%x "
-                       "Data: x%x x%x x%x x%x\n",
+                       "Data: x%x x%x x%x\n",
                        phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus,
-                       irsp->un.ulpWord[4], irsp->ulpTimeout,
-                       phba->num_disc_nodes);
+                       irsp->un.ulpWord[4], phba->num_disc_nodes);
 
        phba->fc_prli_sent--;
        /* Check to see if link went down during discovery */
@@ -904,7 +873,8 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                   (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
                   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
                        goto out;
-               } else {
+               }
+               else {
                        lpfc_disc_state_machine(phba, ndlp, cmdiocb,
                                        NLP_EVT_CMPL_PRLI);
                }
@@ -934,10 +904,10 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
        pring = &psli->ring[LPFC_ELS_RING];     /* ELS ring */
 
        cmdsize = (sizeof (uint32_t) + sizeof (PRLI));
-       elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp,
-                                       ndlp->nlp_DID, ELS_CMD_PRLI);
-       if (!elsiocb)
-               return 1;
+       if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry,
+                                         ndlp, ELS_CMD_PRLI)) == 0) {
+               return (1);
+       }
 
        icmd = &elsiocb->iocb;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
@@ -973,11 +943,11 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
                ndlp->nlp_flag &= ~NLP_PRLI_SND;
                spin_unlock_irq(phba->host->host_lock);
                lpfc_els_free_iocb(phba, elsiocb);
-               return 1;
+               return (1);
        }
        spin_unlock_irq(phba->host->host_lock);
        phba->fc_prli_sent++;
-       return 0;
+       return (0);
 }
 
 static void
@@ -1046,22 +1016,21 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 
        irsp = &(rspiocb->iocb);
        ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
+       spin_lock_irq(phba->host->host_lock);
+       ndlp->nlp_flag &= ~NLP_ADISC_SND;
+       spin_unlock_irq(phba->host->host_lock);
 
        /* Since ndlp can be freed in the disc state machine, note if this node
         * is being used during discovery.
         */
        disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
-       spin_lock_irq(phba->host->host_lock);
-       ndlp->nlp_flag &= ~(NLP_ADISC_SND | NLP_NPR_2B_DISC);
-       spin_unlock_irq(phba->host->host_lock);
 
        /* ADISC completes to NPort <nlp_DID> */
        lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
                        "%d:0104 ADISC completes to NPort x%x "
-                       "Data: x%x x%x x%x x%x x%x\n",
+                       "Data: x%x x%x x%x x%x\n",
                        phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus,
-                       irsp->un.ulpWord[4], irsp->ulpTimeout, disc,
-                       phba->num_disc_nodes);
+                       irsp->un.ulpWord[4], disc, phba->num_disc_nodes);
 
        /* Check to see if link went down during discovery */
        if (lpfc_els_chk_latt(phba)) {
@@ -1085,10 +1054,13 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                }
                /* ADISC failed */
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
-               if ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
-                  ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) &&
-                  (irsp->un.ulpWord[4] != IOERR_LINK_DOWN) &&
-                  (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) {
+               if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
+                  ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+                  (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
+                  (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
+                       disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
+               }
+               else {
                        lpfc_disc_state_machine(phba, ndlp, cmdiocb,
                                        NLP_EVT_CMPL_ADISC);
                }
@@ -1140,6 +1112,9 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                        }
                }
        }
+       spin_lock_irq(phba->host->host_lock);
+       ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+       spin_unlock_irq(phba->host->host_lock);
 out:
        lpfc_els_free_iocb(phba, cmdiocb);
        return;
@@ -1161,10 +1136,10 @@ lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
        pring = &psli->ring[LPFC_ELS_RING];     /* ELS ring */
 
        cmdsize = (sizeof (uint32_t) + sizeof (ADISC));
-       elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp,
-                                               ndlp->nlp_DID, ELS_CMD_ADISC);
-       if (!elsiocb)
-               return 1;
+       if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry,
+                                         ndlp, ELS_CMD_ADISC)) == 0) {
+               return (1);
+       }
 
        icmd = &elsiocb->iocb;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
@@ -1188,10 +1163,10 @@ lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
                ndlp->nlp_flag &= ~NLP_ADISC_SND;
                spin_unlock_irq(phba->host->host_lock);
                lpfc_els_free_iocb(phba, elsiocb);
-               return 1;
+               return (1);
        }
        spin_unlock_irq(phba->host->host_lock);
-       return 0;
+       return (0);
 }
 
 static void
@@ -1215,10 +1190,9 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
        /* LOGO completes to NPort <nlp_DID> */
        lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
                        "%d:0105 LOGO completes to NPort x%x "
-                       "Data: x%x x%x x%x x%x\n",
+                       "Data: x%x x%x x%x\n",
                        phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus,
-                       irsp->un.ulpWord[4], irsp->ulpTimeout,
-                       phba->num_disc_nodes);
+                       irsp->un.ulpWord[4], phba->num_disc_nodes);
 
        /* Check to see if link went down during discovery */
        if (lpfc_els_chk_latt(phba))
@@ -1237,15 +1211,18 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                   (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
                   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
                        goto out;
-               } else {
+               }
+               else {
                        lpfc_disc_state_machine(phba, ndlp, cmdiocb,
                                        NLP_EVT_CMPL_LOGO);
                }
        } else {
-               /* Good status, call state machine.
-                * This will unregister the rpi if needed.
-                */
+               /* Good status, call state machine */
                lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO);
+
+               if (ndlp->nlp_flag & NLP_DELAY_TMO) {
+                       lpfc_unreg_rpi(phba, ndlp);
+               }
        }
 
 out:
@@ -1267,11 +1244,11 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
        psli = &phba->sli;
        pring = &psli->ring[LPFC_ELS_RING];
 
-       cmdsize = (2 * sizeof (uint32_t)) + sizeof (struct lpfc_name);
-       elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp,
-                                               ndlp->nlp_DID, ELS_CMD_LOGO);
-       if (!elsiocb)
-               return 1;
+       cmdsize = 2 * (sizeof (uint32_t) + sizeof (struct lpfc_name));
+       if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry,
+                                         ndlp, ELS_CMD_LOGO)) == 0) {
+               return (1);
+       }
 
        icmd = &elsiocb->iocb;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
@@ -1291,10 +1268,10 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
                ndlp->nlp_flag &= ~NLP_LOGO_SND;
                spin_unlock_irq(phba->host->host_lock);
                lpfc_els_free_iocb(phba, elsiocb);
-               return 1;
+               return (1);
        }
        spin_unlock_irq(phba->host->host_lock);
-       return 0;
+       return (0);
 }
 
 static void
@@ -1309,10 +1286,9 @@ lpfc_cmpl_els_cmd(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
        lpfc_printf_log(phba,
                        KERN_INFO,
                        LOG_ELS,
-                       "%d:0106 ELS cmd tag x%x completes Data: x%x x%x x%x\n",
+                       "%d:0106 ELS cmd tag x%x completes Data: x%x x%x\n",
                        phba->brd_no,
-                       irsp->ulpIoTag, irsp->ulpStatus,
-                       irsp->un.ulpWord[4], irsp->ulpTimeout);
+                       irsp->ulpIoTag, irsp->ulpStatus, irsp->un.ulpWord[4]);
 
        /* Check to see if link went down during discovery */
        lpfc_els_chk_latt(phba);
@@ -1334,17 +1310,16 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
        psli = &phba->sli;
        pring = &psli->ring[LPFC_ELS_RING];     /* ELS ring */
        cmdsize = (sizeof (uint32_t) + sizeof (SCR));
-       ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
-       if (!ndlp)
-               return 1;
+       if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) == 0) {
+               return (1);
+       }
 
        lpfc_nlp_init(phba, ndlp, nportid);
 
-       elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp,
-                                               ndlp->nlp_DID, ELS_CMD_SCR);
-       if (!elsiocb) {
+       if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry,
+                                         ndlp, ELS_CMD_SCR)) == 0) {
                mempool_free( ndlp, phba->nlp_mem_pool);
-               return 1;
+               return (1);
        }
 
        icmd = &elsiocb->iocb;
@@ -1364,11 +1339,11 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
                spin_unlock_irq(phba->host->host_lock);
                mempool_free( ndlp, phba->nlp_mem_pool);
                lpfc_els_free_iocb(phba, elsiocb);
-               return 1;
+               return (1);
        }
        spin_unlock_irq(phba->host->host_lock);
        mempool_free( ndlp, phba->nlp_mem_pool);
-       return 0;
+       return (0);
 }
 
 static int
@@ -1388,16 +1363,15 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
        psli = &phba->sli;
        pring = &psli->ring[LPFC_ELS_RING];     /* ELS ring */
        cmdsize = (sizeof (uint32_t) + sizeof (FARP));
-       ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
-       if (!ndlp)
-               return 1;
+       if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) == 0) {
+               return (1);
+       }
        lpfc_nlp_init(phba, ndlp, nportid);
 
-       elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp,
-                                               ndlp->nlp_DID, ELS_CMD_RNID);
-       if (!elsiocb) {
+       if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry,
+                                         ndlp, ELS_CMD_RNID)) == 0) {
                mempool_free( ndlp, phba->nlp_mem_pool);
-               return 1;
+               return (1);
        }
 
        icmd = &elsiocb->iocb;
@@ -1431,52 +1405,11 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
                spin_unlock_irq(phba->host->host_lock);
                mempool_free( ndlp, phba->nlp_mem_pool);
                lpfc_els_free_iocb(phba, elsiocb);
-               return 1;
+               return (1);
        }
        spin_unlock_irq(phba->host->host_lock);
        mempool_free( ndlp, phba->nlp_mem_pool);
-       return 0;
-}
-
-void
-lpfc_cancel_retry_delay_tmo(struct lpfc_hba *phba, struct lpfc_nodelist * nlp)
-{
-       nlp->nlp_flag &= ~NLP_DELAY_TMO;
-       del_timer_sync(&nlp->nlp_delayfunc);
-       nlp->nlp_last_elscmd = 0;
-
-       if (!list_empty(&nlp->els_retry_evt.evt_listp))
-               list_del_init(&nlp->els_retry_evt.evt_listp);
-
-       if (nlp->nlp_flag & NLP_NPR_2B_DISC) {
-               nlp->nlp_flag &= ~NLP_NPR_2B_DISC;
-               if (phba->num_disc_nodes) {
-                       /* Check to see if there are more
-                        * PLOGIs to be sent
-                        */
-                       lpfc_more_plogi(phba);
-
-                       if (phba->num_disc_nodes == 0) {
-                               phba->fc_flag &= ~FC_NDISC_ACTIVE;
-                               lpfc_can_disctmo(phba);
-                               if (phba->fc_flag & FC_RSCN_MODE) {
-                                       /*
-                                        * Check to see if more RSCNs
-                                        * came in while we were
-                                        * processing this one.
-                                        */
-                                       if((phba->fc_rscn_id_cnt==0) &&
-                                        !(phba->fc_flag & FC_RSCN_DISCOVERY)) {
-                                               phba->fc_flag &= ~FC_RSCN_MODE;
-                                       }
-                                       else {
-                                               lpfc_els_handle_rscn(phba);
-                                       }
-                               }
-                       }
-               }
-       }
-       return;
+       return (0);
 }
 
 void
@@ -1517,9 +1450,8 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
 
        phba = ndlp->nlp_phba;
        spin_lock_irq(phba->host->host_lock);
-       did = ndlp->nlp_DID;
-       cmd = ndlp->nlp_last_elscmd;
-       ndlp->nlp_last_elscmd = 0;
+       did = (uint32_t) (ndlp->nlp_DID);
+       cmd = (uint32_t) (ndlp->nlp_last_elscmd);
 
        if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
                spin_unlock_irq(phba->host->host_lock);
@@ -1528,12 +1460,6 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
 
        ndlp->nlp_flag &= ~NLP_DELAY_TMO;
        spin_unlock_irq(phba->host->host_lock);
-       /*
-        * If a discovery event readded nlp_delayfunc after timer
-        * firing and before processing the timer, cancel the
-        * nlp_delayfunc.
-        */
-       del_timer_sync(&ndlp->nlp_delayfunc);
        retry = ndlp->nlp_retry;
 
        switch (cmd) {
@@ -1541,32 +1467,24 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
                lpfc_issue_els_flogi(phba, ndlp, retry);
                break;
        case ELS_CMD_PLOGI:
-               if(!lpfc_issue_els_plogi(phba, ndlp->nlp_DID, retry)) {
-                       ndlp->nlp_prev_state = ndlp->nlp_state;
-                       ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
-                       lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
-               }
+               ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
+               lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
+               lpfc_issue_els_plogi(phba, ndlp, retry);
                break;
        case ELS_CMD_ADISC:
-               if (!lpfc_issue_els_adisc(phba, ndlp, retry)) {
-                       ndlp->nlp_prev_state = ndlp->nlp_state;
-                       ndlp->nlp_state = NLP_STE_ADISC_ISSUE;
-                       lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST);
-               }
+               ndlp->nlp_state = NLP_STE_ADISC_ISSUE;
+               lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST);
+               lpfc_issue_els_adisc(phba, ndlp, retry);
                break;
        case ELS_CMD_PRLI:
-               if (!lpfc_issue_els_prli(phba, ndlp, retry)) {
-                       ndlp->nlp_prev_state = ndlp->nlp_state;
-                       ndlp->nlp_state = NLP_STE_PRLI_ISSUE;
-                       lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST);
-               }
+               ndlp->nlp_state = NLP_STE_PRLI_ISSUE;
+               lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST);
+               lpfc_issue_els_prli(phba, ndlp, retry);
                break;
        case ELS_CMD_LOGO:
-               if (!lpfc_issue_els_logo(phba, ndlp, retry)) {
-                       ndlp->nlp_prev_state = ndlp->nlp_state;
-                       ndlp->nlp_state = NLP_STE_NPR_NODE;
-                       lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
-               }
+               ndlp->nlp_state = NLP_STE_NPR_NODE;
+               lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
+               lpfc_issue_els_logo(phba, ndlp, retry);
                break;
        }
        return;
@@ -1584,7 +1502,6 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
        int retry, maxretry;
        int delay;
        uint32_t cmd;
-       uint32_t did;
 
        retry = 0;
        delay = 0;
@@ -1593,7 +1510,6 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
        ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
        pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
        cmd = 0;
-
        /* Note: context2 may be 0 for internal driver abort
         * of delays ELS command.
         */
@@ -1603,16 +1519,6 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                cmd = *elscmd++;
        }
 
-       if(ndlp)
-               did = ndlp->nlp_DID;
-       else {
-               /* We should only hit this case for retrying PLOGI */
-               did = irsp->un.elsreq64.remoteID;
-               ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did);
-               if (!ndlp && (cmd != ELS_CMD_PLOGI))
-                       return 1;
-       }
-
        switch (irsp->ulpStatus) {
        case IOSTAT_FCP_RSP_ERROR:
        case IOSTAT_REMOTE_STOP:
@@ -1631,6 +1537,11 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 
                case IOERR_SEQUENCE_TIMEOUT:
                        retry = 1;
+                       if ((cmd == ELS_CMD_FLOGI)
+                           && (phba->fc_topology != TOPOLOGY_LOOP)) {
+                               delay = 1;
+                               maxretry = 48;
+                       }
                        break;
 
                case IOERR_NO_RESOURCES:
@@ -1701,8 +1612,9 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                break;
        }
 
-       if (did == FDMI_DID)
+       if (ndlp->nlp_DID == FDMI_DID) {
                retry = 1;
+       }
 
        if ((++cmdiocb->retry) >= maxretry) {
                phba->fc_stat.elsRetryExceeded++;
@@ -1716,7 +1628,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                                "%d:0107 Retry ELS command x%x to remote "
                                "NPORT x%x Data: x%x x%x\n",
                                phba->brd_no,
-                               cmd, did, cmdiocb->retry, delay);
+                               cmd, ndlp->nlp_DID, cmdiocb->retry, delay);
 
                if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) {
                        /* If discovery / RSCN timer is running, reset it */
@@ -1727,61 +1639,54 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                }
 
                phba->fc_stat.elsXmitRetry++;
-               if (ndlp && delay) {
+               if (delay) {
                        phba->fc_stat.elsDelayRetry++;
                        ndlp->nlp_retry = cmdiocb->retry;
 
                        mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
                        ndlp->nlp_flag |= NLP_DELAY_TMO;
 
-                       ndlp->nlp_prev_state = ndlp->nlp_state;
                        ndlp->nlp_state = NLP_STE_NPR_NODE;
                        lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
                        ndlp->nlp_last_elscmd = cmd;
 
-                       return 1;
+                       return (1);
                }
                switch (cmd) {
                case ELS_CMD_FLOGI:
                        lpfc_issue_els_flogi(phba, ndlp, cmdiocb->retry);
-                       return 1;
+                       return (1);
                case ELS_CMD_PLOGI:
-                       if (ndlp) {
-                               ndlp->nlp_prev_state = ndlp->nlp_state;
-                               ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
-                               lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
-                       }
-                       lpfc_issue_els_plogi(phba, did, cmdiocb->retry);
-                       return 1;
+                       ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
+                       lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
+                       lpfc_issue_els_plogi(phba, ndlp, cmdiocb->retry);
+                       return (1);
                case ELS_CMD_ADISC:
-                       ndlp->nlp_prev_state = ndlp->nlp_state;
                        ndlp->nlp_state = NLP_STE_ADISC_ISSUE;
                        lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST);
                        lpfc_issue_els_adisc(phba, ndlp, cmdiocb->retry);
-                       return 1;
+                       return (1);
                case ELS_CMD_PRLI:
-                       ndlp->nlp_prev_state = ndlp->nlp_state;
                        ndlp->nlp_state = NLP_STE_PRLI_ISSUE;
                        lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST);
                        lpfc_issue_els_prli(phba, ndlp, cmdiocb->retry);
-                       return 1;
+                       return (1);
                case ELS_CMD_LOGO:
-                       ndlp->nlp_prev_state = ndlp->nlp_state;
                        ndlp->nlp_state = NLP_STE_NPR_NODE;
                        lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
                        lpfc_issue_els_logo(phba, ndlp, cmdiocb->retry);
-                       return 1;
+                       return (1);
                }
        }
 
        /* No retry ELS command <elsCmd> to remote NPORT <did> */
        lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
                        "%d:0108 No retry ELS command x%x to remote NPORT x%x "
-                       "Data: x%x\n",
+                       "Data: x%x x%x\n",
                        phba->brd_no,
-                       cmd, did, cmdiocb->retry);
+                       cmd, ndlp->nlp_DID, cmdiocb->retry, ndlp->nlp_flag);
 
-       return 0;
+       return (0);
 }
 
 int
@@ -1830,6 +1735,10 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                        phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag,
                        ndlp->nlp_state, ndlp->nlp_rpi);
 
+       spin_lock_irq(phba->host->host_lock);
+       ndlp->nlp_flag &= ~NLP_LOGO_ACC;
+       spin_unlock_irq(phba->host->host_lock);
+
        switch (ndlp->nlp_state) {
        case NLP_STE_UNUSED_NODE:       /* node is just allocated */
                lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
@@ -1848,12 +1757,9 @@ static void
 lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                  struct lpfc_iocbq * rspiocb)
 {
-       IOCB_t *irsp;
        struct lpfc_nodelist *ndlp;
        LPFC_MBOXQ_t *mbox = NULL;
 
-       irsp = &rspiocb->iocb;
-
        ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
        if (cmdiocb->context_un.mbox)
                mbox = cmdiocb->context_un.mbox;
@@ -1870,20 +1776,21 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
        /* ELS response tag <ulpIoTag> completes */
        lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
                        "%d:0110 ELS response tag x%x completes "
-                       "Data: x%x x%x x%x x%x x%x x%x x%x\n",
+                       "Data: x%x x%x x%x x%x x%x x%x\n",
                        phba->brd_no,
                        cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus,
-                       rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout,
-                       ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
-                       ndlp->nlp_rpi);
+                       rspiocb->iocb.un.ulpWord[4], ndlp->nlp_DID,
+                       ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
 
        if (mbox) {
                if ((rspiocb->iocb.ulpStatus == 0)
                    && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) {
+                       /* set_slim mailbox command needs to execute first,
+                        * queue this command to be processed later.
+                        */
                        lpfc_unreg_rpi(phba, ndlp);
                        mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
                        mbox->context2 = ndlp;
-                       ndlp->nlp_prev_state = ndlp->nlp_state;
                        ndlp->nlp_state = NLP_STE_REG_LOGIN_ISSUE;
                        lpfc_nlp_list(phba, ndlp, NLP_REGLOGIN_LIST);
                        if (lpfc_sli_issue_mbox(phba, mbox,
@@ -1896,15 +1803,8 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                        mempool_free( mbox, phba->mbox_mem_pool);
                } else {
                        mempool_free( mbox, phba->mbox_mem_pool);
-                       /* Do not call NO_LIST for lpfc_els_abort'ed ELS cmds */
-                       if (!((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
-                             ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
-                              (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
-                              (irsp->un.ulpWord[4] == IOERR_SLI_DOWN)))) {
-                               if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
-                                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
-                                       ndlp = NULL;
-                               }
+                       if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
+                               lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                        }
                }
        }
@@ -1931,7 +1831,6 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
        uint8_t *pcmd;
        uint16_t cmdsize;
        int rc;
-       ELS_PKT *els_pkt_ptr;
 
        psli = &phba->sli;
        pring = &psli->ring[LPFC_ELS_RING];     /* ELS ring */
@@ -1940,11 +1839,10 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
        switch (flag) {
        case ELS_CMD_ACC:
                cmdsize = sizeof (uint32_t);
-               elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
-                                       ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
-               if (!elsiocb) {
-                       ndlp->nlp_flag &= ~NLP_LOGO_ACC;
-                       return 1;
+               if ((elsiocb =
+                    lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
+                                       ndlp, ELS_CMD_ACC)) == 0) {
+                       return (1);
                }
                icmd = &elsiocb->iocb;
                icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
@@ -1954,11 +1852,11 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
                break;
        case ELS_CMD_PLOGI:
                cmdsize = (sizeof (struct serv_parm) + sizeof (uint32_t));
-               elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
-                                       ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
-               if (!elsiocb)
-                       return 1;
-
+               if ((elsiocb =
+                    lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
+                                       ndlp, ELS_CMD_ACC)) == 0) {
+                       return (1);
+               }
                icmd = &elsiocb->iocb;
                icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
                pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
@@ -1970,25 +1868,8 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
                pcmd += sizeof (uint32_t);
                memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm));
                break;
-       case ELS_CMD_PRLO:
-               cmdsize = sizeof (uint32_t) + sizeof (PRLO);
-               elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
-                                            ndlp, ndlp->nlp_DID, ELS_CMD_PRLO);
-               if (!elsiocb)
-                       return 1;
-
-               icmd = &elsiocb->iocb;
-               icmd->ulpContext = oldcmd->ulpContext; /* Xri */
-               pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
-
-               memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt,
-                      sizeof (uint32_t) + sizeof (PRLO));
-               *((uint32_t *) (pcmd)) = ELS_CMD_PRLO_ACC;
-               els_pkt_ptr = (ELS_PKT *) pcmd;
-               els_pkt_ptr->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED;
-               break;
        default:
-               return 1;
+               return (1);
        }
 
        if (newnode)
@@ -2004,9 +1885,6 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
                        ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
 
        if (ndlp->nlp_flag & NLP_LOGO_ACC) {
-               spin_lock_irq(phba->host->host_lock);
-               ndlp->nlp_flag &= ~NLP_LOGO_ACC;
-               spin_unlock_irq(phba->host->host_lock);
                elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc;
        } else {
                elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
@@ -2018,9 +1896,9 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
        spin_unlock_irq(phba->host->host_lock);
        if (rc == IOCB_ERROR) {
                lpfc_els_free_iocb(phba, elsiocb);
-               return 1;
+               return (1);
        }
-       return 0;
+       return (0);
 }
 
 int
@@ -2040,10 +1918,10 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError,
        pring = &psli->ring[LPFC_ELS_RING];     /* ELS ring */
 
        cmdsize = 2 * sizeof (uint32_t);
-       elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
-                                       ndlp, ndlp->nlp_DID, ELS_CMD_LS_RJT);
-       if (!elsiocb)
-               return 1;
+       if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
+                                         ndlp, ELS_CMD_LS_RJT)) == 0) {
+               return (1);
+       }
 
        icmd = &elsiocb->iocb;
        oldcmd = &oldiocb->iocb;
@@ -2070,9 +1948,9 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError,
        spin_unlock_irq(phba->host->host_lock);
        if (rc == IOCB_ERROR) {
                lpfc_els_free_iocb(phba, elsiocb);
-               return 1;
+               return (1);
        }
-       return 0;
+       return (0);
 }
 
 int
@@ -2093,10 +1971,10 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba,
        pring = &psli->ring[LPFC_ELS_RING];     /* ELS ring */
 
        cmdsize = sizeof (uint32_t) + sizeof (ADISC);
-       elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
-                                       ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
-       if (!elsiocb)
-               return 1;
+       if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
+                                         ndlp, ELS_CMD_ACC)) == 0) {
+               return (1);
+       }
 
        /* Xmit ADISC ACC response tag <ulpIoTag> */
        lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
@@ -2128,9 +2006,9 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba,
        spin_unlock_irq(phba->host->host_lock);
        if (rc == IOCB_ERROR) {
                lpfc_els_free_iocb(phba, elsiocb);
-               return 1;
+               return (1);
        }
-       return 0;
+       return (0);
 }
 
 int
@@ -2152,10 +2030,13 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba * phba,
        pring = &psli->ring[LPFC_ELS_RING];     /* ELS ring */
 
        cmdsize = sizeof (uint32_t) + sizeof (PRLI);
-       elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, ndlp,
-               ndlp->nlp_DID, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)));
-       if (!elsiocb)
-               return 1;
+       if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
+                                         ndlp,
+                                         (ELS_CMD_ACC |
+                                          (ELS_CMD_PRLI & ~ELS_RSP_MASK)))) ==
+           0) {
+               return (1);
+       }
 
        /* Xmit PRLI ACC response tag <ulpIoTag> */
        lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
@@ -2205,9 +2086,9 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba * phba,
        spin_unlock_irq(phba->host->host_lock);
        if (rc == IOCB_ERROR) {
                lpfc_els_free_iocb(phba, elsiocb);
-               return 1;
+               return (1);
        }
-       return 0;
+       return (0);
 }
 
 static int
@@ -2233,10 +2114,10 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba,
        if (format)
                cmdsize += sizeof (RNID_TOP_DISC);
 
-       elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
-                                       ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
-       if (!elsiocb)
-               return 1;
+       if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
+                                         ndlp, ELS_CMD_ACC)) == 0) {
+               return (1);
+       }
 
        /* Xmit RNID ACC response tag <ulpIoTag> */
        lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
@@ -2288,9 +2169,9 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba,
        spin_unlock_irq(phba->host->host_lock);
        if (rc == IOCB_ERROR) {
                lpfc_els_free_iocb(phba, elsiocb);
-               return 1;
+               return (1);
        }
-       return 0;
+       return (0);
 }
 
 int
@@ -2306,7 +2187,6 @@ lpfc_els_disc_adisc(struct lpfc_hba * phba)
                if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
                        if (ndlp->nlp_flag & NLP_NPR_ADISC) {
                                ndlp->nlp_flag &= ~NLP_NPR_ADISC;
-                               ndlp->nlp_prev_state = ndlp->nlp_state;
                                ndlp->nlp_state = NLP_STE_ADISC_ISSUE;
                                lpfc_nlp_list(phba, ndlp,
                                        NLP_ADISC_LIST);
@@ -2328,7 +2208,7 @@ lpfc_els_disc_adisc(struct lpfc_hba * phba)
                phba->fc_flag &= ~FC_NLP_MORE;
                spin_unlock_irq(phba->host->host_lock);
        }
-       return sentadisc;
+       return(sentadisc);
 }
 
 int
@@ -2344,10 +2224,9 @@ lpfc_els_disc_plogi(struct lpfc_hba * phba)
                if ((ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
                   (!(ndlp->nlp_flag & NLP_DELAY_TMO))) {
                        if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
-                               ndlp->nlp_prev_state = ndlp->nlp_state;
                                ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
                                lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
-                               lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0);
+                               lpfc_issue_els_plogi(phba, ndlp, 0);
                                sentplogi++;
                                phba->num_disc_nodes++;
                                if (phba->num_disc_nodes >=
@@ -2365,7 +2244,7 @@ lpfc_els_disc_plogi(struct lpfc_hba * phba)
                phba->fc_flag &= ~FC_NLP_MORE;
                spin_unlock_irq(phba->host->host_lock);
        }
-       return sentplogi;
+       return(sentplogi);
 }
 
 int
@@ -2385,7 +2264,7 @@ lpfc_els_flush_rscn(struct lpfc_hba * phba)
        phba->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY);
        spin_unlock_irq(phba->host->host_lock);
        lpfc_can_disctmo(phba);
-       return 0;
+       return (0);
 }
 
 int
@@ -2406,7 +2285,7 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did)
 
        /* If we are doing a FULL RSCN rediscovery, match everything */
        if (phba->fc_flag & FC_RSCN_DISCOVERY) {
-               return did;
+               return (did);
        }
 
        for (i = 0; i < phba->fc_rscn_id_cnt; i++) {
@@ -2454,7 +2333,7 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did)
                        }
                }
        }
-       return match;
+       return (match);
 }
 
 static int
@@ -2486,15 +2365,17 @@ lpfc_rscn_recovery_check(struct lpfc_hba * phba)
 
                        lpfc_disc_state_machine(phba, ndlp, NULL,
                                        NLP_EVT_DEVICE_RECOVERY);
-
-                       /* Make sure NLP_DELAY_TMO is NOT running
-                        * after a device recovery event.
-                        */
-                       if (ndlp->nlp_flag & NLP_DELAY_TMO)
-                               lpfc_cancel_retry_delay_tmo(phba, ndlp);
+                       if (ndlp->nlp_flag & NLP_DELAY_TMO) {
+                               ndlp->nlp_flag &= ~NLP_DELAY_TMO;
+                               del_timer_sync(&ndlp->nlp_delayfunc);
+                               if (!list_empty(&ndlp->
+                                               els_retry_evt.evt_listp))
+                                       list_del_init(&ndlp->
+                                               els_retry_evt.evt_listp);
+                       }
                }
        }
-       return 0;
+       return (0);
 }
 
 static int
@@ -2527,10 +2408,10 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba,
        /* If we are about to begin discovery, just ACC the RSCN.
         * Discovery processing will satisfy it.
         */
-       if (phba->hba_state <= LPFC_NS_QRY) {
+       if (phba->hba_state < LPFC_NS_QRY) {
                lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL,
                                                                newnode);
-               return 0;
+               return (0);
        }
 
        /* If we are already processing an RSCN, save the received
@@ -2572,7 +2453,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba,
 
                /* send RECOVERY event for ALL nodes that match RSCN payload */
                lpfc_rscn_recovery_check(phba);
-               return 0;
+               return (0);
        }
 
        phba->fc_flag |= FC_RSCN_MODE;
@@ -2591,7 +2472,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba,
        /* send RECOVERY event for ALL nodes that match RSCN payload */
        lpfc_rscn_recovery_check(phba);
 
-       return lpfc_els_handle_rscn(phba);
+       return (lpfc_els_handle_rscn(phba));
 }
 
 int
@@ -2613,41 +2494,40 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba)
 
        /* To process RSCN, first compare RSCN data with NameServer */
        phba->fc_ns_retry = 0;
-       ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, NameServer_DID);
-       if (ndlp) {
+       if ((ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED,
+                                     NameServer_DID))) {
                /* Good ndlp, issue CT Request to NameServer */
                if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) {
                        /* Wait for NameServer query cmpl before we can
                           continue */
-                       return 1;
+                       return (1);
                }
        } else {
                /* If login to NameServer does not exist, issue one */
                /* Good status, issue PLOGI to NameServer */
-               ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID);
-               if (ndlp) {
+               if ((ndlp =
+                    lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID))) {
                        /* Wait for NameServer login cmpl before we can
                           continue */
-                       return 1;
+                       return (1);
                }
-               ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
-               if (!ndlp) {
+               if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL))
+                   == 0) {
                        lpfc_els_flush_rscn(phba);
-                       return 0;
+                       return (0);
                } else {
                        lpfc_nlp_init(phba, ndlp, NameServer_DID);
                        ndlp->nlp_type |= NLP_FABRIC;
-                       ndlp->nlp_prev_state = ndlp->nlp_state;
                        ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
-                       lpfc_issue_els_plogi(phba, NameServer_DID, 0);
+                       lpfc_issue_els_plogi(phba, ndlp, 0);
                        /* Wait for NameServer login cmpl before we can
                           continue */
-                       return 1;
+                       return (1);
                }
        }
 
        lpfc_els_flush_rscn(phba);
-       return 0;
+       return (0);
 }
 
 static int
@@ -2681,7 +2561,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba,
                                "%d:0113 An FLOGI ELS command x%x was received "
                                "from DID x%x in Loop Mode\n",
                                phba->brd_no, cmd, did);
-               return 1;
+               return (1);
        }
 
        did = Fabric_DID;
@@ -2697,7 +2577,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba,
                if (!rc) {
                        if ((mbox = mempool_alloc(phba->mbox_mem_pool,
                                                  GFP_KERNEL)) == 0) {
-                               return 1;
+                               return (1);
                        }
                        lpfc_linkdown(phba);
                        lpfc_init_link(phba, mbox,
@@ -2710,8 +2590,9 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba,
                        if (rc == MBX_NOT_FINISHED) {
                                mempool_free( mbox, phba->mbox_mem_pool);
                        }
-                       return 1;
-               } else if (rc > 0) {    /* greater than */
+                       return (1);
+               }
+               else if (rc > 0) {      /* greater than */
                        spin_lock_irq(phba->host->host_lock);
                        phba->fc_flag |= FC_PT2PT_PLOGI;
                        spin_unlock_irq(phba->host->host_lock);
@@ -2725,13 +2606,13 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba,
                stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
                stat.un.b.vendorUnique = 0;
                lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
-               return 1;
+               return (1);
        }
 
        /* Send back ACC */
        lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode);
 
-       return 0;
+       return (0);
 }
 
 static int
@@ -2769,246 +2650,45 @@ lpfc_els_rcv_rnid(struct lpfc_hba * phba,
                stat.un.b.vendorUnique = 0;
                lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
        }
-       return 0;
+       return (0);
 }
 
 static int
-lpfc_els_rcv_lirr(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
+lpfc_els_rcv_rrq(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                 struct lpfc_nodelist * ndlp)
 {
-       struct ls_rjt stat;
-
-       /* For now, unconditionally reject this command */
-       stat.un.b.lsRjtRsvd0 = 0;
-       stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
-       stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
-       stat.un.b.vendorUnique = 0;
-       lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
-       return 0;
-}
-
-static void
-lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
-{
-       struct lpfc_sli *psli;
-       struct lpfc_sli_ring *pring;
-       MAILBOX_t *mb;
-       IOCB_t *icmd;
-       RPS_RSP *rps_rsp;
-       uint8_t *pcmd;
-       struct lpfc_iocbq *elsiocb;
-       struct lpfc_nodelist *ndlp;
-       uint16_t xri, status;
-       uint32_t cmdsize;
-
-       psli = &phba->sli;
-       pring = &psli->ring[LPFC_ELS_RING];
-       mb = &pmb->mb;
-
-       ndlp = (struct lpfc_nodelist *) pmb->context2;
-       xri = (uint16_t) ((unsigned long)(pmb->context1));
-       pmb->context1 = NULL;
-       pmb->context2 = NULL;
-
-       if (mb->mbxStatus) {
-               mempool_free( pmb, phba->mbox_mem_pool);
-               return;
-       }
-
-       cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t);
-       mempool_free( pmb, phba->mbox_mem_pool);
-       elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, lpfc_max_els_tries, ndlp,
-                                               ndlp->nlp_DID, ELS_CMD_ACC);
-       if (!elsiocb)
-               return;
-
-       icmd = &elsiocb->iocb;
-       icmd->ulpContext = xri;
-
-       pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
-       *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
-       pcmd += sizeof (uint32_t); /* Skip past command */
-       rps_rsp = (RPS_RSP *)pcmd;
-
-       if (phba->fc_topology != TOPOLOGY_LOOP)
-               status = 0x10;
-       else
-               status = 0x8;
-       if (phba->fc_flag & FC_FABRIC)
-               status |= 0x4;
-
-       rps_rsp->rsvd1 = 0;
-       rps_rsp->portStatus = be16_to_cpu(status);
-       rps_rsp->linkFailureCnt = be32_to_cpu(mb->un.varRdLnk.linkFailureCnt);
-       rps_rsp->lossSyncCnt = be32_to_cpu(mb->un.varRdLnk.lossSyncCnt);
-       rps_rsp->lossSignalCnt = be32_to_cpu(mb->un.varRdLnk.lossSignalCnt);
-       rps_rsp->primSeqErrCnt = be32_to_cpu(mb->un.varRdLnk.primSeqErrCnt);
-       rps_rsp->invalidXmitWord = be32_to_cpu(mb->un.varRdLnk.invalidXmitWord);
-       rps_rsp->crcCnt = be32_to_cpu(mb->un.varRdLnk.crcCnt);
-
-       /* Xmit ELS RPS ACC response tag <ulpIoTag> */
-       lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
-                       "%d:0118 Xmit ELS RPS ACC response tag x%x "
-                       "Data: x%x x%x x%x x%x x%x\n",
-                       phba->brd_no,
-                       elsiocb->iocb.ulpIoTag,
-                       elsiocb->iocb.ulpContext, ndlp->nlp_DID,
-                       ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
-
-       elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
-       phba->fc_stat.elsXmitACC++;
-       if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
-               lpfc_els_free_iocb(phba, elsiocb);
-       }
-       return;
-}
-
-static int
-lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-                struct lpfc_nodelist * ndlp)
-{
-       uint32_t *lp;
-       uint8_t flag;
-       LPFC_MBOXQ_t *mbox;
        struct lpfc_dmabuf *pcmd;
-       RPS *rps;
-       struct ls_rjt stat;
-
-       if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
-           (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
-               stat.un.b.lsRjtRsvd0 = 0;
-               stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
-               stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
-               stat.un.b.vendorUnique = 0;
-               lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
-       }
-
-       pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
-       lp = (uint32_t *) pcmd->virt;
-       flag = (be32_to_cpu(*lp++) & 0xf);
-       rps = (RPS *) lp;
-
-       if ((flag == 0) ||
-           ((flag == 1) && (be32_to_cpu(rps->un.portNum) == 0)) ||
-           ((flag == 2) && (memcmp(&rps->un.portName, &phba->fc_portname,
-                          sizeof (struct lpfc_name)) == 0))) {
-               if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC))) {
-                       lpfc_read_lnk_stat(phba, mbox);
-                       mbox->context1 =
-                           (void *)((unsigned long)cmdiocb->iocb.ulpContext);
-                       mbox->context2 = ndlp;
-                       mbox->mbox_cmpl = lpfc_els_rsp_rps_acc;
-                       if (lpfc_sli_issue_mbox (phba, mbox,
-                           (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) {
-                               /* Mbox completion will send ELS Response */
-                               return 0;
-                       }
-                       mempool_free(mbox, phba->mbox_mem_pool);
-               }
-       }
-       stat.un.b.lsRjtRsvd0 = 0;
-       stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
-       stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
-       stat.un.b.vendorUnique = 0;
-       lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
-       return 0;
-}
-
-static int
-lpfc_els_rsp_rpl_acc(struct lpfc_hba * phba, uint16_t cmdsize,
-                struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp)
-{
+       uint32_t *lp;
        IOCB_t *icmd;
-       IOCB_t *oldcmd;
-       RPL_RSP rpl_rsp;
-       struct lpfc_iocbq *elsiocb;
        struct lpfc_sli_ring *pring;
        struct lpfc_sli *psli;
-       uint8_t *pcmd;
+       RRQ *rrq;
+       uint32_t cmd, did;
 
        psli = &phba->sli;
-       pring = &psli->ring[LPFC_ELS_RING];     /* ELS ring */
-
-       elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
-                                       ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
-       if (!elsiocb)
-               return 1;
-
-       icmd = &elsiocb->iocb;
-       oldcmd = &oldiocb->iocb;
-       icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
-
-       pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
-       *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
-       pcmd += sizeof (uint16_t);
-       *((uint16_t *)(pcmd)) = be16_to_cpu(cmdsize);
-       pcmd += sizeof(uint16_t);
-
-       /* Setup the RPL ACC payload */
-       rpl_rsp.listLen = be32_to_cpu(1);
-       rpl_rsp.index = 0;
-       rpl_rsp.port_num_blk.portNum = 0;
-       rpl_rsp.port_num_blk.portID = be32_to_cpu(phba->fc_myDID);
-       memcpy(&rpl_rsp.port_num_blk.portName, &phba->fc_portname,
-           sizeof(struct lpfc_name));
-
-       memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t));
-
-
-       /* Xmit ELS RPL ACC response tag <ulpIoTag> */
-       lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
-                       "%d:0120 Xmit ELS RPL ACC response tag x%x "
-                       "Data: x%x x%x x%x x%x x%x\n",
-                       phba->brd_no,
-                       elsiocb->iocb.ulpIoTag,
-                       elsiocb->iocb.ulpContext, ndlp->nlp_DID,
-                       ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
-
-       elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
-
-       phba->fc_stat.elsXmitACC++;
-       if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
-               lpfc_els_free_iocb(phba, elsiocb);
-               return 1;
-       }
-       return 0;
-}
-
-static int
-lpfc_els_rcv_rpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-                struct lpfc_nodelist * ndlp)
-{
-       struct lpfc_dmabuf *pcmd;
-       uint32_t *lp;
-       uint32_t maxsize;
-       uint16_t cmdsize;
-       RPL *rpl;
-       struct ls_rjt stat;
-
-       if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
-           (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
-               stat.un.b.lsRjtRsvd0 = 0;
-               stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
-               stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
-               stat.un.b.vendorUnique = 0;
-               lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
-       }
-
+       pring = &psli->ring[LPFC_FCP_RING];
+       icmd = &cmdiocb->iocb;
+       did = icmd->un.elsreq64.remoteID;
        pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
        lp = (uint32_t *) pcmd->virt;
-       rpl = (RPL *) (lp + 1);
 
-       maxsize = be32_to_cpu(rpl->maxsize);
+       cmd = *lp++;
+       rrq = (RRQ *) lp;
 
-       /* We support only one port */
-       if ((rpl->index == 0) &&
-           ((maxsize == 0) ||
-            ((maxsize * sizeof(uint32_t)) >= sizeof(RPL_RSP)))) {
-               cmdsize = sizeof(uint32_t) + sizeof(RPL_RSP);
+       /* RRQ received */
+       /* Get oxid / rxid from payload and abort it */
+       spin_lock_irq(phba->host->host_lock);
+       if ((rrq->SID == be32_to_cpu(phba->fc_myDID))) {
+               lpfc_sli_abort_iocb(phba, pring, 0, 0, rrq->Oxid,
+                                                       LPFC_CTX_CTX);
        } else {
-               cmdsize = sizeof(uint32_t) + maxsize * sizeof(uint32_t);
+               lpfc_sli_abort_iocb(phba, pring, 0, 0, rrq->Rxid,
+                                                       LPFC_CTX_CTX);
        }
-       lpfc_els_rsp_rpl_acc(phba, cmdsize, cmdiocb, ndlp);
+
+       spin_unlock_irq(phba->host->host_lock);
+       /* ACCEPT the rrq request */
+       lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
 
        return 0;
 }
@@ -3040,7 +2720,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba,
 
        /* We will only support match on WWPN or WWNN */
        if (fp->Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) {
-               return 0;
+               return (0);
        }
 
        cnt = 0;
@@ -3063,10 +2743,9 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba,
                   (ndlp->nlp_state == NLP_STE_MAPPED_NODE)) {
                        /* Log back into the node before sending the FARP. */
                        if (fp->Rflags & FARP_REQUEST_PLOGI) {
-                               ndlp->nlp_prev_state = ndlp->nlp_state;
                                ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
                                lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
-                               lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0);
+                               lpfc_issue_els_plogi(phba, ndlp, 0);
                        }
 
                        /* Send a FARP response to that node */
@@ -3075,7 +2754,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba,
                        }
                }
        }
-       return 0;
+       return (0);
 }
 
 static int
@@ -3108,89 +2787,47 @@ lpfc_els_rcv_farpr(struct lpfc_hba * phba,
 
 static int
 lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-                struct lpfc_nodelist * fan_ndlp)
+                struct lpfc_nodelist * ndlp)
 {
        struct lpfc_dmabuf *pcmd;
        uint32_t *lp;
        IOCB_t *icmd;
-       uint32_t cmd, did;
        FAN *fp;
-       struct lpfc_nodelist *ndlp, *next_ndlp;
-
-       /* FAN received */
-       lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0265 FAN received\n",
-                                                               phba->brd_no);
+       uint32_t cmd, did;
 
        icmd = &cmdiocb->iocb;
        did = icmd->un.elsreq64.remoteID;
-       pcmd = (struct lpfc_dmabuf *)cmdiocb->context2;
-       lp = (uint32_t *)pcmd->virt;
+       pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
+       lp = (uint32_t *) pcmd->virt;
 
        cmd = *lp++;
-       fp = (FAN *)lp;
+       fp = (FAN *) lp;
 
-       /* FAN received; Fan does not have a reply sequence */
-
-       if (phba->hba_state == LPFC_LOCAL_CFG_LINK) {
-               if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName,
-                       sizeof(struct lpfc_name)) != 0) ||
-                   (memcmp(&phba->fc_fabparam.portName, &fp->FportName,
-                       sizeof(struct lpfc_name)) != 0)) {
-                       /*
-                        * This node has switched fabrics.  FLOGI is required
-                        * Clean up the old rpi's
-                        */
+       /* FAN received */
 
-                       list_for_each_entry_safe(ndlp, next_ndlp,
-                               &phba->fc_npr_list, nlp_listp) {
-
-                               if (ndlp->nlp_type & NLP_FABRIC) {
-                                       /*
-                                        * Clean up old Fabric, Nameserver and
-                                        * other NLP_FABRIC logins
-                                        */
-                                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
-                               } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
-                                       /* Fail outstanding I/O now since this
-                                        * device is marked for PLOGI
-                                        */
-                                       lpfc_unreg_rpi(phba, ndlp);
-                               }
-                       }
+       /* ACCEPT the FAN request */
+       lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
 
-                       phba->hba_state = LPFC_FLOGI;
-                       lpfc_set_disctmo(phba);
-                       lpfc_initial_flogi(phba);
-                       return 0;
-               }
-               /* Discovery not needed,
-                * move the nodes to their original state.
+       if (phba->hba_state == LPFC_LOCAL_CFG_LINK) {
+               /* The discovery state machine needs to take a different
+                * action if this node has switched fabrics
                 */
-               list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list,
-                       nlp_listp) {
-
-                       switch (ndlp->nlp_prev_state) {
-                       case NLP_STE_UNMAPPED_NODE:
-                               ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
-                               ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
-                               lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
-                               break;
-
-                       case NLP_STE_MAPPED_NODE:
-                               ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
-                               ndlp->nlp_state = NLP_STE_MAPPED_NODE;
-                               lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST);
-                               break;
-
-                       default:
-                               break;
-                       }
+               if ((memcmp(&fp->FportName, &phba->fc_fabparam.portName,
+                           sizeof (struct lpfc_name)) != 0)
+                   ||
+                   (memcmp(&fp->FnodeName, &phba->fc_fabparam.nodeName,
+                           sizeof (struct lpfc_name)) != 0)) {
+                       /* This node has switched fabrics.  An FLOGI is required
+                        * after the timeout
+                        */
+                       return (0);
                }
 
-               /* Start discovery - this should just do CLEAR_LA */
+               /* Start discovery */
                lpfc_disc_start(phba);
        }
-       return 0;
+
+       return (0);
 }
 
 void
@@ -3267,9 +2904,8 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
 
                if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) {
                        struct lpfc_nodelist *ndlp;
-                       spin_unlock_irq(phba->host->host_lock);
+
                        ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext);
-                       spin_lock_irq(phba->host->host_lock);
                        remote_ID = ndlp->nlp_DID;
                        if (cmd->un.elsreq64.bdl.ulpIoTag32) {
                                lpfc_sli_issue_abort_iotag32(phba,
@@ -3298,9 +2934,10 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
                } else
                        lpfc_sli_release_iocbq(phba, piocb);
        }
-       if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt)
-               mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout);
-
+       if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) {
+               phba->els_tmofunc.expires = jiffies + HZ * timeout;
+               add_timer(&phba->els_tmofunc);
+       }
        spin_unlock_irq(phba->host->host_lock);
 }
 
@@ -3313,6 +2950,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
        struct lpfc_dmabuf *pcmd;
        uint32_t *elscmd;
        uint32_t els_command;
+       uint32_t remote_ID;
 
        pring = &phba->sli.ring[LPFC_ELS_RING];
        spin_lock_irq(phba->host->host_lock);
@@ -3335,6 +2973,18 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
                elscmd = (uint32_t *) (pcmd->virt);
                els_command = *elscmd;
 
+               if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) {
+                       struct lpfc_nodelist *ndlp;
+
+                       ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext);
+                       remote_ID = ndlp->nlp_DID;
+                       if (phba->hba_state == LPFC_HBA_READY) {
+                               continue;
+                       }
+               } else {
+                       remote_ID = cmd->un.elsreq64.remoteID;
+               }
+
                list_del(&piocb->list);
                pring->txcmplq_cnt--;
 
@@ -3345,7 +2995,8 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
                        spin_unlock_irq(phba->host->host_lock);
                        (piocb->iocb_cmpl) (phba, piocb, piocb);
                        spin_lock_irq(phba->host->host_lock);
-               } else
+               }
+               else
                        lpfc_sli_release_iocbq(phba, piocb);
        }
 
@@ -3359,6 +3010,18 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
                elscmd = (uint32_t *) (pcmd->virt);
                els_command = *elscmd;
 
+               if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) {
+                       struct lpfc_nodelist *ndlp;
+
+                       ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext);
+                       remote_ID = ndlp->nlp_DID;
+                       if (phba->hba_state == LPFC_HBA_READY) {
+                               continue;
+                       }
+               } else {
+                       remote_ID = cmd->un.elsreq64.remoteID;
+               }
+
                list_del(&piocb->list);
                pring->txcmplq_cnt--;
 
@@ -3369,7 +3032,8 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
                        spin_unlock_irq(phba->host->host_lock);
                        (piocb->iocb_cmpl) (phba, piocb, piocb);
                        spin_lock_irq(phba->host->host_lock);
-               } else
+               }
+               else
                        lpfc_sli_release_iocbq(phba, piocb);
        }
        spin_unlock_irq(phba->host->host_lock);
@@ -3441,11 +3105,10 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
        }
 
        did = icmd->un.rcvels.remoteID;
-       ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did);
-       if (!ndlp) {
+       if ((ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did)) == 0) {
                /* Cannot find existing Fabric ndlp, so allocate a new one */
-               ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
-               if (!ndlp) {
+               if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL))
+                   == 0) {
                        lpfc_mbuf_free(phba, mp->virt, mp->phys);
                        kfree(mp);
                        drop_cmd = 1;
@@ -3457,8 +3120,6 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) {
                        ndlp->nlp_type |= NLP_FABRIC;
                }
-               ndlp->nlp_state = NLP_STE_UNUSED_NODE;
-               lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
        }
 
        phba->fc_stat.elsRcvFrame++;
@@ -3480,14 +3141,13 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                        rjt_err = 1;
                        break;
                }
-               ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp);
                lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI);
                break;
        case ELS_CMD_FLOGI:
                phba->fc_stat.elsRcvFLOGI++;
                lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode);
                if (newnode) {
-                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
+                       mempool_free( ndlp, phba->nlp_mem_pool);
                }
                break;
        case ELS_CMD_LOGO:
@@ -3510,7 +3170,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                phba->fc_stat.elsRcvRSCN++;
                lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode);
                if (newnode) {
-                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
+                       mempool_free( ndlp, phba->nlp_mem_pool);
                }
                break;
        case ELS_CMD_ADISC:
@@ -3541,6 +3201,10 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                phba->fc_stat.elsRcvFAN++;
                lpfc_els_rcv_fan(phba, elsiocb, ndlp);
                break;
+       case ELS_CMD_RRQ:
+               phba->fc_stat.elsRcvRRQ++;
+               lpfc_els_rcv_rrq(phba, elsiocb, ndlp);
+               break;
        case ELS_CMD_PRLI:
                phba->fc_stat.elsRcvPRLI++;
                if (phba->hba_state < LPFC_DISC_AUTH) {
@@ -3549,33 +3213,9 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                }
                lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PRLI);
                break;
-       case ELS_CMD_LIRR:
-               phba->fc_stat.elsRcvLIRR++;
-               lpfc_els_rcv_lirr(phba, elsiocb, ndlp);
-               if (newnode) {
-                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
-               }
-               break;
-       case ELS_CMD_RPS:
-               phba->fc_stat.elsRcvRPS++;
-               lpfc_els_rcv_rps(phba, elsiocb, ndlp);
-               if (newnode) {
-                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
-               }
-               break;
-       case ELS_CMD_RPL:
-               phba->fc_stat.elsRcvRPL++;
-               lpfc_els_rcv_rpl(phba, elsiocb, ndlp);
-               if (newnode) {
-                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
-               }
-               break;
        case ELS_CMD_RNID:
                phba->fc_stat.elsRcvRNID++;
                lpfc_els_rcv_rnid(phba, elsiocb, ndlp);
-               if (newnode) {
-                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
-               }
                break;
        default:
                /* Unsupported ELS command, reject */
@@ -3586,7 +3226,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                                "%d:0115 Unknown ELS command x%x received from "
                                "NPORT x%x\n", phba->brd_no, cmd, did);
                if (newnode) {
-                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
+                       mempool_free( ndlp, phba->nlp_mem_pool);
                }
                break;
        }
@@ -3609,9 +3249,8 @@ dropit:
        if (drop_cmd == 1) {
                lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
                                "%d:0111 Dropping received ELS cmd "
-                               "Data: x%x x%x x%x\n", phba->brd_no,
-                               icmd->ulpStatus, icmd->un.ulpWord[4],
-                               icmd->ulpTimeout);
+                               "Data: x%x x%x\n", phba->brd_no,
+                               icmd->ulpStatus, icmd->un.ulpWord[4]);
                phba->fc_stat.elsRcvDrop++;
        }
        return;