]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/lpfc/lpfc_ct.c
Merge branch 'master' of ../linux-2.6/
[linux-2.6-omap-h63xx.git] / drivers / scsi / lpfc / lpfc_ct.c
index 5584f395314c741ad9713e06750540afe7ab8923..3d0ccd9b341de1272607790f4ff85e0503d44d8d 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-2007 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2008 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -19,7 +19,7 @@
  *******************************************************************/
 
 /*
- * Fibre Channel SCSI LAN Device Driver CT support
+ * Fibre Channel SCSI LAN Device Driver CT support: FC Generic Services FC-GS
  */
 
 #include <linux/blkdev.h>
@@ -41,6 +41,7 @@
 #include "lpfc_crtn.h"
 #include "lpfc_version.h"
 #include "lpfc_vport.h"
+#include "lpfc_debugfs.h"
 
 #define HBA_PORTSPEED_UNKNOWN               0  /* Unknown - transceiver
                                                 * incapable of reporting */
 
 static char *lpfc_release_version = LPFC_DRIVER_VERSION;
 
-/*
- * lpfc_ct_unsol_event
- */
 static void
-lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
-                    struct lpfc_dmabuf *mp, uint32_t size)
+lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
+                         struct lpfc_dmabuf *mp, uint32_t size)
 {
        if (!mp) {
-               printk(KERN_ERR "%s (%d): Unsolited CT, no buffer, "
-                      "piocbq = %p, status = x%x, mp = %p, size = %d\n",
-                      __FUNCTION__, __LINE__,
-                      piocbq, piocbq->iocb.ulpStatus, mp, size);
+               lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
+                               "0146 Ignoring unsolicted CT No HBQ "
+                               "status = x%x\n",
+                               piocbq->iocb.ulpStatus);
        }
-
-       printk(KERN_ERR "%s (%d): Ignoring unsolicted CT piocbq = %p, "
-              "buffer = %p, size = %d, status = x%x\n",
-              __FUNCTION__, __LINE__,
-              piocbq, mp, size,
-              piocbq->iocb.ulpStatus);
-
+       lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
+                       "0145 Ignoring unsolicted CT HBQ Size:%d "
+                       "status = x%x\n",
+                       size, piocbq->iocb.ulpStatus);
 }
 
 static void
-lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
-                         struct lpfc_dmabuf *mp, uint32_t size)
+lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
+                    struct lpfc_dmabuf *mp, uint32_t size)
 {
-       if (!mp) {
-               printk(KERN_ERR "%s (%d): Unsolited CT, no "
-                      "HBQ buffer, piocbq = %p, status = x%x\n",
-                      __FUNCTION__, __LINE__,
-                      piocbq, piocbq->iocb.ulpStatus);
-       } else {
-               lpfc_ct_unsol_buffer(phba, piocbq, mp, size);
-               printk(KERN_ERR "%s (%d): Ignoring unsolicted CT "
-                      "piocbq = %p, buffer = %p, size = %d, "
-                      "status = x%x\n",
-                      __FUNCTION__, __LINE__,
-                      piocbq, mp, size, piocbq->iocb.ulpStatus);
-       }
+       lpfc_ct_ignore_hbq_buffer(phba, piocbq, mp, size);
 }
 
 void
@@ -108,11 +91,8 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
        struct lpfc_iocbq *iocbq;
        dma_addr_t paddr;
        uint32_t size;
-       struct lpfc_dmabuf *bdeBuf1 = piocbq->context2;
-       struct lpfc_dmabuf *bdeBuf2 = piocbq->context3;
-
-       piocbq->context2 = NULL;
-       piocbq->context3 = NULL;
+       struct list_head head;
+       struct lpfc_dmabuf *bdeBuf;
 
        if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) {
                lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
@@ -121,7 +101,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                /* Not enough posted buffers; Try posting more buffers */
                phba->fc_stat.NoRcvBuf++;
                if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
-                       lpfc_post_buffer(phba, pring, 0, 1);
+                       lpfc_post_buffer(phba, pring, 2, 1);
                return;
        }
 
@@ -132,38 +112,34 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                return;
 
        if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
-               list_for_each_entry(iocbq, &piocbq->list, list) {
+               INIT_LIST_HEAD(&head);
+               list_add_tail(&head, &piocbq->list);
+               list_for_each_entry(iocbq, &head, list) {
                        icmd = &iocbq->iocb;
-                       if (icmd->ulpBdeCount == 0) {
-                               printk(KERN_ERR "%s (%d): Unsolited CT, no "
-                                      "BDE, iocbq = %p, status = x%x\n",
-                                      __FUNCTION__, __LINE__,
-                                      iocbq, iocbq->iocb.ulpStatus);
+                       if (icmd->ulpBdeCount == 0)
                                continue;
-                       }
-
+                       bdeBuf = iocbq->context2;
+                       iocbq->context2 = NULL;
                        size  = icmd->un.cont64[0].tus.f.bdeSize;
-                       lpfc_ct_ignore_hbq_buffer(phba, piocbq, bdeBuf1, size);
-                       lpfc_in_buf_free(phba, bdeBuf1);
+                       lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size);
+                       lpfc_in_buf_free(phba, bdeBuf);
                        if (icmd->ulpBdeCount == 2) {
-                               lpfc_ct_ignore_hbq_buffer(phba, piocbq, bdeBuf2,
-                                                         size);
-                               lpfc_in_buf_free(phba, bdeBuf2);
+                               bdeBuf = iocbq->context3;
+                               iocbq->context3 = NULL;
+                               size  = icmd->unsli3.rcvsli3.bde2.tus.f.bdeSize;
+                               lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf,
+                                                    size);
+                               lpfc_in_buf_free(phba, bdeBuf);
                        }
                }
+               list_del(&head);
        } else {
                struct lpfc_iocbq  *next;
 
                list_for_each_entry_safe(iocbq, next, &piocbq->list, list) {
                        icmd = &iocbq->iocb;
-                       if (icmd->ulpBdeCount == 0) {
-                               printk(KERN_ERR "%s (%d): Unsolited CT, no "
-                                      "BDE, iocbq = %p, status = x%x\n",
-                                      __FUNCTION__, __LINE__,
-                                      iocbq, iocbq->iocb.ulpStatus);
-                               continue;
-                       }
-
+                       if (icmd->ulpBdeCount == 0)
+                               lpfc_ct_unsol_buffer(phba, piocbq, NULL, 0);
                        for (i = 0; i < icmd->ulpBdeCount; i++) {
                                paddr = getPaddr(icmd->un.cont64[i].addrHigh,
                                                 icmd->un.cont64[i].addrLow);
@@ -175,6 +151,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                        }
                        list_del(&iocbq->list);
                        lpfc_sli_release_iocbq(phba, iocbq);
+                       lpfc_post_buffer(phba, pring, i, 1);
                }
        }
 }
@@ -202,7 +179,7 @@ lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl,
        struct lpfc_dmabuf *mp;
        int cnt, i = 0;
 
-       /* We get chucks of FCELSSIZE */
+       /* We get chunks of FCELSSIZE */
        cnt = size > FCELSSIZE ? FCELSSIZE: size;
 
        while (size) {
@@ -251,6 +228,36 @@ lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl,
        return mlist;
 }
 
+int
+lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb)
+{
+       struct lpfc_dmabuf *buf_ptr;
+
+       if (ctiocb->context_un.ndlp) {
+               lpfc_nlp_put(ctiocb->context_un.ndlp);
+               ctiocb->context_un.ndlp = NULL;
+       }
+       if (ctiocb->context1) {
+               buf_ptr = (struct lpfc_dmabuf *) ctiocb->context1;
+               lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
+               kfree(buf_ptr);
+               ctiocb->context1 = NULL;
+       }
+       if (ctiocb->context2) {
+               lpfc_free_ct_rsp(phba, (struct lpfc_dmabuf *) ctiocb->context2);
+               ctiocb->context2 = NULL;
+       }
+
+       if (ctiocb->context3) {
+               buf_ptr = (struct lpfc_dmabuf *) ctiocb->context3;
+               lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
+               kfree(buf_ptr);
+               ctiocb->context1 = NULL;
+       }
+       lpfc_sli_release_iocbq(phba, ctiocb);
+       return 0;
+}
+
 static int
 lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
             struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp,
@@ -287,6 +294,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
        /* Save for completion so we can release these resources */
        geniocb->context1 = (uint8_t *) inp;
        geniocb->context2 = (uint8_t *) outp;
+       geniocb->context_un.ndlp = lpfc_nlp_get(ndlp);
 
        /* Fill in payload, bp points to frame payload */
        icmd->ulpCommand = CMD_GEN_REQUEST64_CR;
@@ -314,11 +322,11 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
        }
 
        /* Issue GEN REQ IOCB for NPORT <did> */
-       lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
-                       "%d (%d):0119 Issue GEN REQ IOCB to NPORT x%x "
-                       "Data: x%x x%x\n", phba->brd_no, vport->vpi,
-                       ndlp->nlp_DID, icmd->ulpIoTag,
-                       vport->port_state);
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                        "0119 Issue GEN REQ IOCB to NPORT x%x "
+                        "Data: x%x x%x\n",
+                        ndlp->nlp_DID, icmd->ulpIoTag,
+                        vport->port_state);
        geniocb->iocb_cmpl = cmpl;
        geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
        geniocb->vport = vport;
@@ -363,17 +371,19 @@ lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp,
        return 0;
 }
 
-static struct lpfc_vport *
+struct lpfc_vport *
 lpfc_find_vport_by_did(struct lpfc_hba *phba, uint32_t did) {
-
        struct lpfc_vport *vport_curr;
+       unsigned long flags;
 
+       spin_lock_irqsave(&phba->hbalock, flags);
        list_for_each_entry(vport_curr, &phba->port_list, listentry) {
-               if ((vport_curr->fc_myDID) &&
-                       (vport_curr->fc_myDID == did))
+               if ((vport_curr->fc_myDID) && (vport_curr->fc_myDID == did)) {
+                       spin_unlock_irqrestore(&phba->hbalock, flags);
                        return vport_curr;
+               }
        }
-
+       spin_unlock_irqrestore(&phba->hbalock, flags);
        return NULL;
 }
 
@@ -392,6 +402,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
 
        lpfc_set_disctmo(vport);
        vport->num_disc_nodes = 0;
+       vport->fc_ns_retry = 0;
 
 
        list_add_tail(&head, &mp->list);
@@ -422,51 +433,88 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
                         */
                        if ((Did != vport->fc_myDID) &&
                            ((lpfc_find_vport_by_did(phba, Did) == NULL) ||
-                            phba->cfg_peer_port_login)) {
+                            vport->cfg_peer_port_login)) {
                                if ((vport->port_type != LPFC_NPIV_PORT) ||
-                                   (vport->fc_flag & FC_RFF_NOT_SUPPORTED) ||
-                                   (!phba->cfg_vport_restrict_login)) {
+                                   (!(vport->ct_flags & FC_CT_RFF_ID)) ||
+                                   (!vport->cfg_restrict_login)) {
                                        ndlp = lpfc_setup_disc_node(vport, Did);
                                        if (ndlp) {
-                                               lpfc_printf_log(phba, KERN_INFO,
+                                               lpfc_debugfs_disc_trc(vport,
+                                               LPFC_DISC_TRC_CT,
+                                               "Parse GID_FTrsp: "
+                                               "did:x%x flg:x%x x%x",
+                                               Did, ndlp->nlp_flag,
+                                               vport->fc_flag);
+
+                                               lpfc_printf_vlog(vport,
+                                                       KERN_INFO,
                                                        LOG_DISCOVERY,
-                                                       "%d (%d):0238 Process "
+                                                       "0238 Process "
                                                        "x%x NameServer Rsp"
                                                        "Data: x%x x%x x%x\n",
-                                                       phba->brd_no,
-                                                       vport->vpi, Did,
-                                                       ndlp->nlp_flag,
+                                                       Did, ndlp->nlp_flag,
                                                        vport->fc_flag,
                                                        vport->fc_rscn_id_cnt);
                                        } else {
-                                               lpfc_printf_log(phba, KERN_INFO,
+                                               lpfc_debugfs_disc_trc(vport,
+                                               LPFC_DISC_TRC_CT,
+                                               "Skip1 GID_FTrsp: "
+                                               "did:x%x flg:x%x cnt:%d",
+                                               Did, vport->fc_flag,
+                                               vport->fc_rscn_id_cnt);
+
+                                               lpfc_printf_vlog(vport,
+                                                       KERN_INFO,
                                                        LOG_DISCOVERY,
-                                                       "%d (%d):0239 Skip x%x "
+                                                       "0239 Skip x%x "
                                                        "NameServer Rsp Data: "
                                                        "x%x x%x\n",
-                                                       phba->brd_no,
-                                                       vport->vpi, Did,
-                                                       vport->fc_flag,
+                                                       Did, vport->fc_flag,
                                                        vport->fc_rscn_id_cnt);
                                        }
 
                                } else {
                                        if (!(vport->fc_flag & FC_RSCN_MODE) ||
                                        (lpfc_rscn_payload_check(vport, Did))) {
-                                               if (lpfc_ns_cmd(vport,
+                                               lpfc_debugfs_disc_trc(vport,
+                                               LPFC_DISC_TRC_CT,
+                                               "Query GID_FTrsp: "
+                                               "did:x%x flg:x%x cnt:%d",
+                                               Did, vport->fc_flag,
+                                               vport->fc_rscn_id_cnt);
+
+                                               /* This NPortID was previously
+                                                * a FCP target, * Don't even
+                                                * bother to send GFF_ID.
+                                                */
+                                               ndlp = lpfc_findnode_did(vport,
+                                                       Did);
+                                               if (ndlp &&
+                                                   NLP_CHK_NODE_ACT(ndlp)
+                                                   && (ndlp->nlp_type &
+                                                    NLP_FCP_TARGET))
+                                                       lpfc_setup_disc_node
+                                                               (vport, Did);
+                                               else if (lpfc_ns_cmd(vport,
                                                        SLI_CTNS_GFF_ID,
                                                        0, Did) == 0)
                                                        vport->num_disc_nodes++;
                                        }
                                        else {
-                                               lpfc_printf_log(phba, KERN_INFO,
+                                               lpfc_debugfs_disc_trc(vport,
+                                               LPFC_DISC_TRC_CT,
+                                               "Skip2 GID_FTrsp: "
+                                               "did:x%x flg:x%x cnt:%d",
+                                               Did, vport->fc_flag,
+                                               vport->fc_rscn_id_cnt);
+
+                                               lpfc_printf_vlog(vport,
+                                                       KERN_INFO,
                                                        LOG_DISCOVERY,
-                                                       "%d (%d):0245 Skip x%x "
+                                                       "0245 Skip x%x "
                                                        "NameServer Rsp Data: "
                                                        "x%x x%x\n",
-                                                       phba->brd_no,
-                                                       vport->vpi, Did,
-                                                       vport->fc_flag,
+                                                       Did, vport->fc_flag,
                                                        vport->fc_rscn_id_cnt);
                                        }
                                }
@@ -492,77 +540,135 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
        IOCB_t *irsp;
        struct lpfc_dmabuf *bmp;
-       struct lpfc_dmabuf *inp;
        struct lpfc_dmabuf *outp;
        struct lpfc_sli_ct_request *CTrsp;
-       int rc;
+       struct lpfc_nodelist *ndlp;
+       int rc, retry;
+
+       /* First save ndlp, before we overwrite it */
+       ndlp = cmdiocb->context_un.ndlp;
 
        /* we pass cmdiocb to state machine which needs rspiocb as well */
        cmdiocb->context_un.rsp_iocb = rspiocb;
 
-       inp = (struct lpfc_dmabuf *) cmdiocb->context1;
        outp = (struct lpfc_dmabuf *) cmdiocb->context2;
        bmp = (struct lpfc_dmabuf *) cmdiocb->context3;
+       irsp = &rspiocb->iocb;
+
+       lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
+                "GID_FT cmpl:     status:x%x/x%x rtry:%d",
+               irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_ns_retry);
 
        /* Don't bother processing response if vport is being torn down. */
        if (vport->load_flag & FC_UNLOADING)
                goto out;
 
-       irsp = &rspiocb->iocb;
-       if (irsp->ulpStatus) {
-               if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
-                       ((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) ||
-                        (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED)))
-                       goto err1;
+       if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) {
+               lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+                                "0216 Link event during NS query\n");
+               lpfc_vport_set_state(vport, FC_VPORT_FAILED);
+               goto out;
+       }
 
+       if (irsp->ulpStatus) {
                /* Check for retry */
                if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
-                       vport->fc_ns_retry++;
-                       /* CT command is being retried */
-                       rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
+                       retry = 1;
+                       if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
+                               switch (irsp->un.ulpWord[4]) {
+                               case IOERR_NO_RESOURCES:
+                                       /* We don't increment the retry
+                                        * count for this case.
+                                        */
+                                       break;
+                               case IOERR_LINK_DOWN:
+                               case IOERR_SLI_ABORTED:
+                               case IOERR_SLI_DOWN:
+                                       retry = 0;
+                                       break;
+                               default:
+                                       vport->fc_ns_retry++;
+                               }
+                       }
+                       else
+                               vport->fc_ns_retry++;
+
+                       if (retry) {
+                               /* CT command is being retried */
+                               rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
                                         vport->fc_ns_retry, 0);
-                       if (rc == 0)
-                               goto out;
+                               if (rc == 0) {
+                                       /* success */
+                                       goto out;
+                               }
+                       }
                }
-err1:
                lpfc_vport_set_state(vport, FC_VPORT_FAILED);
-               lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
-                       "%d (%d):0257 GID_FT Query error: 0x%x 0x%x\n",
-                       phba->brd_no, vport->vpi, irsp->ulpStatus,
-                       vport->fc_ns_retry);
+               lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+                                "0257 GID_FT Query error: 0x%x 0x%x\n",
+                                irsp->ulpStatus, vport->fc_ns_retry);
        } else {
                /* Good status, continue checking */
                CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
                if (CTrsp->CommandResponse.bits.CmdRsp ==
                    be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) {
-                       lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
-                                       "%d (%d):0208 NameServer Rsp "
-                                       "Data: x%x\n",
-                                       phba->brd_no, vport->vpi,
-                                       vport->fc_flag);
+                       lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+                                        "0208 NameServer Rsp Data: x%x\n",
+                                        vport->fc_flag);
                        lpfc_ns_rsp(vport, outp,
                                    (uint32_t) (irsp->un.genreq64.bdl.bdeSize));
                } else if (CTrsp->CommandResponse.bits.CmdRsp ==
                           be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
                        /* NameServer Rsp Error */
-                       lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
-                                       "%d (%d):0240 NameServer Rsp Error "
+                       if ((CTrsp->ReasonCode == SLI_CT_UNABLE_TO_PERFORM_REQ)
+                           && (CTrsp->Explanation == SLI_CT_NO_FC4_TYPES)) {
+                               lpfc_printf_vlog(vport, KERN_INFO,
+                                       LOG_DISCOVERY,
+                                       "0269 No NameServer Entries "
                                        "Data: x%x x%x x%x x%x\n",
-                                       phba->brd_no, vport->vpi,
                                        CTrsp->CommandResponse.bits.CmdRsp,
                                        (uint32_t) CTrsp->ReasonCode,
                                        (uint32_t) CTrsp->Explanation,
                                        vport->fc_flag);
+
+                               lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
+                               "GID_FT no entry  cmd:x%x rsn:x%x exp:x%x",
+                               (uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
+                               (uint32_t) CTrsp->ReasonCode,
+                               (uint32_t) CTrsp->Explanation);
+                       } else {
+                               lpfc_printf_vlog(vport, KERN_INFO,
+                                       LOG_DISCOVERY,
+                                       "0240 NameServer Rsp Error "
+                                       "Data: x%x x%x x%x x%x\n",
+                                       CTrsp->CommandResponse.bits.CmdRsp,
+                                       (uint32_t) CTrsp->ReasonCode,
+                                       (uint32_t) CTrsp->Explanation,
+                                       vport->fc_flag);
+
+                               lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
+                               "GID_FT rsp err1  cmd:x%x rsn:x%x exp:x%x",
+                               (uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
+                               (uint32_t) CTrsp->ReasonCode,
+                               (uint32_t) CTrsp->Explanation);
+                       }
+
+
                } else {
                        /* NameServer Rsp Error */
-                       lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
-                                       "%d (%d):0241 NameServer Rsp Error "
+                       lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+                                       "0241 NameServer Rsp Error "
                                        "Data: x%x x%x x%x x%x\n",
-                                       phba->brd_no, vport->vpi,
                                        CTrsp->CommandResponse.bits.CmdRsp,
                                        (uint32_t) CTrsp->ReasonCode,
                                        (uint32_t) CTrsp->Explanation,
                                        vport->fc_flag);
+
+                       lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
+                               "GID_FT rsp err2  cmd:x%x rsn:x%x exp:x%x",
+                               (uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
+                               (uint32_t) CTrsp->ReasonCode,
+                               (uint32_t) CTrsp->Explanation);
                }
        }
        /* Link up / RSCN discovery */
@@ -586,33 +692,32 @@ err1:
                lpfc_disc_start(vport);
        }
 out:
-       lpfc_free_ct_rsp(phba, outp);
-       lpfc_mbuf_free(phba, inp->virt, inp->phys);
-       lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
-       kfree(inp);
-       kfree(bmp);
-       lpfc_sli_release_iocbq(phba, cmdiocb);
+       cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
+       lpfc_ct_free_iocb(phba, cmdiocb);
        return;
 }
 
-void
+static void
 lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        struct lpfc_iocbq *rspiocb)
 {
        struct lpfc_vport *vport = cmdiocb->vport;
        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
        IOCB_t *irsp = &rspiocb->iocb;
-       struct lpfc_dmabuf *bmp = (struct lpfc_dmabuf *) cmdiocb->context3;
        struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1;
        struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2;
        struct lpfc_sli_ct_request *CTrsp;
-       int did;
+       int did, rc, retry;
        uint8_t fbits;
        struct lpfc_nodelist *ndlp;
 
        did = ((struct lpfc_sli_ct_request *) inp->virt)->un.gff.PortId;
        did = be32_to_cpu(did);
 
+       lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
+               "GFF_ID cmpl:     status:x%x/x%x did:x%x",
+               irsp->ulpStatus, irsp->un.ulpWord[4], did);
+
        if (irsp->ulpStatus == IOSTAT_SUCCESS) {
                /* Good status, continue checking */
                CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
@@ -622,31 +727,70 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                    be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) {
                        if ((fbits & FC4_FEATURE_INIT) &&
                            !(fbits & FC4_FEATURE_TARGET)) {
-                               lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
-                                               "%d (%d):0245 Skip x%x GFF "
-                                               "NameServer Rsp Data: (init) "
-                                               "x%x x%x\n", phba->brd_no,
-                                               vport->vpi, did, fbits,
-                                               vport->fc_rscn_id_cnt);
+                               lpfc_printf_vlog(vport, KERN_INFO,
+                                                LOG_DISCOVERY,
+                                                "0270 Skip x%x GFF "
+                                                "NameServer Rsp Data: (init) "
+                                                "x%x x%x\n", did, fbits,
+                                                vport->fc_rscn_id_cnt);
                                goto out;
                        }
                }
        }
+       else {
+               /* Check for retry */
+               if (cmdiocb->retry < LPFC_MAX_NS_RETRY) {
+                       retry = 1;
+                       if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
+                               switch (irsp->un.ulpWord[4]) {
+                               case IOERR_NO_RESOURCES:
+                                       /* We don't increment the retry
+                                        * count for this case.
+                                        */
+                                       break;
+                               case IOERR_LINK_DOWN:
+                               case IOERR_SLI_ABORTED:
+                               case IOERR_SLI_DOWN:
+                                       retry = 0;
+                                       break;
+                               default:
+                                       cmdiocb->retry++;
+                               }
+                       }
+                       else
+                               cmdiocb->retry++;
+
+                       if (retry) {
+                               /* CT command is being retried */
+                               rc = lpfc_ns_cmd(vport, SLI_CTNS_GFF_ID,
+                                        cmdiocb->retry, did);
+                               if (rc == 0) {
+                                       /* success */
+                                       lpfc_ct_free_iocb(phba, cmdiocb);
+                                       return;
+                               }
+                       }
+               }
+               lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+                                "0267 NameServer GFF Rsp "
+                                "x%x Error (%d %d) Data: x%x x%x\n",
+                                did, irsp->ulpStatus, irsp->un.ulpWord[4],
+                                vport->fc_flag, vport->fc_rscn_id_cnt);
+       }
+
        /* This is a target port, unregistered port, or the GFF_ID failed */
        ndlp = lpfc_setup_disc_node(vport, did);
        if (ndlp) {
-               lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
-                               "%d (%d):0242 Process x%x GFF "
-                               "NameServer Rsp Data: x%x x%x x%x\n",
-                               phba->brd_no, vport->vpi,
-                               did, ndlp->nlp_flag, vport->fc_flag,
-                               vport->fc_rscn_id_cnt);
+               lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+                                "0242 Process x%x GFF "
+                                "NameServer Rsp Data: x%x x%x x%x\n",
+                                did, ndlp->nlp_flag, vport->fc_flag,
+                                vport->fc_rscn_id_cnt);
        } else {
-               lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
-                               "%d (%d):0243 Skip x%x GFF "
-                               "NameServer Rsp Data: x%x x%x\n",
-                               phba->brd_no, vport->vpi, did,
-                               vport->fc_flag, vport->fc_rscn_id_cnt);
+               lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+                                "0243 Skip x%x GFF "
+                                "NameServer Rsp Data: x%x x%x\n", did,
+                                vport->fc_flag, vport->fc_rscn_id_cnt);
        }
 out:
        /* Link up / RSCN discovery */
@@ -670,53 +814,58 @@ out:
                }
                lpfc_disc_start(vport);
        }
-
-       lpfc_free_ct_rsp(phba, outp);
-       lpfc_mbuf_free(phba, inp->virt, inp->phys);
-       lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
-       kfree(inp);
-       kfree(bmp);
-       lpfc_sli_release_iocbq(phba, cmdiocb);
+       lpfc_ct_free_iocb(phba, cmdiocb);
        return;
 }
 
 
 static void
-lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
-                       struct lpfc_iocbq *rspiocb)
+lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+            struct lpfc_iocbq *rspiocb)
 {
        struct lpfc_vport *vport = cmdiocb->vport;
-       struct lpfc_dmabuf *bmp;
        struct lpfc_dmabuf *inp;
        struct lpfc_dmabuf *outp;
        IOCB_t *irsp;
        struct lpfc_sli_ct_request *CTrsp;
+       struct lpfc_nodelist *ndlp;
        int cmdcode, rc;
        uint8_t retry;
+       uint32_t latt;
+
+       /* First save ndlp, before we overwrite it */
+       ndlp = cmdiocb->context_un.ndlp;
 
        /* we pass cmdiocb to state machine which needs rspiocb as well */
        cmdiocb->context_un.rsp_iocb = rspiocb;
 
        inp = (struct lpfc_dmabuf *) cmdiocb->context1;
        outp = (struct lpfc_dmabuf *) cmdiocb->context2;
-       bmp = (struct lpfc_dmabuf *) cmdiocb->context3;
        irsp = &rspiocb->iocb;
 
        cmdcode = be16_to_cpu(((struct lpfc_sli_ct_request *) inp->virt)->
                                        CommandResponse.bits.CmdRsp);
        CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
 
-       /* NS request completes status <ulpStatus> CmdRsp <CmdRsp> */
-       lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
-                       "%d (%d):0209 NS request %x completes "
-                       "ulpStatus x%x / x%x "
-                       "CmdRsp x%x, Context x%x, Tag x%x\n",
-                       phba->brd_no, vport->vpi,
-                       cmdcode, irsp->ulpStatus, irsp->un.ulpWord[4],
-                       CTrsp->CommandResponse.bits.CmdRsp,
-                       cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag);
+       latt = lpfc_els_chk_latt(vport);
+
+       /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+                        "0209 CT Request completes, latt %d, "
+                        "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n",
+                        latt, irsp->ulpStatus,
+                        CTrsp->CommandResponse.bits.CmdRsp,
+                        cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag);
+
+       lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
+               "CT cmd cmpl:     status:x%x/x%x cmd:x%x",
+               irsp->ulpStatus, irsp->un.ulpWord[4], cmdcode);
 
        if (irsp->ulpStatus) {
+               lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+                                "0268 NS cmd %x Error (%d %d)\n",
+                                cmdcode, irsp->ulpStatus, irsp->un.ulpWord[4]);
+
                if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
                        ((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) ||
                         (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED)))
@@ -727,21 +876,37 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        goto out;
 
                retry++;
-               lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
-                               "%d (%d):0216 Retrying NS cmd %x\n",
-                               phba->brd_no, vport->vpi, cmdcode);
+               lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+                                "0216 Retrying NS cmd %x\n", cmdcode);
                rc = lpfc_ns_cmd(vport, cmdcode, retry, 0);
                if (rc == 0)
                        goto out;
        }
 
 out:
-       lpfc_free_ct_rsp(phba, outp);
-       lpfc_mbuf_free(phba, inp->virt, inp->phys);
-       lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
-       kfree(inp);
-       kfree(bmp);
-       lpfc_sli_release_iocbq(phba, cmdiocb);
+       cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
+       lpfc_ct_free_iocb(phba, cmdiocb);
+       return;
+}
+
+static void
+lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+                       struct lpfc_iocbq *rspiocb)
+{
+       IOCB_t *irsp = &rspiocb->iocb;
+       struct lpfc_vport *vport = cmdiocb->vport;
+
+       if (irsp->ulpStatus == IOSTAT_SUCCESS) {
+               struct lpfc_dmabuf *outp;
+               struct lpfc_sli_ct_request *CTrsp;
+
+               outp = (struct lpfc_dmabuf *) cmdiocb->context2;
+               CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
+               if (CTrsp->CommandResponse.bits.CmdRsp ==
+                   be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
+                       vport->ct_flags |= FC_CT_RFT_ID;
+       }
+       lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
        return;
 }
 
@@ -749,7 +914,20 @@ static void
 lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        struct lpfc_iocbq *rspiocb)
 {
-       lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
+       IOCB_t *irsp = &rspiocb->iocb;
+       struct lpfc_vport *vport = cmdiocb->vport;
+
+       if (irsp->ulpStatus == IOSTAT_SUCCESS) {
+               struct lpfc_dmabuf *outp;
+               struct lpfc_sli_ct_request *CTrsp;
+
+               outp = (struct lpfc_dmabuf *) cmdiocb->context2;
+               CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
+               if (CTrsp->CommandResponse.bits.CmdRsp ==
+                   be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
+                       vport->ct_flags |= FC_CT_RNN_ID;
+       }
+       lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
        return;
 }
 
@@ -757,7 +935,20 @@ static void
 lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                         struct lpfc_iocbq *rspiocb)
 {
-       lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
+       IOCB_t *irsp = &rspiocb->iocb;
+       struct lpfc_vport *vport = cmdiocb->vport;
+
+       if (irsp->ulpStatus == IOSTAT_SUCCESS) {
+               struct lpfc_dmabuf *outp;
+               struct lpfc_sli_ct_request *CTrsp;
+
+               outp = (struct lpfc_dmabuf *) cmdiocb->context2;
+               CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
+               if (CTrsp->CommandResponse.bits.CmdRsp ==
+                   be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
+                       vport->ct_flags |= FC_CT_RSPN_ID;
+       }
+       lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
        return;
 }
 
@@ -765,7 +956,32 @@ static void
 lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                         struct lpfc_iocbq *rspiocb)
 {
-       lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
+       IOCB_t *irsp = &rspiocb->iocb;
+       struct lpfc_vport *vport = cmdiocb->vport;
+
+       if (irsp->ulpStatus == IOSTAT_SUCCESS) {
+               struct lpfc_dmabuf *outp;
+               struct lpfc_sli_ct_request *CTrsp;
+
+               outp = (struct lpfc_dmabuf *) cmdiocb->context2;
+               CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
+               if (CTrsp->CommandResponse.bits.CmdRsp ==
+                   be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
+                       vport->ct_flags |= FC_CT_RSNN_NN;
+       }
+       lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
+       return;
+}
+
+static void
+lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ struct lpfc_iocbq *rspiocb)
+{
+       struct lpfc_vport *vport = cmdiocb->vport;
+
+       /* even if it fails we will act as though it succeeded. */
+       vport->ct_flags = 0;
+       lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
        return;
 }
 
@@ -776,14 +992,21 @@ lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        IOCB_t *irsp = &rspiocb->iocb;
        struct lpfc_vport *vport = cmdiocb->vport;
 
-       if (irsp->ulpStatus != IOSTAT_SUCCESS)
-           vport->fc_flag |= FC_RFF_NOT_SUPPORTED;
+       if (irsp->ulpStatus == IOSTAT_SUCCESS) {
+               struct lpfc_dmabuf *outp;
+               struct lpfc_sli_ct_request *CTrsp;
 
-       lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
+               outp = (struct lpfc_dmabuf *) cmdiocb->context2;
+               CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
+               if (CTrsp->CommandResponse.bits.CmdRsp ==
+                   be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
+                       vport->ct_flags |= FC_CT_RFF_ID;
+       }
+       lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
        return;
 }
 
-int
+static int
 lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol,
        size_t size)
 {
@@ -840,37 +1063,48 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
                      struct lpfc_iocbq *) = NULL;
        uint32_t rsp_size = 1024;
        size_t   size;
+       int rc = 0;
 
        ndlp = lpfc_findnode_did(vport, NameServer_DID);
-       if (ndlp == NULL || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)
-               return 1;
+       if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)
+           || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) {
+               rc=1;
+               goto ns_cmd_exit;
+       }
 
        /* fill in BDEs for command */
        /* Allocate buffer for command payload */
        mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
-       if (!mp)
+       if (!mp) {
+               rc=2;
                goto ns_cmd_exit;
+       }
 
        INIT_LIST_HEAD(&mp->list);
        mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys));
-       if (!mp->virt)
+       if (!mp->virt) {
+               rc=3;
                goto ns_cmd_free_mp;
+       }
 
        /* Allocate buffer for Buffer ptr list */
        bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
-       if (!bmp)
+       if (!bmp) {
+               rc=4;
                goto ns_cmd_free_mpvirt;
+       }
 
        INIT_LIST_HEAD(&bmp->list);
        bmp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(bmp->phys));
-       if (!bmp->virt)
+       if (!bmp->virt) {
+               rc=5;
                goto ns_cmd_free_bmp;
+       }
 
        /* NameServer Req */
-       lpfc_printf_log(phba, KERN_INFO ,LOG_DISCOVERY,
-                       "%d (%d):0236 NameServer Req Data: x%x x%x x%x\n",
-                       phba->brd_no, vport->vpi, cmdcode, vport->fc_flag,
-                       vport->fc_rscn_id_cnt);
+       lpfc_printf_vlog(vport, KERN_INFO ,LOG_DISCOVERY,
+                        "0236 NameServer Req Data: x%x x%x x%x\n",
+                        cmdcode, vport->fc_flag, vport->fc_rscn_id_cnt);
 
        bpl = (struct ulp_bde64 *) bmp->virt;
        memset(bpl, 0, sizeof(struct ulp_bde64));
@@ -889,6 +1123,8 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
                bpl->tus.f.bdeSize = RSPN_REQUEST_SZ;
        else if (cmdcode == SLI_CTNS_RSNN_NN)
                bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;
+       else if (cmdcode == SLI_CTNS_DA_ID)
+               bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ;
        else if (cmdcode == SLI_CTNS_RFF_ID)
                bpl->tus.f.bdeSize = RFF_REQUEST_SZ;
        else
@@ -917,31 +1153,34 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
        case SLI_CTNS_GFF_ID:
                CtReq->CommandResponse.bits.CmdRsp =
                        be16_to_cpu(SLI_CTNS_GFF_ID);
-               CtReq->un.gff.PortId = be32_to_cpu(context);
+               CtReq->un.gff.PortId = cpu_to_be32(context);
                cmpl = lpfc_cmpl_ct_cmd_gff_id;
                break;
 
        case SLI_CTNS_RFT_ID:
+               vport->ct_flags &= ~FC_CT_RFT_ID;
                CtReq->CommandResponse.bits.CmdRsp =
                    be16_to_cpu(SLI_CTNS_RFT_ID);
-               CtReq->un.rft.PortId = be32_to_cpu(vport->fc_myDID);
+               CtReq->un.rft.PortId = cpu_to_be32(vport->fc_myDID);
                CtReq->un.rft.fcpReg = 1;
                cmpl = lpfc_cmpl_ct_cmd_rft_id;
                break;
 
        case SLI_CTNS_RNN_ID:
+               vport->ct_flags &= ~FC_CT_RNN_ID;
                CtReq->CommandResponse.bits.CmdRsp =
                    be16_to_cpu(SLI_CTNS_RNN_ID);
-               CtReq->un.rnn.PortId = be32_to_cpu(vport->fc_myDID);
+               CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID);
                memcpy(CtReq->un.rnn.wwnn,  &vport->fc_nodename,
                       sizeof (struct lpfc_name));
                cmpl = lpfc_cmpl_ct_cmd_rnn_id;
                break;
 
        case SLI_CTNS_RSPN_ID:
+               vport->ct_flags &= ~FC_CT_RSPN_ID;
                CtReq->CommandResponse.bits.CmdRsp =
                    be16_to_cpu(SLI_CTNS_RSPN_ID);
-               CtReq->un.rspn.PortId = be32_to_cpu(vport->fc_myDID);
+               CtReq->un.rspn.PortId = cpu_to_be32(vport->fc_myDID);
                size = sizeof(CtReq->un.rspn.symbname);
                CtReq->un.rspn.len =
                        lpfc_vport_symbolic_port_name(vport,
@@ -949,6 +1188,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
                cmpl = lpfc_cmpl_ct_cmd_rspn_id;
                break;
        case SLI_CTNS_RSNN_NN:
+               vport->ct_flags &= ~FC_CT_RSNN_NN;
                CtReq->CommandResponse.bits.CmdRsp =
                    be16_to_cpu(SLI_CTNS_RSNN_NN);
                memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename,
@@ -959,20 +1199,39 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
                        CtReq->un.rsnn.symbname, size);
                cmpl = lpfc_cmpl_ct_cmd_rsnn_nn;
                break;
+       case SLI_CTNS_DA_ID:
+               /* Implement DA_ID Nameserver request */
+               CtReq->CommandResponse.bits.CmdRsp =
+                       be16_to_cpu(SLI_CTNS_DA_ID);
+               CtReq->un.da_id.port_id = cpu_to_be32(vport->fc_myDID);
+               cmpl = lpfc_cmpl_ct_cmd_da_id;
+               break;
        case SLI_CTNS_RFF_ID:
-               vport->fc_flag &= ~FC_RFF_NOT_SUPPORTED;
+               vport->ct_flags &= ~FC_CT_RFF_ID;
                CtReq->CommandResponse.bits.CmdRsp =
                    be16_to_cpu(SLI_CTNS_RFF_ID);
-               CtReq->un.rff.PortId = be32_to_cpu(vport->fc_myDID);;
+               CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);;
                CtReq->un.rff.fbits = FC4_FEATURE_INIT;
                CtReq->un.rff.type_code = FC_FCP_DATA;
                cmpl = lpfc_cmpl_ct_cmd_rff_id;
                break;
        }
-
-       if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry))
+       /* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count
+        * to hold ndlp reference for the corresponding callback function.
+        */
+       if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) {
                /* On success, The cmpl function will free the buffers */
+               lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
+                       "Issue CT cmd:    cmd:x%x did:x%x",
+                       cmdcode, ndlp->nlp_DID, 0);
                return 0;
+       }
+       rc=6;
+
+       /* Decrement ndlp reference count to release ndlp reference held
+        * for the failed command's callback function.
+        */
+       lpfc_nlp_put(ndlp);
 
        lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
 ns_cmd_free_bmp:
@@ -982,6 +1241,9 @@ ns_cmd_free_mpvirt:
 ns_cmd_free_mp:
        kfree(mp);
 ns_cmd_exit:
+       lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+                        "0266 Issue NameServer Req x%x err %d Data: x%x x%x\n",
+                        cmdcode, rc, vport->fc_flag, vport->fc_rscn_id_cnt);
        return 1;
 }
 
@@ -989,7 +1251,6 @@ static void
 lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                      struct lpfc_iocbq * rspiocb)
 {
-       struct lpfc_dmabuf *bmp = cmdiocb->context3;
        struct lpfc_dmabuf *inp = cmdiocb->context1;
        struct lpfc_dmabuf *outp = cmdiocb->context2;
        struct lpfc_sli_ct_request *CTrsp = outp->virt;
@@ -998,14 +1259,34 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp;
        uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp;
        struct lpfc_vport *vport = cmdiocb->vport;
+       IOCB_t *irsp = &rspiocb->iocb;
+       uint32_t latt;
+
+       latt = lpfc_els_chk_latt(vport);
+
+       lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
+               "FDMI cmpl:       status:x%x/x%x latt:%d",
+               irsp->ulpStatus, irsp->un.ulpWord[4], latt);
+
+       if (latt || irsp->ulpStatus) {
+               lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+                                "0229 FDMI cmd %04x failed, latt = %d "
+                                "ulpStatus: x%x, rid x%x\n",
+                                be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus,
+                                irsp->un.ulpWord[4]);
+               lpfc_ct_free_iocb(phba, cmdiocb);
+               return;
+       }
 
        ndlp = lpfc_findnode_did(vport, FDMI_DID);
+       if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
+               goto fail_out;
+
        if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
                /* FDMI rsp failed */
-               lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
-                               "%d (%d):0220 FDMI rsp failed Data: x%x\n",
-                               phba->brd_no, vport->vpi,
-                               be16_to_cpu(fdmi_cmd));
+               lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+                                "0220 FDMI rsp failed Data: x%x\n",
+                                be16_to_cpu(fdmi_cmd));
        }
 
        switch (be16_to_cpu(fdmi_cmd)) {
@@ -1025,12 +1306,8 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                break;
        }
 
-       lpfc_free_ct_rsp(phba, outp);
-       lpfc_mbuf_free(phba, inp->virt, inp->phys);
-       lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
-       kfree(inp);
-       kfree(bmp);
-       lpfc_sli_release_iocbq(phba, cmdiocb);
+fail_out:
+       lpfc_ct_free_iocb(phba, cmdiocb);
        return;
 }
 
@@ -1074,11 +1351,9 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
        INIT_LIST_HEAD(&bmp->list);
 
        /* FDMI request */
-       lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
-                       "%d (%d):0218 FDMI Request Data: x%x x%x x%x\n",
-                       phba->brd_no, vport->vpi, vport->fc_flag,
-                       vport->port_state, cmdcode);
-
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+                        "0218 FDMI Request Data: x%x x%x x%x\n",
+                        vport->fc_flag, vport->port_state, cmdcode);
        CtReq = (struct lpfc_sli_ct_request *) mp->virt;
 
        memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request));
@@ -1338,7 +1613,7 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
                        pab->ab.EntryCnt++;
                        size += FOURBYTES + len;
 
-                       if (phba->cfg_fdmi_on == 2) {
+                       if (vport->cfg_fdmi_on == 2) {
                                /* #6 Port attribute entry */
                                ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab +
                                                          size);
@@ -1389,9 +1664,17 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
 
        cmpl = lpfc_cmpl_ct_cmd_fdmi;
 
+       /* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count
+        * to hold ndlp reference for the corresponding callback function.
+        */
        if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP, 0))
                return 0;
 
+       /* Decrement ndlp reference count to release ndlp reference held
+        * for the failed command's callback function.
+        */
+       lpfc_nlp_put(ndlp);
+
        lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
 fdmi_cmd_free_bmp:
        kfree(bmp);
@@ -1401,9 +1684,9 @@ fdmi_cmd_free_mp:
        kfree(mp);
 fdmi_cmd_exit:
        /* Issue FDMI request failed */
-       lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
-                       "%d (%d):0244 Issue FDMI request failed Data: x%x\n",
-                       phba->brd_no, vport->vpi, cmdcode);
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+                        "0244 Issue FDMI request failed Data: x%x\n",
+                        cmdcode);
        return 1;
 }
 
@@ -1434,7 +1717,7 @@ lpfc_fdmi_timeout_handler(struct lpfc_vport *vport)
        struct lpfc_nodelist *ndlp;
 
        ndlp = lpfc_findnode_did(vport, FDMI_DID);
-       if (ndlp) {
+       if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
                if (init_utsname()->nodename[0] != '\0')
                        lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA);
                else