[SCSI] lpfc: NPIV: split ports

The driver is reorganized to separate the handling of the adapter from
the handling of the FC port. Adapter handling includes submissions of
command requests, receiving responses, and managing adapter resources.
The FC port includes the discovery engine, login handling, and the
mapping of a Scsi_Host on the "port".  Although not a large functional
change, as it touches core structures and functions, resulting in a
large text delta.

Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 638b3cd..0af33be 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -41,23 +41,20 @@
 static int lpfc_max_els_tries = 3;
 
 static int
-lpfc_els_chk_latt(struct lpfc_hba * phba)
+lpfc_els_chk_latt(struct lpfc_vport *vport)
 {
-	struct lpfc_sli *psli;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
 	LPFC_MBOXQ_t *mbox;
 	uint32_t ha_copy;
 	int rc;
 
-	psli = &phba->sli;
-
-	if ((phba->hba_state >= LPFC_HBA_READY) ||
-	    (phba->hba_state == LPFC_LINK_DOWN))
+	if (vport->port_state >= LPFC_VPORT_READY ||
+	    phba->link_state == LPFC_LINK_DOWN)
 		return 0;
 
 	/* Read the HBA Host Attention Register */
-	spin_lock_irq(phba->host->host_lock);
 	ha_copy = readl(phba->HAregaddr);
-	spin_unlock_irq(phba->host->host_lock);
 
 	if (!(ha_copy & HA_LATT))
 		return 0;
@@ -66,7 +63,7 @@
 	lpfc_printf_log(phba, KERN_WARNING, LOG_DISCOVERY,
 			"%d:0237 Pending Link Event during "
 			"Discovery: State x%x\n",
-			phba->brd_no, phba->hba_state);
+			phba->brd_no, phba->pport->port_state);
 
 	/* CLEAR_LA should re-enable link attention events and
 	 * we should then imediately take a LATT event. The
@@ -74,20 +71,23 @@
 	 * will cleanup any left over in-progress discovery
 	 * events.
 	 */
-	spin_lock_irq(phba->host->host_lock);
-	phba->fc_flag |= FC_ABORT_DISCOVERY;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	vport->fc_flag |= FC_ABORT_DISCOVERY;
+	spin_unlock_irq(shost->host_lock);
 
-	if (phba->hba_state != LPFC_CLEAR_LA) {
+	if (phba->link_state != LPFC_CLEAR_LA) {
 		if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) {
-			phba->hba_state = LPFC_CLEAR_LA;
+			phba->link_state = LPFC_CLEAR_LA;
 			lpfc_clear_la(phba, mbox);
 			mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
-			rc = lpfc_sli_issue_mbox (phba, mbox,
-						  (MBX_NOWAIT | MBX_STOP_IOCB));
+			mbox->vport = vport;
+			printk(KERN_ERR "%s (%d): do clear_la\n",
+			       __FUNCTION__, __LINE__);
+			rc = lpfc_sli_issue_mbox(phba, mbox,
+						 (MBX_NOWAIT | MBX_STOP_IOCB));
 			if (rc == MBX_NOT_FINISHED) {
 				mempool_free(mbox, phba->mbox_mem_pool);
-				phba->hba_state = LPFC_HBA_ERROR;
+				phba->link_state = LPFC_HBA_ERROR;
 			}
 		}
 	}
@@ -97,25 +97,23 @@
 }
 
 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_vport *vport, uint8_t expectRsp,
+		   uint16_t cmdSize, uint8_t retry,
+		   struct lpfc_nodelist *ndlp, uint32_t did,
+		   uint32_t elscmd)
 {
-	struct lpfc_sli_ring *pring;
+	struct lpfc_hba  *phba = vport->phba;
 	struct lpfc_iocbq *elsiocb;
 	struct lpfc_dmabuf *pcmd, *prsp, *pbuflist;
 	struct ulp_bde64 *bpl;
 	IOCB_t *icmd;
 
-	pring = &phba->sli.ring[LPFC_ELS_RING];
 
-	if (phba->hba_state < LPFC_LINK_UP)
-		return  NULL;
+	if (!lpfc_is_link_up(phba))
+		return NULL;
 
 	/* Allocate buffer for  command iocb */
-	spin_lock_irq(phba->host->host_lock);
 	elsiocb = lpfc_sli_get_iocbq(phba);
-	spin_unlock_irq(phba->host->host_lock);
 
 	if (elsiocb == NULL)
 		return NULL;
@@ -128,9 +126,7 @@
 					   MEM_PRI, &(pcmd->phys))) == 0)) {
 		kfree(pcmd);
 
-		spin_lock_irq(phba->host->host_lock);
 		lpfc_sli_release_iocbq(phba, elsiocb);
-		spin_unlock_irq(phba->host->host_lock);
 		return NULL;
 	}
 
@@ -146,9 +142,7 @@
 			kfree(prsp);
 			lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
 			kfree(pcmd);
-			spin_lock_irq(phba->host->host_lock);
 			lpfc_sli_release_iocbq(phba, elsiocb);
-			spin_unlock_irq(phba->host->host_lock);
 			return NULL;
 		}
 		INIT_LIST_HEAD(&prsp->list);
@@ -162,9 +156,7 @@
 	    pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
 					     &pbuflist->phys);
 	if (pbuflist == 0 || pbuflist->virt == 0) {
-		spin_lock_irq(phba->host->host_lock);
 		lpfc_sli_release_iocbq(phba, elsiocb);
-		spin_unlock_irq(phba->host->host_lock);
 		lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
 		lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
 		kfree(pcmd);
@@ -178,9 +170,9 @@
 	icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
 	icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
 	icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL;
+	icmd->un.elsreq64.remoteID = did;	/* DID */
 	if (expectRsp) {
 		icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64));
-		icmd->un.elsreq64.remoteID = did;	/* DID */
 		icmd->ulpCommand = CMD_ELS_REQUEST64_CR;
 		icmd->ulpTimeout = phba->fc_ratov * 2;
 	} else {
@@ -213,6 +205,7 @@
 	elsiocb->context2 = pcmd;
 	elsiocb->context3 = pbuflist;
 	elsiocb->retry = retry;
+	elsiocb->vport = vport;
 	elsiocb->drvrTimeout = (phba->fc_ratov << 1) + LPFC_DRVR_TIMEOUT;
 
 	if (prsp) {
@@ -223,9 +216,9 @@
 		/* Xmit ELS command <elsCmd> to remote NPORT <did> */
 		lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
 				"%d:0116 Xmit ELS command x%x to remote "
-				"NPORT x%x I/O tag: x%x, HBA state: x%x\n",
-				phba->brd_no, elscmd,
-				did, elsiocb->iotag, phba->hba_state);
+				"NPORT x%x I/O tag: x%x, port state: x%x\n",
+				phba->brd_no, elscmd, did,
+				elsiocb->iotag, vport->port_state);
 	} else {
 		/* Xmit ELS response <elsCmd> to remote NPORT <did> */
 		lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
@@ -240,16 +233,18 @@
 
 
 static int
-lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
-		struct serv_parm *sp, IOCB_t *irsp)
+lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			   struct serv_parm *sp, IOCB_t *irsp)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
 	LPFC_MBOXQ_t *mbox;
 	struct lpfc_dmabuf *mp;
 	int rc;
 
-	spin_lock_irq(phba->host->host_lock);
-	phba->fc_flag |= FC_FABRIC;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	vport->fc_flag |= FC_FABRIC;
+	spin_unlock_irq(shost->host_lock);
 
 	phba->fc_edtov = be32_to_cpu(sp->cmn.e_d_tov);
 	if (sp->cmn.edtovResolution)	/* E_D_TOV ticks are in nanoseconds */
@@ -258,18 +253,18 @@
 	phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000;
 
 	if (phba->fc_topology == TOPOLOGY_LOOP) {
-		spin_lock_irq(phba->host->host_lock);
-		phba->fc_flag |= FC_PUBLIC_LOOP;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
+		vport->fc_flag |= FC_PUBLIC_LOOP;
+		spin_unlock_irq(shost->host_lock);
 	} else {
 		/*
 		 * If we are a N-port connected to a Fabric, fixup sparam's so
 		 * logins to devices on remote loops work.
 		 */
-		phba->fc_sparam.cmn.altBbCredit = 1;
+		vport->fc_sparam.cmn.altBbCredit = 1;
 	}
 
-	phba->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
+	vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
 	memcpy(&ndlp->nlp_portname, &sp->portName, sizeof(struct lpfc_name));
 	memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof (struct lpfc_name));
 	ndlp->nlp_class_sup = 0;
@@ -285,11 +280,13 @@
 				sp->cmn.bbRcvSizeLsb;
 	memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
 
+	ndlp->nlp_sid = irsp->un.ulpWord[4] & Mask_DID;
+
 	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!mbox)
 		goto fail;
 
-	phba->hba_state = LPFC_FABRIC_CFG_LINK;
+	vport->port_state = LPFC_FABRIC_CFG_LINK;
 	lpfc_config_link(phba, mbox);
 	mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
 
@@ -300,11 +297,12 @@
 	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!mbox)
 		goto fail;
-
-	if (lpfc_reg_login(phba, Fabric_DID, (uint8_t *) sp, mbox, 0))
+	rc = lpfc_reg_login(phba, Fabric_DID, (uint8_t *) sp, mbox, 0);
+	if (rc)
 		goto fail_free_mbox;
 
 	mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login;
+	mbox->vport = vport;
 	mbox->context2 = lpfc_nlp_get(ndlp);
 
 	rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB);
@@ -328,25 +326,27 @@
  * We FLOGIed into an NPort, initiate pt2pt protocol
  */
 static int
-lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
-		struct serv_parm *sp)
+lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			  struct serv_parm *sp)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
 	LPFC_MBOXQ_t *mbox;
 	int rc;
 
-	spin_lock_irq(phba->host->host_lock);
-	phba->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
-	spin_unlock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
+	spin_unlock_irq(shost->host_lock);
 
 	phba->fc_edtov = FF_DEF_EDTOV;
 	phba->fc_ratov = FF_DEF_RATOV;
-	rc = memcmp(&phba->fc_portname, &sp->portName,
+	rc = memcmp(&vport->fc_portname, &sp->portName,
 			sizeof(struct lpfc_name));
 	if (rc >= 0) {
 		/* This side will initiate the PLOGI */
-		spin_lock_irq(phba->host->host_lock);
-		phba->fc_flag |= FC_PT2PT_PLOGI;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
+		vport->fc_flag |= FC_PT2PT_PLOGI;
+		spin_unlock_irq(shost->host_lock);
 
 		/*
 		 * N_Port ID cannot be 0, set our to LocalID the other
@@ -355,7 +355,7 @@
 
 		/* not equal */
 		if (rc)
-			phba->fc_myDID = PT2PT_LocalID;
+			vport->fc_myDID = PT2PT_LocalID;
 
 		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 		if (!mbox)
@@ -372,7 +372,7 @@
 		}
 		lpfc_nlp_put(ndlp);
 
-		ndlp = lpfc_findnode_did(phba, PT2PT_RemoteID);
+		ndlp = lpfc_findnode_did(vport, PT2PT_RemoteID);
 		if (!ndlp) {
 			/*
 			 * Cannot find existing Fabric ndlp, so allocate a
@@ -382,26 +382,28 @@
 			if (!ndlp)
 				goto fail;
 
-			lpfc_nlp_init(phba, ndlp, PT2PT_RemoteID);
+			lpfc_nlp_init(vport, ndlp, PT2PT_RemoteID);
 		}
 
 		memcpy(&ndlp->nlp_portname, &sp->portName,
-				sizeof(struct lpfc_name));
+		       sizeof(struct lpfc_name));
 		memcpy(&ndlp->nlp_nodename, &sp->nodeName,
-				sizeof(struct lpfc_name));
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
+		       sizeof(struct lpfc_name));
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag |= NLP_NPR_2B_DISC;
+		spin_unlock_irq(shost->host_lock);
 	} else {
 		/* This side will wait for the PLOGI */
 		lpfc_nlp_put(ndlp);
 	}
 
-	spin_lock_irq(phba->host->host_lock);
-	phba->fc_flag |= FC_PT2PT;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	vport->fc_flag |= FC_PT2PT;
+	spin_unlock_irq(shost->host_lock);
 
 	/* Start discovery - this should just do CLEAR_LA */
-	lpfc_disc_start(phba);
+	lpfc_disc_start(vport);
 	return 0;
  fail:
 	return -ENXIO;
@@ -411,6 +413,8 @@
 lpfc_cmpl_els_flogi(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_nodelist *ndlp = cmdiocb->context1;
 	struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
@@ -418,21 +422,20 @@
 	int rc;
 
 	/* Check to see if link went down during discovery */
-	if (lpfc_els_chk_latt(phba)) {
+	if (lpfc_els_chk_latt(vport)) {
 		lpfc_nlp_put(ndlp);
 		goto out;
 	}
 
 	if (irsp->ulpStatus) {
 		/* Check for retry */
-		if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
-			/* ELS command is being retried */
+		if (lpfc_els_retry(phba, cmdiocb, rspiocb))
 			goto out;
-		}
+
 		/* FLOGI failed, so there is no fabric */
-		spin_lock_irq(phba->host->host_lock);
-		phba->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
-		spin_unlock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
+		vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
+		spin_unlock_irq(shost->host_lock);
 
 		/* If private loop, then allow max outstanding els to be
 		 * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no
@@ -469,15 +472,15 @@
 			irsp->un.ulpWord[4], sp->cmn.e_d_tov,
 			sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution);
 
-	if (phba->hba_state == LPFC_FLOGI) {
+	if (vport->port_state == LPFC_FLOGI) {
 		/*
 		 * If Common Service Parameters indicate Nport
 		 * we are point to point, if Fport we are Fabric.
 		 */
 		if (sp->cmn.fPort)
-			rc = lpfc_cmpl_els_flogi_fabric(phba, ndlp, sp, irsp);
+			rc = lpfc_cmpl_els_flogi_fabric(vport, ndlp, sp, irsp);
 		else
-			rc = lpfc_cmpl_els_flogi_nport(phba, ndlp, sp);
+			rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
 
 		if (!rc)
 			goto out;
@@ -490,10 +493,10 @@
 	    (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED &&
 	     irsp->un.ulpWord[4] != IOERR_SLI_DOWN)) {
 		/* FLOGI failed, so just use loop map to make discovery list */
-		lpfc_disc_list_loopmap(phba);
+		lpfc_disc_list_loopmap(vport);
 
 		/* Start discovery */
-		lpfc_disc_start(phba);
+		lpfc_disc_start(vport);
 	}
 
 out:
@@ -501,9 +504,10 @@
 }
 
 static int
-lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
+lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 		     uint8_t retry)
 {
+	struct lpfc_hba  *phba = vport->phba;
 	struct serv_parm *sp;
 	IOCB_t *icmd;
 	struct lpfc_iocbq *elsiocb;
@@ -516,8 +520,8 @@
 	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);
+	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_FLOGI);
 	if (!elsiocb)
 		return 1;
 
@@ -527,7 +531,7 @@
 	/* For FLOGI request, remainder of payload is service parameters */
 	*((uint32_t *) (pcmd)) = ELS_CMD_FLOGI;
 	pcmd += sizeof (uint32_t);
-	memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm));
+	memcpy(pcmd, &vport->fc_sparam, sizeof (struct serv_parm));
 	sp = (struct serv_parm *) pcmd;
 
 	/* Setup CSPs accordingly for Fabric */
@@ -543,14 +547,12 @@
 
 	tmo = phba->fc_ratov;
 	phba->fc_ratov = LPFC_DISC_FLOGI_TMO;
-	lpfc_set_disctmo(phba);
+	lpfc_set_disctmo(vport);
 	phba->fc_ratov = tmo;
 
 	phba->fc_stat.elsXmitFLOGI++;
 	elsiocb->iocb_cmpl = lpfc_cmpl_els_flogi;
-	spin_lock_irq(phba->host->host_lock);
 	rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
-	spin_unlock_irq(phba->host->host_lock);
 	if (rc == IOCB_ERROR) {
 		lpfc_els_free_iocb(phba, elsiocb);
 		return 1;
@@ -559,7 +561,7 @@
 }
 
 int
-lpfc_els_abort_flogi(struct lpfc_hba * phba)
+lpfc_els_abort_flogi(struct lpfc_hba *phba)
 {
 	struct lpfc_sli_ring *pring;
 	struct lpfc_iocbq *iocb, *next_iocb;
@@ -577,62 +579,65 @@
 	 * Check the txcmplq for an iocb that matches the nport the driver is
 	 * searching for.
 	 */
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
 		icmd = &iocb->iocb;
-		if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) {
+		if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR &&
+		    icmd->un.elsreq64.bdl.ulpIoTag32) {
 			ndlp = (struct lpfc_nodelist *)(iocb->context1);
 			if (ndlp && (ndlp->nlp_DID == Fabric_DID))
 				lpfc_sli_issue_abort_iotag(phba, pring, iocb);
 		}
 	}
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	return 0;
 }
 
 int
-lpfc_initial_flogi(struct lpfc_hba *phba)
+lpfc_initial_flogi(struct lpfc_vport *vport)
 {
+	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_nodelist *ndlp;
 
 	/* First look for the Fabric ndlp */
-	ndlp = lpfc_findnode_did(phba, Fabric_DID);
+	ndlp = lpfc_findnode_did(vport, Fabric_DID);
 	if (!ndlp) {
 		/* Cannot find existing Fabric ndlp, so allocate a new one */
 		ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
 		if (!ndlp)
 			return 0;
-		lpfc_nlp_init(phba, ndlp, Fabric_DID);
+		lpfc_nlp_init(vport, ndlp, Fabric_DID);
 	} else {
-		lpfc_dequeue_node(phba, ndlp);
+		lpfc_dequeue_node(vport, ndlp);
 	}
-	if (lpfc_issue_els_flogi(phba, ndlp, 0)) {
+	if (lpfc_issue_els_flogi(vport, ndlp, 0)) {
 		lpfc_nlp_put(ndlp);
 	}
 	return 1;
 }
 
 static void
-lpfc_more_plogi(struct lpfc_hba * phba)
+lpfc_more_plogi(struct lpfc_vport *vport)
 {
 	int sentplogi;
+	struct lpfc_hba *phba = vport->phba;
 
-	if (phba->num_disc_nodes)
-		phba->num_disc_nodes--;
+	if (vport->num_disc_nodes)
+		vport->num_disc_nodes--;
 
 	/* Continue discovery with <num_disc_nodes> PLOGIs to go */
 	lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
 			"%d:0232 Continue discovery with %d PLOGIs to go "
 			"Data: x%x x%x x%x\n",
-			phba->brd_no, phba->num_disc_nodes, phba->fc_plogi_cnt,
-			phba->fc_flag, phba->hba_state);
+			phba->brd_no, vport->num_disc_nodes,
+			vport->fc_plogi_cnt, vport->fc_flag, vport->port_state);
 
 	/* Check to see if there are more PLOGIs to be sent */
-	if (phba->fc_flag & FC_NLP_MORE) {
-		/* go thru NPR list and issue any remaining ELS PLOGIs */
-		sentplogi = lpfc_els_disc_plogi(phba);
-	}
+	if (vport->fc_flag & FC_NLP_MORE)
+		/* go thru NPR nodes and issue any remaining ELS PLOGIs */
+		sentplogi = lpfc_els_disc_plogi(vport);
+
 	return;
 }
 
@@ -640,6 +645,7 @@
 lpfc_plogi_confirm_nport(struct lpfc_hba *phba, struct lpfc_dmabuf *prsp,
 			 struct lpfc_nodelist *ndlp)
 {
+	struct lpfc_vport    *vport = ndlp->vport;
 	struct lpfc_nodelist *new_ndlp;
 	uint32_t *lp;
 	struct serv_parm *sp;
@@ -659,43 +665,45 @@
 	/* Now we 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, &sp->portName);
+	new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName);
 
 	if (new_ndlp == ndlp)
 		return ndlp;
 
 	if (!new_ndlp) {
-		rc =
-		   memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name));
+		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_nlp_init(vport, new_ndlp, ndlp->nlp_DID);
 	}
 
-	lpfc_unreg_rpi(phba, new_ndlp);
+	lpfc_unreg_rpi(vport, new_ndlp);
 	new_ndlp->nlp_DID = ndlp->nlp_DID;
 	new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
-	lpfc_nlp_set_state(phba, new_ndlp, ndlp->nlp_state);
+	lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state);
 
-	/* Move this back to NPR list */
+	/* Move this back to NPR state */
 	if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0)
-		lpfc_drop_node(phba, ndlp);
+		lpfc_drop_node(vport, ndlp);
 	else {
-		lpfc_unreg_rpi(phba, ndlp);
+		lpfc_unreg_rpi(vport, ndlp);
 		ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
 	}
 	return new_ndlp;
 }
 
 static void
-lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-		    struct lpfc_iocbq * rspiocb)
+lpfc_cmpl_els_plogi(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;
 	struct lpfc_nodelist *ndlp;
 	struct lpfc_dmabuf *prsp;
@@ -705,17 +713,17 @@
 	cmdiocb->context_un.rsp_iocb = rspiocb;
 
 	irsp = &rspiocb->iocb;
-	ndlp = lpfc_findnode_did(phba, irsp->un.elsreq64.remoteID);
+	ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID);
 	if (!ndlp)
 		goto out;
 
 	/* Since ndlp can be freed in the disc state machine, note if this node
 	 * is being used during discovery.
 	 */
+	spin_lock_irq(shost->host_lock);
 	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);
+	spin_unlock_irq(shost->host_lock);
 	rc   = 0;
 
 	/* PLOGI completes to NPort <nlp_DID> */
@@ -724,13 +732,13 @@
 			"Data: x%x 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);
+			vport->num_disc_nodes);
 
 	/* Check to see if link went down during discovery */
-	if (lpfc_els_chk_latt(phba)) {
-		spin_lock_irq(phba->host->host_lock);
+	if (lpfc_els_chk_latt(vport)) {
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag |= NLP_NPR_2B_DISC;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 		goto out;
 	}
 
@@ -743,9 +751,9 @@
 		if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
 			/* ELS command is being retried */
 			if (disc) {
-				spin_lock_irq(phba->host->host_lock);
+				spin_lock_irq(shost->host_lock);
 				ndlp->nlp_flag |= NLP_NPR_2B_DISC;
-				spin_unlock_irq(phba->host->host_lock);
+				spin_unlock_irq(shost->host_lock);
 			}
 			goto out;
 		}
@@ -758,7 +766,7 @@
 		   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
 			rc = NLP_STE_FREED_NODE;
 		} else {
-			rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb,
+			rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb,
 					NLP_EVT_CMPL_PLOGI);
 		}
 	} else {
@@ -767,32 +775,32 @@
 			cmdiocb->context2)->list.next,
 			struct lpfc_dmabuf, list);
 		ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp);
-		rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb,
+		rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb,
 					NLP_EVT_CMPL_PLOGI);
 	}
 
-	if (disc && phba->num_disc_nodes) {
+	if (disc && vport->num_disc_nodes) {
 		/* Check to see if there are more PLOGIs to be sent */
-		lpfc_more_plogi(phba);
+		lpfc_more_plogi(vport);
 
-		if (phba->num_disc_nodes == 0) {
-			spin_lock_irq(phba->host->host_lock);
-			phba->fc_flag &= ~FC_NDISC_ACTIVE;
-			spin_unlock_irq(phba->host->host_lock);
+		if (vport->num_disc_nodes == 0) {
+			spin_lock_irq(shost->host_lock);
+			vport->fc_flag &= ~FC_NDISC_ACTIVE;
+			spin_unlock_irq(shost->host_lock);
 
-			lpfc_can_disctmo(phba);
-			if (phba->fc_flag & FC_RSCN_MODE) {
+			lpfc_can_disctmo(vport);
+			if (vport->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);
+				if ((vport->fc_rscn_id_cnt == 0) &&
+				    (!(vport->fc_flag & FC_RSCN_DISCOVERY))) {
+					spin_lock_irq(shost->host_lock);
+					vport->fc_flag &= ~FC_RSCN_MODE;
+					spin_unlock_irq(shost->host_lock);
 				} else {
-					lpfc_els_handle_rscn(phba);
+					lpfc_els_handle_rscn(vport);
 				}
 			}
 		}
@@ -804,8 +812,9 @@
 }
 
 int
-lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry)
+lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
 {
+	struct lpfc_hba  *phba = vport->phba;
 	struct serv_parm *sp;
 	IOCB_t *icmd;
 	struct lpfc_iocbq *elsiocb;
@@ -818,8 +827,8 @@
 	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);
+	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, NULL, did,
+				     ELS_CMD_PLOGI);
 	if (!elsiocb)
 		return 1;
 
@@ -829,7 +838,7 @@
 	/* For PLOGI request, remainder of payload is service parameters */
 	*((uint32_t *) (pcmd)) = ELS_CMD_PLOGI;
 	pcmd += sizeof (uint32_t);
-	memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm));
+	memcpy(pcmd, &vport->fc_sparam, sizeof (struct serv_parm));
 	sp = (struct serv_parm *) pcmd;
 
 	if (sp->cmn.fcphLow < FC_PH_4_3)
@@ -840,20 +849,19 @@
 
 	phba->fc_stat.elsXmitPLOGI++;
 	elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi;
-	spin_lock_irq(phba->host->host_lock);
 	if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
-		spin_unlock_irq(phba->host->host_lock);
 		lpfc_els_free_iocb(phba, elsiocb);
 		return 1;
 	}
-	spin_unlock_irq(phba->host->host_lock);
 	return 0;
 }
 
 static void
-lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-		   struct lpfc_iocbq * rspiocb)
+lpfc_cmpl_els_prli(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;
 	struct lpfc_sli *psli;
 	struct lpfc_nodelist *ndlp;
@@ -864,9 +872,9 @@
 
 	irsp = &(rspiocb->iocb);
 	ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag &= ~NLP_PRLI_SND;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 
 	/* PRLI completes to NPort <nlp_DID> */
 	lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
@@ -874,11 +882,11 @@
 			"Data: x%x 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);
+			vport->num_disc_nodes);
 
-	phba->fc_prli_sent--;
+	vport->fc_prli_sent--;
 	/* Check to see if link went down during discovery */
-	if (lpfc_els_chk_latt(phba))
+	if (lpfc_els_chk_latt(vport))
 		goto out;
 
 	if (irsp->ulpStatus) {
@@ -895,12 +903,13 @@
 		   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
 			goto out;
 		} else {
-			lpfc_disc_state_machine(phba, ndlp, cmdiocb,
+			lpfc_disc_state_machine(vport, ndlp, cmdiocb,
 					NLP_EVT_CMPL_PRLI);
 		}
 	} else {
 		/* Good status, call state machine */
-		lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_PRLI);
+		lpfc_disc_state_machine(vport, ndlp, cmdiocb,
+							NLP_EVT_CMPL_PRLI);
 	}
 
 out:
@@ -909,9 +918,11 @@
 }
 
 int
-lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
+lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 		    uint8_t retry)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba *phba = vport->phba;
 	PRLI *npr;
 	IOCB_t *icmd;
 	struct lpfc_iocbq *elsiocb;
@@ -924,8 +935,8 @@
 	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);
+	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_PRLI);
 	if (!elsiocb)
 		return 1;
 
@@ -957,79 +968,80 @@
 
 	phba->fc_stat.elsXmitPRLI++;
 	elsiocb->iocb_cmpl = lpfc_cmpl_els_prli;
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag |= NLP_PRLI_SND;
+	spin_unlock_irq(shost->host_lock);
 	if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag &= ~NLP_PRLI_SND;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 		lpfc_els_free_iocb(phba, elsiocb);
 		return 1;
 	}
-	spin_unlock_irq(phba->host->host_lock);
-	phba->fc_prli_sent++;
+	vport->fc_prli_sent++;
 	return 0;
 }
 
 static void
-lpfc_more_adisc(struct lpfc_hba * phba)
+lpfc_more_adisc(struct lpfc_vport *vport)
 {
 	int sentadisc;
+	struct lpfc_hba *phba = vport->phba;
 
-	if (phba->num_disc_nodes)
-		phba->num_disc_nodes--;
+	if (vport->num_disc_nodes)
+		vport->num_disc_nodes--;
 
 	/* Continue discovery with <num_disc_nodes> ADISCs to go */
 	lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
 			"%d:0210 Continue discovery with %d ADISCs to go "
 			"Data: x%x x%x x%x\n",
-			phba->brd_no, phba->num_disc_nodes, phba->fc_adisc_cnt,
-			phba->fc_flag, phba->hba_state);
+			phba->brd_no, vport->num_disc_nodes,
+			vport->fc_adisc_cnt, vport->fc_flag, vport->port_state);
 
 	/* Check to see if there are more ADISCs to be sent */
-	if (phba->fc_flag & FC_NLP_MORE) {
-		lpfc_set_disctmo(phba);
-
-		/* go thru NPR list and issue any remaining ELS ADISCs */
-		sentadisc = lpfc_els_disc_adisc(phba);
+	if (vport->fc_flag & FC_NLP_MORE) {
+		lpfc_set_disctmo(vport);
+		/* go thru NPR nodes and issue any remaining ELS ADISCs */
+		sentadisc = lpfc_els_disc_adisc(vport);
 	}
 	return;
 }
 
 static void
-lpfc_rscn_disc(struct lpfc_hba * phba)
+lpfc_rscn_disc(struct lpfc_vport *vport)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
 	/* RSCN discovery */
-	/* go thru NPR list and issue ELS PLOGIs */
-	if (phba->fc_npr_cnt) {
-		if (lpfc_els_disc_plogi(phba))
+	/* go thru NPR nodes and issue ELS PLOGIs */
+	if (vport->fc_npr_cnt)
+		if (lpfc_els_disc_plogi(vport))
 			return;
-	}
-	if (phba->fc_flag & FC_RSCN_MODE) {
+
+	if (vport->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);
+		if ((vport->fc_rscn_id_cnt == 0) &&
+		    (!(vport->fc_flag & FC_RSCN_DISCOVERY))) {
+			spin_lock_irq(shost->host_lock);
+			vport->fc_flag &= ~FC_RSCN_MODE;
+			spin_unlock_irq(shost->host_lock);
 		} else {
-			lpfc_els_handle_rscn(phba);
+			lpfc_els_handle_rscn(vport);
 		}
 	}
 }
 
 static void
-lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-		    struct lpfc_iocbq * rspiocb)
+lpfc_cmpl_els_adisc(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;
-	struct lpfc_sli *psli;
 	struct lpfc_nodelist *ndlp;
-	LPFC_MBOXQ_t *mbox;
-	int disc, rc;
-
-	psli = &phba->sli;
+	int  disc;
 
 	/* we pass cmdiocb to state machine which needs rspiocb as well */
 	cmdiocb->context_un.rsp_iocb = rspiocb;
@@ -1040,10 +1052,10 @@
 	/* Since ndlp can be freed in the disc state machine, note if this node
 	 * is being used during discovery.
 	 */
+	spin_lock_irq(shost->host_lock);
 	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);
+	spin_unlock_irq(shost->host_lock);
 
 	/* ADISC completes to NPort <nlp_DID> */
 	lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
@@ -1051,13 +1063,13 @@
 			"Data: x%x 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);
+			vport->num_disc_nodes);
 
 	/* Check to see if link went down during discovery */
-	if (lpfc_els_chk_latt(phba)) {
-		spin_lock_irq(phba->host->host_lock);
+	if (lpfc_els_chk_latt(vport)) {
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag |= NLP_NPR_2B_DISC;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 		goto out;
 	}
 
@@ -1066,10 +1078,10 @@
 		if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
 			/* ELS command is being retried */
 			if (disc) {
-				spin_lock_irq(phba->host->host_lock);
+				spin_lock_irq(shost->host_lock);
 				ndlp->nlp_flag |= NLP_NPR_2B_DISC;
-				spin_unlock_irq(phba->host->host_lock);
-				lpfc_set_disctmo(phba);
+				spin_unlock_irq(shost->host_lock);
+				lpfc_set_disctmo(vport);
 			}
 			goto out;
 		}
@@ -1079,54 +1091,30 @@
 		   ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) &&
 		   (irsp->un.ulpWord[4] != IOERR_LINK_DOWN) &&
 		   (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) {
-			lpfc_disc_state_machine(phba, ndlp, cmdiocb,
+			lpfc_disc_state_machine(vport, ndlp, cmdiocb,
 					NLP_EVT_CMPL_ADISC);
 		}
 	} else {
 		/* Good status, call state machine */
-		lpfc_disc_state_machine(phba, ndlp, cmdiocb,
+		lpfc_disc_state_machine(vport, ndlp, cmdiocb,
 					NLP_EVT_CMPL_ADISC);
 	}
 
-	if (disc && phba->num_disc_nodes) {
+	if (disc && vport->num_disc_nodes) {
 		/* Check to see if there are more ADISCs to be sent */
-		lpfc_more_adisc(phba);
+		lpfc_more_adisc(vport);
 
 		/* Check to see if we are done with ADISC authentication */
-		if (phba->num_disc_nodes == 0) {
-			lpfc_can_disctmo(phba);
+		if (vport->num_disc_nodes == 0) {
+			lpfc_can_disctmo(vport);
 			/* If we get here, there is nothing left to wait for */
-			if ((phba->hba_state < LPFC_HBA_READY) &&
-			    (phba->hba_state != LPFC_CLEAR_LA)) {
-				/* Link up discovery */
-				if ((mbox = mempool_alloc(phba->mbox_mem_pool,
-							  GFP_KERNEL))) {
-					phba->hba_state = LPFC_CLEAR_LA;
-					lpfc_clear_la(phba, mbox);
-					mbox->mbox_cmpl =
-					    lpfc_mbx_cmpl_clear_la;
-					rc = lpfc_sli_issue_mbox
-						(phba, mbox,
-						 (MBX_NOWAIT | MBX_STOP_IOCB));
-					if (rc == MBX_NOT_FINISHED) {
-						mempool_free(mbox,
-						     phba->mbox_mem_pool);
-						lpfc_disc_flush_list(phba);
-						psli->ring[(psli->extra_ring)].
-						    flag &=
-						    ~LPFC_STOP_IOCB_EVENT;
-						psli->ring[(psli->fcp_ring)].
-						    flag &=
-						    ~LPFC_STOP_IOCB_EVENT;
-						psli->ring[(psli->next_ring)].
-						    flag &=
-						    ~LPFC_STOP_IOCB_EVENT;
-						phba->hba_state =
-						    LPFC_HBA_READY;
-					}
+			if (vport->port_state < LPFC_VPORT_READY &&
+			    phba->link_state != LPFC_CLEAR_LA) {
+				if (vport->port_type == LPFC_PHYSICAL_PORT) {
+					lpfc_issue_clear_la(phba, vport);
 				}
 			} else {
-				lpfc_rscn_disc(phba);
+				lpfc_rscn_disc(vport);
 			}
 		}
 	}
@@ -1136,23 +1124,22 @@
 }
 
 int
-lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
+lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 		     uint8_t retry)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
 	ADISC *ap;
 	IOCB_t *icmd;
 	struct lpfc_iocbq *elsiocb;
-	struct lpfc_sli_ring *pring;
-	struct lpfc_sli *psli;
+	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
 	uint8_t *pcmd;
 	uint16_t cmdsize;
 
-	psli = &phba->sli;
-	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);
+	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_ADISC);
 	if (!elsiocb)
 		return 1;
 
@@ -1166,41 +1153,43 @@
 	/* Fill in ADISC payload */
 	ap = (ADISC *) pcmd;
 	ap->hardAL_PA = phba->fc_pref_ALPA;
-	memcpy(&ap->portName, &phba->fc_portname, sizeof (struct lpfc_name));
-	memcpy(&ap->nodeName, &phba->fc_nodename, sizeof (struct lpfc_name));
-	ap->DID = be32_to_cpu(phba->fc_myDID);
+	memcpy(&ap->portName, &vport->fc_portname, sizeof (struct lpfc_name));
+	memcpy(&ap->nodeName, &vport->fc_nodename, sizeof (struct lpfc_name));
+	ap->DID = be32_to_cpu(vport->fc_myDID);
 
 	phba->fc_stat.elsXmitADISC++;
 	elsiocb->iocb_cmpl = lpfc_cmpl_els_adisc;
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag |= NLP_ADISC_SND;
+	spin_unlock_irq(shost->host_lock);
 	if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag &= ~NLP_ADISC_SND;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 		lpfc_els_free_iocb(phba, elsiocb);
 		return 1;
 	}
-	spin_unlock_irq(phba->host->host_lock);
 	return 0;
 }
 
 static void
-lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-		   struct lpfc_iocbq * rspiocb)
+lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+		   struct lpfc_iocbq *rspiocb)
 {
+	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
+	struct lpfc_vport *vport = ndlp->vport;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
 	IOCB_t *irsp;
 	struct lpfc_sli *psli;
-	struct lpfc_nodelist *ndlp;
 
 	psli = &phba->sli;
 	/* we pass cmdiocb to state machine which needs rspiocb as well */
 	cmdiocb->context_un.rsp_iocb = rspiocb;
 
 	irsp = &(rspiocb->iocb);
-	ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag &= ~NLP_LOGO_SND;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 
 	/* LOGO completes to NPort <nlp_DID> */
 	lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
@@ -1208,18 +1197,17 @@
 			"Data: x%x 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);
+			vport->num_disc_nodes);
 
 	/* Check to see if link went down during discovery */
-	if (lpfc_els_chk_latt(phba))
+	if (lpfc_els_chk_latt(vport))
 		goto out;
 
 	if (irsp->ulpStatus) {
 		/* Check for retry */
-		if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
+		if (lpfc_els_retry(phba, cmdiocb, rspiocb))
 			/* ELS command is being retried */
 			goto out;
-		}
 		/* LOGO failed */
 		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
 		if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
@@ -1228,14 +1216,15 @@
 		   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
 			goto out;
 		} else {
-			lpfc_disc_state_machine(phba, ndlp, cmdiocb,
+			lpfc_disc_state_machine(vport, ndlp, cmdiocb,
 					NLP_EVT_CMPL_LOGO);
 		}
 	} else {
 		/* Good status, call state machine.
 		 * This will unregister the rpi if needed.
 		 */
-		lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO);
+		lpfc_disc_state_machine(vport, ndlp, cmdiocb,
+							NLP_EVT_CMPL_LOGO);
 	}
 
 out:
@@ -1244,9 +1233,11 @@
 }
 
 int
-lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
+lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 		    uint8_t retry)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
 	IOCB_t *icmd;
 	struct lpfc_iocbq *elsiocb;
 	struct lpfc_sli_ring *pring;
@@ -1258,8 +1249,8 @@
 	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);
+	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_LOGO);
 	if (!elsiocb)
 		return 1;
 
@@ -1269,28 +1260,30 @@
 	pcmd += sizeof (uint32_t);
 
 	/* Fill in LOGO payload */
-	*((uint32_t *) (pcmd)) = be32_to_cpu(phba->fc_myDID);
+	*((uint32_t *) (pcmd)) = be32_to_cpu(vport->fc_myDID);
 	pcmd += sizeof (uint32_t);
-	memcpy(pcmd, &phba->fc_portname, sizeof (struct lpfc_name));
+	memcpy(pcmd, &vport->fc_portname, sizeof (struct lpfc_name));
 
 	phba->fc_stat.elsXmitLOGO++;
 	elsiocb->iocb_cmpl = lpfc_cmpl_els_logo;
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag |= NLP_LOGO_SND;
+	spin_unlock_irq(shost->host_lock);
 	if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag &= ~NLP_LOGO_SND;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 		lpfc_els_free_iocb(phba, elsiocb);
 		return 1;
 	}
-	spin_unlock_irq(phba->host->host_lock);
 	return 0;
 }
 
 static void
-lpfc_cmpl_els_cmd(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-		  struct lpfc_iocbq * rspiocb)
+lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+		  struct lpfc_iocbq *rspiocb)
 {
+	struct lpfc_vport *vport = cmdiocb->vport;
 	IOCB_t *irsp;
 
 	irsp = &rspiocb->iocb;
@@ -1305,14 +1298,15 @@
 			irsp->un.ulpWord[4], irsp->ulpTimeout);
 
 	/* Check to see if link went down during discovery */
-	lpfc_els_chk_latt(phba);
+	lpfc_els_chk_latt(vport);
 	lpfc_els_free_iocb(phba, cmdiocb);
 	return;
 }
 
 int
-lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
+lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
 {
+	struct lpfc_hba  *phba = vport->phba;
 	IOCB_t *icmd;
 	struct lpfc_iocbq *elsiocb;
 	struct lpfc_sli_ring *pring;
@@ -1328,10 +1322,11 @@
 	if (!ndlp)
 		return 1;
 
-	lpfc_nlp_init(phba, ndlp, nportid);
+	lpfc_nlp_init(vport, ndlp, nportid);
 
-	elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp,
-						ndlp->nlp_DID, ELS_CMD_SCR);
+	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_SCR);
+
 	if (!elsiocb) {
 		lpfc_nlp_put(ndlp);
 		return 1;
@@ -1349,21 +1344,19 @@
 
 	phba->fc_stat.elsXmitSCR++;
 	elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
-	spin_lock_irq(phba->host->host_lock);
 	if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
-		spin_unlock_irq(phba->host->host_lock);
 		lpfc_nlp_put(ndlp);
 		lpfc_els_free_iocb(phba, elsiocb);
 		return 1;
 	}
-	spin_unlock_irq(phba->host->host_lock);
 	lpfc_nlp_put(ndlp);
 	return 0;
 }
 
 static int
-lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
+lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
 {
+	struct lpfc_hba  *phba = vport->phba;
 	IOCB_t *icmd;
 	struct lpfc_iocbq *elsiocb;
 	struct lpfc_sli_ring *pring;
@@ -1381,10 +1374,11 @@
 	ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
 	if (!ndlp)
 		return 1;
-	lpfc_nlp_init(phba, ndlp, nportid);
 
-	elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp,
-						ndlp->nlp_DID, ELS_CMD_RNID);
+	lpfc_nlp_init(vport, ndlp, nportid);
+
+	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_RNID);
 	if (!elsiocb) {
 		lpfc_nlp_put(ndlp);
 		return 1;
@@ -1401,13 +1395,14 @@
 	memset(fp, 0, sizeof (FARP));
 	lp = (uint32_t *) pcmd;
 	*lp++ = be32_to_cpu(nportid);
-	*lp++ = be32_to_cpu(phba->fc_myDID);
+	*lp++ = be32_to_cpu(vport->fc_myDID);
 	fp->Rflags = 0;
 	fp->Mflags = (FARP_MATCH_PORT | FARP_MATCH_NODE);
 
-	memcpy(&fp->RportName, &phba->fc_portname, sizeof (struct lpfc_name));
-	memcpy(&fp->RnodeName, &phba->fc_nodename, sizeof (struct lpfc_name));
-	if ((ondlp = lpfc_findnode_did(phba, nportid))) {
+	memcpy(&fp->RportName, &vport->fc_portname, sizeof (struct lpfc_name));
+	memcpy(&fp->RnodeName, &vport->fc_nodename, sizeof (struct lpfc_name));
+	ondlp = lpfc_findnode_did(vport, nportid);
+	if (ondlp) {
 		memcpy(&fp->OportName, &ondlp->nlp_portname,
 		       sizeof (struct lpfc_name));
 		memcpy(&fp->OnodeName, &ondlp->nlp_nodename,
@@ -1416,22 +1411,23 @@
 
 	phba->fc_stat.elsXmitFARPR++;
 	elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
-	spin_lock_irq(phba->host->host_lock);
 	if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
-		spin_unlock_irq(phba->host->host_lock);
 		lpfc_nlp_put(ndlp);
 		lpfc_els_free_iocb(phba, elsiocb);
 		return 1;
 	}
-	spin_unlock_irq(phba->host->host_lock);
 	lpfc_nlp_put(ndlp);
 	return 0;
 }
 
 void
-lpfc_cancel_retry_delay_tmo(struct lpfc_hba *phba, struct lpfc_nodelist * nlp)
+lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
+	spin_lock_irq(shost->host_lock);
 	nlp->nlp_flag &= ~NLP_DELAY_TMO;
+	spin_unlock_irq(shost->host_lock);
 	del_timer_sync(&nlp->nlp_delayfunc);
 	nlp->nlp_last_elscmd = 0;
 
@@ -1439,28 +1435,36 @@
 		list_del_init(&nlp->els_retry_evt.evt_listp);
 
 	if (nlp->nlp_flag & NLP_NPR_2B_DISC) {
+		spin_lock_irq(shost->host_lock);
 		nlp->nlp_flag &= ~NLP_NPR_2B_DISC;
-		if (phba->num_disc_nodes) {
+		spin_unlock_irq(shost->host_lock);
+		if (vport->num_disc_nodes) {
 			/* Check to see if there are more
 			 * PLOGIs to be sent
 			 */
-			lpfc_more_plogi(phba);
+			lpfc_more_plogi(vport);
 
-			if (phba->num_disc_nodes == 0) {
-				phba->fc_flag &= ~FC_NDISC_ACTIVE;
-				lpfc_can_disctmo(phba);
-				if (phba->fc_flag & FC_RSCN_MODE) {
+			if (vport->num_disc_nodes == 0) {
+				spin_lock_irq(shost->host_lock);
+				vport->fc_flag &= ~FC_NDISC_ACTIVE;
+				spin_unlock_irq(shost->host_lock);
+				lpfc_can_disctmo(vport);
+				if (vport->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;
+					if (!vport->fc_rscn_id_cnt &&
+					    !(vport->fc_flag &
+					      FC_RSCN_DISCOVERY)) {
+						spin_lock_irq(shost->host_lock);
+						vport->fc_flag &= ~FC_RSCN_MODE;
+						spin_unlock_irq(
+							shost->host_lock);
 					}
 					else {
-						lpfc_els_handle_rscn(phba);
+						lpfc_els_handle_rscn(vport);
 					}
 				}
 			}
@@ -1472,18 +1476,20 @@
 void
 lpfc_els_retry_delay(unsigned long ptr)
 {
-	struct lpfc_nodelist *ndlp;
-	struct lpfc_hba *phba;
+	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) ptr;
+	struct lpfc_vport *vport = ndlp->vport;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba   *phba = vport->phba;
 	unsigned long iflag;
-	struct lpfc_work_evt  *evtp;
+	struct lpfc_work_evt  *evtp = &ndlp->els_retry_evt;
 
-	ndlp = (struct lpfc_nodelist *)ptr;
-	phba = ndlp->nlp_phba;
+	ndlp = (struct lpfc_nodelist *) ptr;
+	phba = ndlp->vport->phba;
 	evtp = &ndlp->els_retry_evt;
 
-	spin_lock_irqsave(phba->host->host_lock, iflag);
+	spin_lock_irqsave(shost->host_lock, iflag);
 	if (!list_empty(&evtp->evt_listp)) {
-		spin_unlock_irqrestore(phba->host->host_lock, iflag);
+		spin_unlock_irqrestore(shost->host_lock, iflag);
 		return;
 	}
 
@@ -1493,31 +1499,29 @@
 	if (phba->work_wait)
 		wake_up(phba->work_wait);
 
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
+	spin_unlock_irqrestore(shost->host_lock, iflag);
 	return;
 }
 
 void
 lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
 {
-	struct lpfc_hba *phba;
-	uint32_t cmd;
-	uint32_t did;
-	uint8_t retry;
+	struct lpfc_vport *vport = ndlp->vport;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
+	uint32_t cmd, did, retry;
 
-	phba = ndlp->nlp_phba;
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	did = ndlp->nlp_DID;
 	cmd = ndlp->nlp_last_elscmd;
 	ndlp->nlp_last_elscmd = 0;
 
 	if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 		return;
 	}
 
 	ndlp->nlp_flag &= ~NLP_DELAY_TMO;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 	/*
 	 * If a discovery event readded nlp_delayfunc after timer
 	 * firing and before processing the timer, cancel the
@@ -1528,30 +1532,30 @@
 
 	switch (cmd) {
 	case ELS_CMD_FLOGI:
-		lpfc_issue_els_flogi(phba, ndlp, retry);
+		lpfc_issue_els_flogi(vport, ndlp, retry);
 		break;
 	case ELS_CMD_PLOGI:
-		if(!lpfc_issue_els_plogi(phba, ndlp->nlp_DID, retry)) {
+		if (!lpfc_issue_els_plogi(vport, ndlp->nlp_DID, retry)) {
 			ndlp->nlp_prev_state = ndlp->nlp_state;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE);
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
 		}
 		break;
 	case ELS_CMD_ADISC:
-		if (!lpfc_issue_els_adisc(phba, ndlp, retry)) {
+		if (!lpfc_issue_els_adisc(vport, ndlp, retry)) {
 			ndlp->nlp_prev_state = ndlp->nlp_state;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE);
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
 		}
 		break;
 	case ELS_CMD_PRLI:
-		if (!lpfc_issue_els_prli(phba, ndlp, retry)) {
+		if (!lpfc_issue_els_prli(vport, ndlp, retry)) {
 			ndlp->nlp_prev_state = ndlp->nlp_state;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_PRLI_ISSUE);
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
 		}
 		break;
 	case ELS_CMD_LOGO:
-		if (!lpfc_issue_els_logo(phba, ndlp, retry)) {
+		if (!lpfc_issue_els_logo(vport, ndlp, retry)) {
 			ndlp->nlp_prev_state = ndlp->nlp_state;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
 		}
 		break;
 	}
@@ -1559,26 +1563,20 @@
 }
 
 static int
-lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-	       struct lpfc_iocbq * rspiocb)
+lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+	       struct lpfc_iocbq *rspiocb)
 {
-	IOCB_t *irsp;
-	struct lpfc_dmabuf *pcmd;
-	struct lpfc_nodelist *ndlp;
+	struct lpfc_vport *vport = cmdiocb->vport;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
+	IOCB_t *irsp = &rspiocb->iocb;
+	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
+	struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
 	uint32_t *elscmd;
 	struct ls_rjt stat;
-	int retry, maxretry;
-	int delay;
-	uint32_t cmd;
+	int retry = 0, maxretry = lpfc_max_els_tries, delay = 0;
+	uint32_t cmd = 0;
 	uint32_t did;
 
-	retry = 0;
-	delay = 0;
-	maxretry = lpfc_max_els_tries;
-	irsp = &rspiocb->iocb;
-	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.
@@ -1594,7 +1592,7 @@
 	else {
 		/* We should only hit this case for retrying PLOGI */
 		did = irsp->un.elsreq64.remoteID;
-		ndlp = lpfc_findnode_did(phba, did);
+		ndlp = lpfc_findnode_did(vport, did);
 		if (!ndlp && (cmd != ELS_CMD_PLOGI))
 			return 1;
 	}
@@ -1607,11 +1605,8 @@
 	case IOSTAT_LOCAL_REJECT:
 		switch ((irsp->un.ulpWord[4] & 0xff)) {
 		case IOERR_LOOP_OPEN_FAILURE:
-			if (cmd == ELS_CMD_PLOGI) {
-				if (cmdiocb->retry == 0) {
+			if (cmd == ELS_CMD_PLOGI && cmdiocb->retry == 0)
 					delay = 1;
-				}
-			}
 			retry = 1;
 			break;
 
@@ -1620,9 +1615,8 @@
 			break;
 
 		case IOERR_NO_RESOURCES:
-			if (cmd == ELS_CMD_PLOGI) {
+			if (cmd == ELS_CMD_PLOGI)
 				delay = 1;
-			}
 			retry = 1;
 			break;
 
@@ -1706,10 +1700,9 @@
 
 		if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) {
 			/* If discovery / RSCN timer is running, reset it */
-			if (timer_pending(&phba->fc_disctmo) ||
-			      (phba->fc_flag & FC_RSCN_MODE)) {
-				lpfc_set_disctmo(phba);
-			}
+			if (timer_pending(&vport->fc_disctmo) ||
+			      (vport->fc_flag & FC_RSCN_MODE))
+				lpfc_set_disctmo(vport);
 		}
 
 		phba->fc_stat.elsXmitRetry++;
@@ -1718,40 +1711,42 @@
 			ndlp->nlp_retry = cmdiocb->retry;
 
 			mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
+			spin_lock_irq(shost->host_lock);
 			ndlp->nlp_flag |= NLP_DELAY_TMO;
+			spin_unlock_irq(shost->host_lock);
 
 			ndlp->nlp_prev_state = ndlp->nlp_state;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
 			ndlp->nlp_last_elscmd = cmd;
 
 			return 1;
 		}
 		switch (cmd) {
 		case ELS_CMD_FLOGI:
-			lpfc_issue_els_flogi(phba, ndlp, cmdiocb->retry);
+			lpfc_issue_els_flogi(vport, ndlp, cmdiocb->retry);
 			return 1;
 		case ELS_CMD_PLOGI:
 			if (ndlp) {
 				ndlp->nlp_prev_state = ndlp->nlp_state;
-				lpfc_nlp_set_state(phba, ndlp,
+				lpfc_nlp_set_state(vport, ndlp,
 						   NLP_STE_PLOGI_ISSUE);
 			}
-			lpfc_issue_els_plogi(phba, did, cmdiocb->retry);
+			lpfc_issue_els_plogi(vport, did, cmdiocb->retry);
 			return 1;
 		case ELS_CMD_ADISC:
 			ndlp->nlp_prev_state = ndlp->nlp_state;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE);
-			lpfc_issue_els_adisc(phba, ndlp, cmdiocb->retry);
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
+			lpfc_issue_els_adisc(vport, ndlp, cmdiocb->retry);
 			return 1;
 		case ELS_CMD_PRLI:
 			ndlp->nlp_prev_state = ndlp->nlp_state;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_PRLI_ISSUE);
-			lpfc_issue_els_prli(phba, ndlp, cmdiocb->retry);
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
+			lpfc_issue_els_prli(vport, ndlp, cmdiocb->retry);
 			return 1;
 		case ELS_CMD_LOGO:
 			ndlp->nlp_prev_state = ndlp->nlp_state;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
-			lpfc_issue_els_logo(phba, ndlp, cmdiocb->retry);
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+			lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry);
 			return 1;
 		}
 	}
@@ -1795,19 +1790,16 @@
 		lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
 		kfree(buf_ptr);
 	}
-	spin_lock_irq(phba->host->host_lock);
 	lpfc_sli_release_iocbq(phba, elsiocb);
-	spin_unlock_irq(phba->host->host_lock);
 	return 0;
 }
 
 static void
-lpfc_cmpl_els_logo_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-		       struct lpfc_iocbq * rspiocb)
+lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+		       struct lpfc_iocbq *rspiocb)
 {
-	struct lpfc_nodelist *ndlp;
-
-	ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
+	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
+	struct lpfc_vport *vport = cmdiocb->vport;
 
 	/* ACC to LOGO completes to NPort <nlp_DID> */
 	lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
@@ -1818,10 +1810,10 @@
 
 	switch (ndlp->nlp_state) {
 	case NLP_STE_UNUSED_NODE:	/* node is just allocated */
-		lpfc_drop_node(phba, ndlp);
+		lpfc_drop_node(vport, ndlp);
 		break;
 	case NLP_STE_NPR_NODE:		/* NPort Recovery mode */
-		lpfc_unreg_rpi(phba, ndlp);
+		lpfc_unreg_rpi(vport, ndlp);
 		break;
 	default:
 		break;
@@ -1834,20 +1826,20 @@
 lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 		  struct lpfc_iocbq *rspiocb)
 {
+	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
+	struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL;
+	struct Scsi_Host  *shost = vport ? lpfc_shost_from_vport(vport) : NULL;
 	IOCB_t *irsp;
-	struct lpfc_nodelist *ndlp;
 	LPFC_MBOXQ_t *mbox = NULL;
-	struct lpfc_dmabuf *mp;
+	struct lpfc_dmabuf *mp = NULL;
 
 	irsp = &rspiocb->iocb;
 
-	ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
 	if (cmdiocb->context_un.mbox)
 		mbox = cmdiocb->context_un.mbox;
 
-
 	/* Check to see if link went down during discovery */
-	if (lpfc_els_chk_latt(phba) || !ndlp) {
+	if (!ndlp || lpfc_els_chk_latt(vport)) {
 		if (mbox) {
 			mp = (struct lpfc_dmabuf *) mbox->context1;
 			if (mp) {
@@ -1866,17 +1858,19 @@
 			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_DID, ndlp->nlp_flag, ndlp->nlp_state,
 			ndlp->nlp_rpi);
 
 	if (mbox) {
 		if ((rspiocb->iocb.ulpStatus == 0)
 		    && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) {
-			lpfc_unreg_rpi(phba, ndlp);
+			lpfc_unreg_rpi(vport, ndlp);
 			mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
 			mbox->context2 = lpfc_nlp_get(ndlp);
+			mbox->vport = vport;
 			ndlp->nlp_prev_state = ndlp->nlp_state;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_REG_LOGIN_ISSUE);
+			lpfc_nlp_set_state(vport, ndlp,
+					   NLP_STE_REG_LOGIN_ISSUE);
 			if (lpfc_sli_issue_mbox(phba, mbox,
 						(MBX_NOWAIT | MBX_STOP_IOCB))
 			    != MBX_NOT_FINISHED) {
@@ -1892,7 +1886,7 @@
 			       (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
 			       (irsp->un.ulpWord[4] == IOERR_SLI_DOWN)))) {
 				if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
-					lpfc_drop_node(phba, ndlp);
+					lpfc_drop_node(vport, ndlp);
 					ndlp = NULL;
 				}
 			}
@@ -1906,19 +1900,21 @@
 	}
 out:
 	if (ndlp) {
-		spin_lock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 	}
 	lpfc_els_free_iocb(phba, cmdiocb);
 	return;
 }
 
 int
-lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
-		 struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp,
-		 LPFC_MBOXQ_t * mbox, uint8_t newnode)
+lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
+		 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
+		 LPFC_MBOXQ_t *mbox, uint8_t newnode)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
 	IOCB_t *icmd;
 	IOCB_t *oldcmd;
 	struct lpfc_iocbq *elsiocb;
@@ -1936,12 +1932,15 @@
 	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);
+		elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
+					     ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
 		if (!elsiocb) {
+			spin_lock_irq(shost->host_lock);
 			ndlp->nlp_flag &= ~NLP_LOGO_ACC;
+			spin_unlock_irq(shost->host_lock);
 			return 1;
 		}
+
 		icmd = &elsiocb->iocb;
 		icmd->ulpContext = oldcmd->ulpContext;	/* Xri */
 		pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
@@ -1950,8 +1949,8 @@
 		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);
+		elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
+					     ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
 		if (!elsiocb)
 			return 1;
 
@@ -1964,11 +1963,11 @@
 
 		*((uint32_t *) (pcmd)) = ELS_CMD_ACC;
 		pcmd += sizeof (uint32_t);
-		memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm));
+		memcpy(pcmd, &vport->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,
+		elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
 					     ndlp, ndlp->nlp_DID, ELS_CMD_PRLO);
 		if (!elsiocb)
 			return 1;
@@ -2001,18 +2000,16 @@
 			ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
 
 	if (ndlp->nlp_flag & NLP_LOGO_ACC) {
-		spin_lock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag &= ~NLP_LOGO_ACC;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 		elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc;
 	} else {
 		elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
 	}
 
 	phba->fc_stat.elsXmitACC++;
-	spin_lock_irq(phba->host->host_lock);
 	rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
-	spin_unlock_irq(phba->host->host_lock);
 	if (rc == IOCB_ERROR) {
 		lpfc_els_free_iocb(phba, elsiocb);
 		return 1;
@@ -2021,9 +2018,10 @@
 }
 
 int
-lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError,
-		    struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp)
+lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
+		    struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
 {
+	struct lpfc_hba  *phba = vport->phba;
 	IOCB_t *icmd;
 	IOCB_t *oldcmd;
 	struct lpfc_iocbq *elsiocb;
@@ -2037,8 +2035,8 @@
 	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);
+	elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_LS_RJT);
 	if (!elsiocb)
 		return 1;
 
@@ -2061,9 +2059,7 @@
 
 	phba->fc_stat.elsXmitLSRJT++;
 	elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
-	spin_lock_irq(phba->host->host_lock);
 	rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
-	spin_unlock_irq(phba->host->host_lock);
 	if (rc == IOCB_ERROR) {
 		lpfc_els_free_iocb(phba, elsiocb);
 		return 1;
@@ -2072,25 +2068,22 @@
 }
 
 int
-lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba,
-		       struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp)
+lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
+		       struct lpfc_nodelist *ndlp)
 {
+	struct lpfc_hba  *phba = vport->phba;
+	struct lpfc_sli  *psli = &phba->sli;
+	struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
 	ADISC *ap;
-	IOCB_t *icmd;
-	IOCB_t *oldcmd;
+	IOCB_t *icmd, *oldcmd;
 	struct lpfc_iocbq *elsiocb;
-	struct lpfc_sli_ring *pring;
-	struct lpfc_sli *psli;
 	uint8_t *pcmd;
 	uint16_t cmdsize;
 	int rc;
 
-	psli = &phba->sli;
-	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);
+	elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_ACC);
 	if (!elsiocb)
 		return 1;
 
@@ -2113,15 +2106,13 @@
 
 	ap = (ADISC *) (pcmd);
 	ap->hardAL_PA = phba->fc_pref_ALPA;
-	memcpy(&ap->portName, &phba->fc_portname, sizeof (struct lpfc_name));
-	memcpy(&ap->nodeName, &phba->fc_nodename, sizeof (struct lpfc_name));
-	ap->DID = be32_to_cpu(phba->fc_myDID);
+	memcpy(&ap->portName, &vport->fc_portname, sizeof (struct lpfc_name));
+	memcpy(&ap->nodeName, &vport->fc_nodename, sizeof (struct lpfc_name));
+	ap->DID = be32_to_cpu(vport->fc_myDID);
 
 	phba->fc_stat.elsXmitACC++;
 	elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
-	spin_lock_irq(phba->host->host_lock);
 	rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
-	spin_unlock_irq(phba->host->host_lock);
 	if (rc == IOCB_ERROR) {
 		lpfc_els_free_iocb(phba, elsiocb);
 		return 1;
@@ -2130,9 +2121,10 @@
 }
 
 int
-lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb,
+lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
 		      struct lpfc_nodelist *ndlp)
 {
+	struct lpfc_hba  *phba = vport->phba;
 	PRLI *npr;
 	lpfc_vpd_t *vpd;
 	IOCB_t *icmd;
@@ -2148,8 +2140,10 @@
 	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)));
+	elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
+				     ndlp->nlp_DID,
+				     (ELS_CMD_ACC |
+				      (ELS_CMD_PRLI & ~ELS_RSP_MASK)));
 	if (!elsiocb)
 		return 1;
 
@@ -2196,9 +2190,7 @@
 	phba->fc_stat.elsXmitACC++;
 	elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
 
-	spin_lock_irq(phba->host->host_lock);
 	rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
-	spin_unlock_irq(phba->host->host_lock);
 	if (rc == IOCB_ERROR) {
 		lpfc_els_free_iocb(phba, elsiocb);
 		return 1;
@@ -2207,12 +2199,12 @@
 }
 
 static int
-lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format,
+lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
 		      struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
 {
+	struct lpfc_hba  *phba = vport->phba;
 	RNID *rn;
-	IOCB_t *icmd;
-	IOCB_t *oldcmd;
+	IOCB_t *icmd, *oldcmd;
 	struct lpfc_iocbq *elsiocb;
 	struct lpfc_sli_ring *pring;
 	struct lpfc_sli *psli;
@@ -2228,8 +2220,8 @@
 	if (format)
 		cmdsize += sizeof (RNID_TOP_DISC);
 
-	elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
-					ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
+	elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_ACC);
 	if (!elsiocb)
 		return 1;
 
@@ -2253,8 +2245,8 @@
 	rn = (RNID *) (pcmd);
 	rn->Format = format;
 	rn->CommonLen = (2 * sizeof (struct lpfc_name));
-	memcpy(&rn->portName, &phba->fc_portname, sizeof (struct lpfc_name));
-	memcpy(&rn->nodeName, &phba->fc_nodename, sizeof (struct lpfc_name));
+	memcpy(&rn->portName, &vport->fc_portname, sizeof (struct lpfc_name));
+	memcpy(&rn->nodeName, &vport->fc_nodename, sizeof (struct lpfc_name));
 	switch (format) {
 	case 0:
 		rn->SpecificLen = 0;
@@ -2262,7 +2254,7 @@
 	case RNID_TOPOLOGY_DISC:
 		rn->SpecificLen = sizeof (RNID_TOP_DISC);
 		memcpy(&rn->un.topologyDisc.portName,
-		       &phba->fc_portname, sizeof (struct lpfc_name));
+		       &vport->fc_portname, sizeof (struct lpfc_name));
 		rn->un.topologyDisc.unitType = RNID_HBA;
 		rn->un.topologyDisc.physPort = 0;
 		rn->un.topologyDisc.attachedNodes = 0;
@@ -2279,9 +2271,7 @@
 	elsiocb->context1 = NULL;  /* Don't need ndlp for cmpl,
 				    * it could be freed */
 
-	spin_lock_irq(phba->host->host_lock);
 	rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
-	spin_unlock_irq(phba->host->host_lock);
 	if (rc == IOCB_ERROR) {
 		lpfc_els_free_iocb(phba, elsiocb);
 		return 1;
@@ -2290,120 +2280,122 @@
 }
 
 int
-lpfc_els_disc_adisc(struct lpfc_hba *phba)
+lpfc_els_disc_adisc(struct lpfc_vport *vport)
 {
-	int sentadisc;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 	struct lpfc_nodelist *ndlp, *next_ndlp;
+	int sentadisc = 0;
 
-	sentadisc = 0;
 	/* go thru NPR nodes and issue any remaining ELS ADISCs */
-	list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) {
+	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
 		if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
 		    (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
 		    (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) {
-			spin_lock_irq(phba->host->host_lock);
+			spin_lock_irq(shost->host_lock);
 			ndlp->nlp_flag &= ~NLP_NPR_ADISC;
-			spin_unlock_irq(phba->host->host_lock);
+			spin_unlock_irq(shost->host_lock);
 			ndlp->nlp_prev_state = ndlp->nlp_state;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE);
-			lpfc_issue_els_adisc(phba, ndlp, 0);
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
+			lpfc_issue_els_adisc(vport, ndlp, 0);
 			sentadisc++;
-			phba->num_disc_nodes++;
-			if (phba->num_disc_nodes >=
-			    phba->cfg_discovery_threads) {
-				spin_lock_irq(phba->host->host_lock);
-				phba->fc_flag |= FC_NLP_MORE;
-				spin_unlock_irq(phba->host->host_lock);
+			vport->num_disc_nodes++;
+			if (vport->num_disc_nodes >=
+			    vport->phba->cfg_discovery_threads) {
+				spin_lock_irq(shost->host_lock);
+				vport->fc_flag |= FC_NLP_MORE;
+				spin_unlock_irq(shost->host_lock);
 				break;
 			}
 		}
 	}
 	if (sentadisc == 0) {
-		spin_lock_irq(phba->host->host_lock);
-		phba->fc_flag &= ~FC_NLP_MORE;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
+		vport->fc_flag &= ~FC_NLP_MORE;
+		spin_unlock_irq(shost->host_lock);
 	}
 	return sentadisc;
 }
 
 int
-lpfc_els_disc_plogi(struct lpfc_hba * phba)
+lpfc_els_disc_plogi(struct lpfc_vport *vport)
 {
-	int sentplogi;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 	struct lpfc_nodelist *ndlp, *next_ndlp;
+	int sentplogi = 0;
 
-	sentplogi = 0;
-	/* go thru NPR list and issue any remaining ELS PLOGIs */
-	list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) {
+	/* go thru NPR nodes and issue any remaining ELS PLOGIs */
+	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
 		if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
 		    (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
 		    (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 &&
 		    (ndlp->nlp_flag & NLP_NPR_ADISC) == 0) {
 			ndlp->nlp_prev_state = ndlp->nlp_state;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE);
-			lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0);
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
+			lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
 			sentplogi++;
-			phba->num_disc_nodes++;
-			if (phba->num_disc_nodes >=
-			    phba->cfg_discovery_threads) {
-				spin_lock_irq(phba->host->host_lock);
-				phba->fc_flag |= FC_NLP_MORE;
-				spin_unlock_irq(phba->host->host_lock);
+			vport->num_disc_nodes++;
+			if (vport->num_disc_nodes >=
+			    vport->phba->cfg_discovery_threads) {
+				spin_lock_irq(shost->host_lock);
+				vport->fc_flag |= FC_NLP_MORE;
+				spin_unlock_irq(shost->host_lock);
 				break;
 			}
 		}
 	}
 	if (sentplogi == 0) {
-		spin_lock_irq(phba->host->host_lock);
-		phba->fc_flag &= ~FC_NLP_MORE;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
+		vport->fc_flag &= ~FC_NLP_MORE;
+		spin_unlock_irq(shost->host_lock);
 	}
 	return sentplogi;
 }
 
 int
-lpfc_els_flush_rscn(struct lpfc_hba * phba)
+lpfc_els_flush_rscn(struct lpfc_vport *vport)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
 	struct lpfc_dmabuf *mp;
 	int i;
 
-	for (i = 0; i < phba->fc_rscn_id_cnt; i++) {
-		mp = phba->fc_rscn_id_list[i];
+	for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
+		mp = vport->fc_rscn_id_list[i];
 		lpfc_mbuf_free(phba, mp->virt, mp->phys);
 		kfree(mp);
-		phba->fc_rscn_id_list[i] = NULL;
+		vport->fc_rscn_id_list[i] = NULL;
 	}
-	phba->fc_rscn_id_cnt = 0;
-	spin_lock_irq(phba->host->host_lock);
-	phba->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY);
-	spin_unlock_irq(phba->host->host_lock);
-	lpfc_can_disctmo(phba);
+	spin_lock_irq(shost->host_lock);
+	vport->fc_rscn_id_cnt = 0;
+	vport->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY);
+	spin_unlock_irq(shost->host_lock);
+	lpfc_can_disctmo(vport);
 	return 0;
 }
 
 int
-lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did)
+lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did)
 {
 	D_ID ns_did;
 	D_ID rscn_did;
 	struct lpfc_dmabuf *mp;
 	uint32_t *lp;
 	uint32_t payload_len, cmd, i, match;
+	struct lpfc_hba *phba = vport->phba;
 
 	ns_did.un.word = did;
 	match = 0;
 
 	/* Never match fabric nodes for RSCNs */
 	if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
-		return(0);
+		return 0;
 
 	/* If we are doing a FULL RSCN rediscovery, match everything */
-	if (phba->fc_flag & FC_RSCN_DISCOVERY) {
+	if (vport->fc_flag & FC_RSCN_DISCOVERY)
 		return did;
-	}
 
-	for (i = 0; i < phba->fc_rscn_id_cnt; i++) {
-		mp = phba->fc_rscn_id_list[i];
+	for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
+		mp = vport->fc_rscn_id_list[i];
 		lp = (uint32_t *) mp->virt;
 		cmd = *lp++;
 		payload_len = be32_to_cpu(cmd) & 0xffff; /* payload length */
@@ -2414,44 +2406,38 @@
 			payload_len -= sizeof (uint32_t);
 			switch (rscn_did.un.b.resv) {
 			case 0:	/* Single N_Port ID effected */
-				if (ns_did.un.word == rscn_did.un.word) {
+				if (ns_did.un.word == rscn_did.un.word)
 					match = did;
-				}
 				break;
 			case 1:	/* Whole N_Port Area effected */
 				if ((ns_did.un.b.domain == rscn_did.un.b.domain)
 				    && (ns_did.un.b.area == rscn_did.un.b.area))
-					{
 						match = did;
-					}
 				break;
 			case 2:	/* Whole N_Port Domain effected */
 				if (ns_did.un.b.domain == rscn_did.un.b.domain)
-					{
 						match = did;
-					}
 				break;
 			case 3:	/* Whole Fabric effected */
 				match = did;
 				break;
 			default:
-				/* Unknown Identifier in RSCN list */
+				/* Unknown Identifier in RSCN node */
 				lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
 						"%d:0217 Unknown Identifier in "
 						"RSCN payload Data: x%x\n",
 						phba->brd_no, rscn_did.un.word);
 				break;
 			}
-			if (match) {
+			if (match)
 				break;
 			}
 		}
-	}
 	return match;
 }
 
 static int
-lpfc_rscn_recovery_check(struct lpfc_hba *phba)
+lpfc_rscn_recovery_check(struct lpfc_vport *vport)
 {
 	struct lpfc_nodelist *ndlp = NULL;
 
@@ -2459,12 +2445,12 @@
 	 * them to NPR state.
 	 */
 
-	list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
+	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
 		if (ndlp->nlp_state == NLP_STE_UNUSED_NODE ||
-		    lpfc_rscn_payload_check(phba, ndlp->nlp_DID) == 0)
+		    lpfc_rscn_payload_check(vport, ndlp->nlp_DID) == 0)
 			continue;
 
-		lpfc_disc_state_machine(phba, ndlp, NULL,
+		lpfc_disc_state_machine(vport, ndlp, NULL,
 					NLP_EVT_DEVICE_RECOVERY);
 
 		/*
@@ -2472,17 +2458,18 @@
 		 * recovery event.
 		 */
 		if (ndlp->nlp_flag & NLP_DELAY_TMO)
-			lpfc_cancel_retry_delay_tmo(phba, ndlp);
+			lpfc_cancel_retry_delay_tmo(vport, ndlp);
 	}
 
 	return 0;
 }
 
 static int
-lpfc_els_rcv_rscn(struct lpfc_hba * phba,
-		  struct lpfc_iocbq * cmdiocb,
-		  struct lpfc_nodelist * ndlp, uint8_t newnode)
+lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+		  struct lpfc_nodelist *ndlp, uint8_t newnode)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
 	struct lpfc_dmabuf *pcmd;
 	uint32_t *lp;
 	IOCB_t *icmd;
@@ -2503,18 +2490,18 @@
 			KERN_INFO,
 			LOG_DISCOVERY,
 			"%d:0214 RSCN received Data: x%x x%x x%x x%x\n",
-			phba->brd_no,
-			phba->fc_flag, payload_len, *lp, phba->fc_rscn_id_cnt);
+			phba->brd_no, vport->fc_flag, payload_len, *lp,
+			vport->fc_rscn_id_cnt);
 
 	for (i = 0; i < payload_len/sizeof(uint32_t); i++)
-		fc_host_post_event(phba->host, fc_get_event_number(),
+		fc_host_post_event(shost, fc_get_event_number(),
 			FCH_EVT_RSCN, lp[i]);
 
 	/* If we are about to begin discovery, just ACC the RSCN.
 	 * Discovery processing will satisfy it.
 	 */
-	if (phba->hba_state <= LPFC_NS_QRY) {
-		lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL,
+	if (vport->port_state <= LPFC_NS_QRY) {
+		lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL,
 								newnode);
 		return 0;
 	}
@@ -2522,13 +2509,13 @@
 	/* If we are already processing an RSCN, save the received
 	 * RSCN payload buffer, cmdiocb->context2 to process later.
 	 */
-	if (phba->fc_flag & (FC_RSCN_MODE | FC_NDISC_ACTIVE)) {
-		if ((phba->fc_rscn_id_cnt < FC_MAX_HOLD_RSCN) &&
-		    !(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);
-			phba->fc_rscn_id_list[phba->fc_rscn_id_cnt++] = pcmd;
+	if (vport->fc_flag & (FC_RSCN_MODE | FC_NDISC_ACTIVE)) {
+		if ((vport->fc_rscn_id_cnt < FC_MAX_HOLD_RSCN) &&
+		    !(vport->fc_flag & FC_RSCN_DISCOVERY)) {
+			spin_lock_irq(shost->host_lock);
+			vport->fc_flag |= FC_RSCN_MODE;
+			spin_unlock_irq(shost->host_lock);
+			vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd;
 
 			/* If we zero, cmdiocb->context2, the calling
 			 * routine will not try to free it.
@@ -2539,54 +2526,59 @@
 			lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
 					"%d:0235 Deferred RSCN "
 					"Data: x%x x%x x%x\n",
-					phba->brd_no, phba->fc_rscn_id_cnt,
-					phba->fc_flag, phba->hba_state);
+					phba->brd_no, vport->fc_rscn_id_cnt,
+					vport->fc_flag,
+					vport->port_state);
 		} else {
-			spin_lock_irq(phba->host->host_lock);
-			phba->fc_flag |= FC_RSCN_DISCOVERY;
-			spin_unlock_irq(phba->host->host_lock);
+			spin_lock_irq(shost->host_lock);
+			vport->fc_flag |= FC_RSCN_DISCOVERY;
+			spin_unlock_irq(shost->host_lock);
 			/* ReDiscovery RSCN */
 			lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
 					"%d:0234 ReDiscovery RSCN "
 					"Data: x%x x%x x%x\n",
-					phba->brd_no, phba->fc_rscn_id_cnt,
-					phba->fc_flag, phba->hba_state);
+					phba->brd_no, vport->fc_rscn_id_cnt,
+					vport->fc_flag,
+					vport->port_state);
 		}
 		/* Send back ACC */
-		lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL,
+		lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL,
 								newnode);
 
 		/* send RECOVERY event for ALL nodes that match RSCN payload */
-		lpfc_rscn_recovery_check(phba);
+		lpfc_rscn_recovery_check(vport);
 		return 0;
 	}
 
-	phba->fc_flag |= FC_RSCN_MODE;
-	phba->fc_rscn_id_list[phba->fc_rscn_id_cnt++] = pcmd;
+	spin_lock_irq(shost->host_lock);
+	vport->fc_flag |= FC_RSCN_MODE;
+	spin_unlock_irq(shost->host_lock);
+	vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd;
 	/*
 	 * If we zero, cmdiocb->context2, the calling routine will
 	 * not try to free it.
 	 */
 	cmdiocb->context2 = NULL;
 
-	lpfc_set_disctmo(phba);
+	lpfc_set_disctmo(vport);
 
 	/* Send back ACC */
-	lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, newnode);
+	lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, newnode);
 
 	/* send RECOVERY event for ALL nodes that match RSCN payload */
-	lpfc_rscn_recovery_check(phba);
+	lpfc_rscn_recovery_check(vport);
 
-	return lpfc_els_handle_rscn(phba);
+	return lpfc_els_handle_rscn(vport);
 }
 
 int
-lpfc_els_handle_rscn(struct lpfc_hba * phba)
+lpfc_els_handle_rscn(struct lpfc_vport *vport)
 {
 	struct lpfc_nodelist *ndlp;
+	struct lpfc_hba *phba = vport->phba;
 
 	/* Start timer for RSCN processing */
-	lpfc_set_disctmo(phba);
+	lpfc_set_disctmo(vport);
 
 	/* RSCN processed */
 	lpfc_printf_log(phba,
@@ -2594,53 +2586,53 @@
 			LOG_DISCOVERY,
 			"%d:0215 RSCN processed Data: x%x x%x x%x x%x\n",
 			phba->brd_no,
-			phba->fc_flag, 0, phba->fc_rscn_id_cnt,
-			phba->hba_state);
+			vport->fc_flag, 0, vport->fc_rscn_id_cnt,
+			vport->port_state);
 
 	/* To process RSCN, first compare RSCN data with NameServer */
-	phba->fc_ns_retry = 0;
-	ndlp = lpfc_findnode_did(phba, NameServer_DID);
+	vport->fc_ns_retry = 0;
+	ndlp = lpfc_findnode_did(vport, NameServer_DID);
 	if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
 		/* Good ndlp, issue CT Request to NameServer */
-		if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) {
+		if (lpfc_ns_cmd(vport, ndlp, SLI_CTNS_GID_FT) == 0)
 			/* Wait for NameServer query cmpl before we can
 			   continue */
 			return 1;
-		}
 	} else {
 		/* If login to NameServer does not exist, issue one */
 		/* Good status, issue PLOGI to NameServer */
-		ndlp = lpfc_findnode_did(phba, NameServer_DID);
-		if (ndlp) {
+		ndlp = lpfc_findnode_did(vport, NameServer_DID);
+		if (ndlp)
 			/* Wait for NameServer login cmpl before we can
 			   continue */
 			return 1;
-		}
+
 		ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
 		if (!ndlp) {
-			lpfc_els_flush_rscn(phba);
+			lpfc_els_flush_rscn(vport);
 			return 0;
 		} else {
-			lpfc_nlp_init(phba, ndlp, NameServer_DID);
+			lpfc_nlp_init(vport, ndlp, NameServer_DID);
 			ndlp->nlp_type |= NLP_FABRIC;
 			ndlp->nlp_prev_state = ndlp->nlp_state;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE);
-			lpfc_issue_els_plogi(phba, NameServer_DID, 0);
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
+			lpfc_issue_els_plogi(vport, NameServer_DID, 0);
 			/* Wait for NameServer login cmpl before we can
 			   continue */
 			return 1;
 		}
 	}
 
-	lpfc_els_flush_rscn(phba);
+	lpfc_els_flush_rscn(vport);
 	return 0;
 }
 
 static int
-lpfc_els_rcv_flogi(struct lpfc_hba * phba,
-		   struct lpfc_iocbq * cmdiocb,
-		   struct lpfc_nodelist * ndlp, uint8_t newnode)
+lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+		   struct lpfc_nodelist *ndlp, uint8_t newnode)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
 	struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
 	uint32_t *lp = (uint32_t *) pcmd->virt;
 	IOCB_t *icmd = &cmdiocb->iocb;
@@ -2655,7 +2647,7 @@
 
 	/* FLOGI received */
 
-	lpfc_set_disctmo(phba);
+	lpfc_set_disctmo(vport);
 
 	if (phba->fc_topology == TOPOLOGY_LOOP) {
 		/* We should never receive a FLOGI in loop mode, ignore it */
@@ -2672,19 +2664,19 @@
 
 	did = Fabric_DID;
 
-	if ((lpfc_check_sparm(phba, ndlp, sp, CLASS3))) {
+	if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3))) {
 		/* For a FLOGI we accept, then if our portname is greater
 		 * then the remote portname we initiate Nport login.
 		 */
 
-		rc = memcmp(&phba->fc_portname, &sp->portName,
+		rc = memcmp(&vport->fc_portname, &sp->portName,
 			    sizeof (struct lpfc_name));
 
 		if (!rc) {
-			if ((mbox = mempool_alloc(phba->mbox_mem_pool,
-						  GFP_KERNEL)) == 0) {
+			mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+			if (!mbox)
 				return 1;
-			}
+
 			lpfc_linkdown(phba);
 			lpfc_init_link(phba, mbox,
 				       phba->cfg_topology,
@@ -2699,31 +2691,33 @@
 			}
 			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);
+			spin_lock_irq(shost->host_lock);
+			vport->fc_flag |= FC_PT2PT_PLOGI;
+			spin_unlock_irq(shost->host_lock);
 		}
-		phba->fc_flag |= FC_PT2PT;
-		phba->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
+		spin_lock_irq(shost->host_lock);
+		vport->fc_flag |= FC_PT2PT;
+		vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
+		spin_unlock_irq(shost->host_lock);
 	} else {
 		/* Reject this request because invalid parameters */
 		stat.un.b.lsRjtRsvd0 = 0;
 		stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
 		stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
 		stat.un.b.vendorUnique = 0;
-		lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
+		lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp);
 		return 1;
 	}
 
 	/* Send back ACC */
-	lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode);
+	lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode);
 
 	return 0;
 }
 
 static int
-lpfc_els_rcv_rnid(struct lpfc_hba * phba,
-		  struct lpfc_iocbq * cmdiocb, struct lpfc_nodelist * ndlp)
+lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+		  struct lpfc_nodelist *ndlp)
 {
 	struct lpfc_dmabuf *pcmd;
 	uint32_t *lp;
@@ -2746,7 +2740,7 @@
 	case 0:
 	case RNID_TOPOLOGY_DISC:
 		/* Send back ACC */
-		lpfc_els_rsp_rnid_acc(phba, rn->Format, cmdiocb, ndlp);
+		lpfc_els_rsp_rnid_acc(vport, rn->Format, cmdiocb, ndlp);
 		break;
 	default:
 		/* Reject this request because format not supported */
@@ -2754,14 +2748,14 @@
 		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);
+		lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp);
 	}
 	return 0;
 }
 
 static int
-lpfc_els_rcv_lirr(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
-		 struct lpfc_nodelist *ndlp)
+lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+		  struct lpfc_nodelist *ndlp)
 {
 	struct ls_rjt stat;
 
@@ -2770,15 +2764,15 @@
 	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);
+	lpfc_els_rsp_reject(vport, 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;
+	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
 	MAILBOX_t *mb;
 	IOCB_t *icmd;
 	RPS_RSP *rps_rsp;
@@ -2788,8 +2782,6 @@
 	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;
@@ -2804,8 +2796,9 @@
 
 	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);
+	elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
+				     lpfc_max_els_tries, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_ACC);
 	lpfc_nlp_put(ndlp);
 	if (!elsiocb)
 		return;
@@ -2822,7 +2815,7 @@
 		status = 0x10;
 	else
 		status = 0x8;
-	if (phba->fc_flag & FC_FABRIC)
+	if (phba->pport->fc_flag & FC_FABRIC)
 		status |= 0x4;
 
 	rps_rsp->rsvd1 = 0;
@@ -2852,9 +2845,10 @@
 }
 
 static int
-lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-		 struct lpfc_nodelist * ndlp)
+lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+		 struct lpfc_nodelist *ndlp)
 {
+	struct lpfc_hba *phba = vport->phba;
 	uint32_t *lp;
 	uint8_t flag;
 	LPFC_MBOXQ_t *mbox;
@@ -2868,7 +2862,7 @@
 		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);
+		lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp);
 	}
 
 	pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
@@ -2878,19 +2872,21 @@
 
 	if ((flag == 0) ||
 	    ((flag == 1) && (be32_to_cpu(rps->un.portNum) == 0)) ||
-	    ((flag == 2) && (memcmp(&rps->un.portName, &phba->fc_portname,
+	    ((flag == 2) && (memcmp(&rps->un.portName, &vport->fc_portname,
 			   sizeof (struct lpfc_name)) == 0))) {
-		if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC))) {
+
+		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
+		if (mbox) {
 			lpfc_read_lnk_stat(phba, mbox);
 			mbox->context1 =
 			    (void *)((unsigned long)cmdiocb->iocb.ulpContext);
 			mbox->context2 = lpfc_nlp_get(ndlp);
 			mbox->mbox_cmpl = lpfc_els_rsp_rps_acc;
 			if (lpfc_sli_issue_mbox (phba, mbox,
-			    (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) {
+			    (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED)
 				/* Mbox completion will send ELS Response */
 				return 0;
-			}
+
 			lpfc_nlp_put(ndlp);
 			mempool_free(mbox, phba->mbox_mem_pool);
 		}
@@ -2899,27 +2895,25 @@
 	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);
+	lpfc_els_rsp_reject(vport, 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)
+lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize,
+		     struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
 {
-	IOCB_t *icmd;
-	IOCB_t *oldcmd;
+	struct lpfc_hba *phba = vport->phba;
+	IOCB_t *icmd, *oldcmd;
 	RPL_RSP rpl_rsp;
 	struct lpfc_iocbq *elsiocb;
-	struct lpfc_sli_ring *pring;
-	struct lpfc_sli *psli;
+	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
 	uint8_t *pcmd;
 
-	psli = &phba->sli;
-	pring = &psli->ring[LPFC_ELS_RING];	/* ELS ring */
+	elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_ACC);
 
-	elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
-					ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
 	if (!elsiocb)
 		return 1;
 
@@ -2937,8 +2931,8 @@
 	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,
+	rpl_rsp.port_num_blk.portID = be32_to_cpu(vport->fc_myDID);
+	memcpy(&rpl_rsp.port_num_blk.portName, &vport->fc_portname,
 	    sizeof(struct lpfc_name));
 
 	memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t));
@@ -2963,8 +2957,8 @@
 }
 
 static int
-lpfc_els_rcv_rpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-		 struct lpfc_nodelist * ndlp)
+lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+		 struct lpfc_nodelist *ndlp)
 {
 	struct lpfc_dmabuf *pcmd;
 	uint32_t *lp;
@@ -2979,7 +2973,7 @@
 		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);
+		lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp);
 	}
 
 	pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
@@ -2996,15 +2990,16 @@
 	} else {
 		cmdsize = sizeof(uint32_t) + maxsize * sizeof(uint32_t);
 	}
-	lpfc_els_rsp_rpl_acc(phba, cmdsize, cmdiocb, ndlp);
+	lpfc_els_rsp_rpl_acc(vport, cmdsize, cmdiocb, ndlp);
 
 	return 0;
 }
 
 static int
-lpfc_els_rcv_farp(struct lpfc_hba * phba,
-		  struct lpfc_iocbq * cmdiocb, struct lpfc_nodelist * ndlp)
+lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+		  struct lpfc_nodelist *ndlp)
 {
+	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_dmabuf *pcmd;
 	uint32_t *lp;
 	IOCB_t *icmd;
@@ -3034,14 +3029,14 @@
 	cnt = 0;
 	/* If this FARP command is searching for my portname */
 	if (fp->Mflags & FARP_MATCH_PORT) {
-		if (memcmp(&fp->RportName, &phba->fc_portname,
+		if (memcmp(&fp->RportName, &vport->fc_portname,
 			   sizeof (struct lpfc_name)) == 0)
 			cnt = 1;
 	}
 
 	/* If this FARP command is searching for my nodename */
 	if (fp->Mflags & FARP_MATCH_NODE) {
-		if (memcmp(&fp->RnodeName, &phba->fc_nodename,
+		if (memcmp(&fp->RnodeName, &vport->fc_nodename,
 			   sizeof (struct lpfc_name)) == 0)
 			cnt = 1;
 	}
@@ -3052,28 +3047,28 @@
 			/* Log back into the node before sending the FARP. */
 			if (fp->Rflags & FARP_REQUEST_PLOGI) {
 				ndlp->nlp_prev_state = ndlp->nlp_state;
-				lpfc_nlp_set_state(phba, ndlp,
+				lpfc_nlp_set_state(vport, ndlp,
 						   NLP_STE_PLOGI_ISSUE);
-				lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0);
+				lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
 			}
 
 			/* Send a FARP response to that node */
-			if (fp->Rflags & FARP_REQUEST_FARPR) {
-				lpfc_issue_els_farpr(phba, did, 0);
-			}
+			if (fp->Rflags & FARP_REQUEST_FARPR)
+				lpfc_issue_els_farpr(vport, did, 0);
 		}
 	}
 	return 0;
 }
 
 static int
-lpfc_els_rcv_farpr(struct lpfc_hba * phba,
-		   struct lpfc_iocbq * cmdiocb, struct lpfc_nodelist * ndlp)
+lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+		   struct lpfc_nodelist  *ndlp)
 {
 	struct lpfc_dmabuf *pcmd;
 	uint32_t *lp;
 	IOCB_t *icmd;
 	uint32_t cmd, did;
+	struct lpfc_hba *phba = vport->phba;
 
 	icmd = &cmdiocb->iocb;
 	did = icmd->un.elsreq64.remoteID;
@@ -3089,14 +3084,14 @@
 			 phba->brd_no, did);
 
 	/* ACCEPT the Farp resp request */
-	lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+	lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
 
 	return 0;
 }
 
 static int
-lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-		 struct lpfc_nodelist * fan_ndlp)
+lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+		 struct lpfc_nodelist *fan_ndlp)
 {
 	struct lpfc_dmabuf *pcmd;
 	uint32_t *lp;
@@ -3104,6 +3099,7 @@
 	uint32_t cmd, did;
 	FAN *fp;
 	struct lpfc_nodelist *ndlp, *next_ndlp;
+	struct lpfc_hba *phba = vport->phba;
 
 	/* FAN received */
 	lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0265 FAN received\n",
@@ -3119,7 +3115,7 @@
 
 	/* FAN received; Fan does not have a reply sequence */
 
-	if (phba->hba_state == LPFC_LOCAL_CFG_LINK) {
+	if (phba->pport->port_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,
@@ -3130,7 +3126,7 @@
 			 */
 
 			list_for_each_entry_safe(ndlp, next_ndlp,
-						 &phba->fc_nodes, nlp_listp) {
+						 &vport->fc_nodes, nlp_listp) {
 				if (ndlp->nlp_state != NLP_STE_NPR_NODE)
 					continue;
 				if (ndlp->nlp_type & NLP_FABRIC) {
@@ -3138,24 +3134,24 @@
 					 * Clean up old Fabric, Nameserver and
 					 * other NLP_FABRIC logins
 					 */
-					lpfc_drop_node(phba, ndlp);
+					lpfc_drop_node(vport, ndlp);
 				} 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);
+					lpfc_unreg_rpi(vport, ndlp);
 				}
 			}
 
-			phba->hba_state = LPFC_FLOGI;
-			lpfc_set_disctmo(phba);
-			lpfc_initial_flogi(phba);
+			vport->port_state = LPFC_FLOGI;
+			lpfc_set_disctmo(vport);
+			lpfc_initial_flogi(vport);
 			return 0;
 		}
 		/* Discovery not needed,
 		 * move the nodes to their original state.
 		 */
-		list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes,
+		list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
 					 nlp_listp) {
 			if (ndlp->nlp_state != NLP_STE_NPR_NODE)
 				continue;
@@ -3163,13 +3159,13 @@
 			switch (ndlp->nlp_prev_state) {
 			case NLP_STE_UNMAPPED_NODE:
 				ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
-				lpfc_nlp_set_state(phba, ndlp,
+				lpfc_nlp_set_state(vport, ndlp,
 						   NLP_STE_UNMAPPED_NODE);
 				break;
 
 			case NLP_STE_MAPPED_NODE:
 				ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
-				lpfc_nlp_set_state(phba, ndlp,
+				lpfc_nlp_set_state(vport, ndlp,
 						   NLP_STE_MAPPED_NODE);
 				break;
 
@@ -3179,7 +3175,7 @@
 		}
 
 		/* Start discovery - this should just do CLEAR_LA */
-		lpfc_disc_start(phba);
+		lpfc_disc_start(vport);
 	}
 	return 0;
 }
@@ -3187,42 +3183,37 @@
 void
 lpfc_els_timeout(unsigned long ptr)
 {
-	struct lpfc_hba *phba;
+	struct lpfc_vport *vport = (struct lpfc_vport *) ptr;
+	struct lpfc_hba   *phba = vport->phba;
 	unsigned long iflag;
 
-	phba = (struct lpfc_hba *)ptr;
-	if (phba == 0)
-		return;
-	spin_lock_irqsave(phba->host->host_lock, iflag);
-	if (!(phba->work_hba_events & WORKER_ELS_TMO)) {
-		phba->work_hba_events |= WORKER_ELS_TMO;
+	spin_lock_irqsave(&vport->work_port_lock, iflag);
+	if ((vport->work_port_events & WORKER_ELS_TMO) == 0) {
+		vport->work_port_events |= WORKER_ELS_TMO;
 		if (phba->work_wait)
 			wake_up(phba->work_wait);
 	}
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
+	spin_unlock_irqrestore(&vport->work_port_lock, iflag);
 	return;
 }
 
 void
-lpfc_els_timeout_handler(struct lpfc_hba *phba)
+lpfc_els_timeout_handler(struct lpfc_vport *vport)
 {
+	struct lpfc_hba  *phba = vport->phba;
 	struct lpfc_sli_ring *pring;
 	struct lpfc_iocbq *tmp_iocb, *piocb;
 	IOCB_t *cmd = NULL;
 	struct lpfc_dmabuf *pcmd;
-	uint32_t *elscmd;
-	uint32_t els_command=0;
+	uint32_t els_command = 0;
 	uint32_t timeout;
-	uint32_t remote_ID;
+	uint32_t remote_ID = 0xffffffff;
 
-	if (phba == 0)
-		return;
-	spin_lock_irq(phba->host->host_lock);
 	/* If the timer is already canceled do nothing */
-	if (!(phba->work_hba_events & WORKER_ELS_TMO)) {
-		spin_unlock_irq(phba->host->host_lock);
+	if ((vport->work_port_events & WORKER_ELS_TMO) == 0) {
 		return;
 	}
+	spin_lock_irq(&phba->hbalock);
 	timeout = (uint32_t)(phba->fc_ratov << 1);
 
 	pring = &phba->sli.ring[LPFC_ELS_RING];
@@ -3230,16 +3221,17 @@
 	list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
 		cmd = &piocb->iocb;
 
-		if ((piocb->iocb_flag & LPFC_IO_LIBDFC) ||
-			(piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN) ||
-			(piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)) {
+		if ((piocb->iocb_flag & LPFC_IO_LIBDFC) != 0 ||
+		    piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN ||
+		    piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
 			continue;
-		}
+
+		if (piocb->vport != vport)
+			continue;
+
 		pcmd = (struct lpfc_dmabuf *) piocb->context2;
-		if (pcmd) {
-			elscmd = (uint32_t *) (pcmd->virt);
-			els_command = *elscmd;
-		}
+		if (pcmd)
+			els_command = *(uint32_t *) (pcmd->virt);
 
 		if ((els_command == ELS_CMD_FARP)
 		    || (els_command == ELS_CMD_FARPR)) {
@@ -3255,12 +3247,14 @@
 			continue;
 		}
 
-		if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) {
-			struct lpfc_nodelist *ndlp;
-			ndlp = __lpfc_findnode_rpi(phba, cmd->ulpContext);
-			remote_ID = ndlp->nlp_DID;
-		} else {
+		remote_ID = 0xffffffff;
+		if (cmd->ulpCommand != CMD_GEN_REQUEST64_CR)
 			remote_ID = cmd->un.elsreq64.remoteID;
+		else {
+			struct lpfc_nodelist *ndlp;
+			ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext);
+			if (ndlp)
+				remote_ID = ndlp->nlp_DID;
 		}
 
 		lpfc_printf_log(phba,
@@ -3272,21 +3266,22 @@
 
 		lpfc_sli_issue_abort_iotag(phba, pring, piocb);
 	}
-	if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt)
-		mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout);
+	spin_unlock_irq(&phba->hbalock);
 
-	spin_unlock_irq(phba->host->host_lock);
+	if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt)
+		mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout);
 }
 
 void
-lpfc_els_flush_cmd(struct lpfc_hba *phba)
+lpfc_els_flush_cmd(struct lpfc_vport *vport)
 {
 	LIST_HEAD(completions);
+	struct lpfc_hba  *phba = vport->phba;
 	struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
 	struct lpfc_iocbq *tmp_iocb, *piocb;
 	IOCB_t *cmd = NULL;
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) {
 		cmd = &piocb->iocb;
 
@@ -3301,61 +3296,63 @@
 		    cmd->ulpCommand == CMD_ABORT_XRI_CN)
 			continue;
 
+		if (piocb->vport != vport)
+			continue;
+
 		list_move_tail(&piocb->list, &completions);
 		pring->txq_cnt--;
-
 	}
 
 	list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
-		cmd = &piocb->iocb;
-
 		if (piocb->iocb_flag & LPFC_IO_LIBDFC) {
 			continue;
 		}
 
+		if (piocb->vport != vport)
+			continue;
+
 		lpfc_sli_issue_abort_iotag(phba, pring, piocb);
 	}
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
-	while(!list_empty(&completions)) {
+	while (!list_empty(&completions)) {
 		piocb = list_get_first(&completions, struct lpfc_iocbq, list);
 		cmd = &piocb->iocb;
 		list_del(&piocb->list);
 
-		if (piocb->iocb_cmpl) {
+		if (!piocb->iocb_cmpl)
+			lpfc_sli_release_iocbq(phba, piocb);
+		else {
 			cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
 			cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
 			(piocb->iocb_cmpl) (phba, piocb, piocb);
-		} else
-			lpfc_sli_release_iocbq(phba, piocb);
+		}
 	}
 
 	return;
 }
 
 void
-lpfc_els_unsol_event(struct lpfc_hba * phba,
-		     struct lpfc_sli_ring * pring, struct lpfc_iocbq * elsiocb)
+lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+		     struct lpfc_iocbq *elsiocb)
 {
 	struct lpfc_sli *psli;
 	struct lpfc_nodelist *ndlp;
-	struct lpfc_dmabuf *mp;
+	struct lpfc_dmabuf *mp = NULL;
 	uint32_t *lp;
 	IOCB_t *icmd;
 	struct ls_rjt stat;
-	uint32_t cmd;
-	uint32_t did;
-	uint32_t newnode;
+	uint32_t cmd, did, newnode, rjt_err = 0;
 	uint32_t drop_cmd = 0;	/* by default do NOT drop received cmd */
-	uint32_t rjt_err = 0;
+	struct lpfc_vport *vport = NULL;
 
 	psli = &phba->sli;
 	icmd = &elsiocb->iocb;
 
 	if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
 		((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) {
-		/* Not enough posted buffers; Try posting more buffers */
 		phba->fc_stat.NoRcvBuf++;
+		/* Not enough posted buffers; Try posting more buffers */
 		lpfc_post_buffer(phba, pring, 0, 1);
 		return;
 	}
@@ -3366,17 +3363,17 @@
 	if (icmd->ulpBdeCount == 0)
 		return;
 
-	/* type of ELS cmd is first 32bit word in packet */
-	mp = lpfc_sli_ringpostbuf_get(phba, pring, getPaddr(icmd->un.
-							    cont64[0].
-							    addrHigh,
-							    icmd->un.
-							    cont64[0].addrLow));
+		/* type of ELS cmd is first 32bit word in packet */
+	mp = lpfc_sli_ringpostbuf_get(phba, pring,
+				      getPaddr(icmd->un.cont64[0].addrHigh,
+					       icmd->un.cont64[0].addrLow));
 	if (mp == 0) {
 		drop_cmd = 1;
 		goto dropit;
 	}
 
+	vport = phba->pport;
+
 	newnode = 0;
 	lp = (uint32_t *) mp->virt;
 	cmd = *lp++;
@@ -3390,7 +3387,7 @@
 	}
 
 	/* Check to see if link went down during discovery */
-	if (lpfc_els_chk_latt(phba)) {
+	if (lpfc_els_chk_latt(vport)) {
 		lpfc_mbuf_free(phba, mp->virt, mp->phys);
 		kfree(mp);
 		drop_cmd = 1;
@@ -3398,7 +3395,7 @@
 	}
 
 	did = icmd->un.rcvels.remoteID;
-	ndlp = lpfc_findnode_did(phba, did);
+	ndlp = lpfc_findnode_did(vport, did);
 	if (!ndlp) {
 		/* Cannot find existing Fabric ndlp, so allocate a new one */
 		ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
@@ -3409,12 +3406,12 @@
 			goto dropit;
 		}
 
-		lpfc_nlp_init(phba, ndlp, did);
+		lpfc_nlp_init(vport, ndlp, did);
 		newnode = 1;
 		if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) {
 			ndlp->nlp_type |= NLP_FABRIC;
 		}
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE);
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
 	}
 
 	phba->fc_stat.elsRcvFrame++;
@@ -3422,6 +3419,7 @@
 		lpfc_nlp_put(elsiocb->context1);
 	elsiocb->context1 = lpfc_nlp_get(ndlp);
 	elsiocb->context2 = mp;
+	elsiocb->vport = vport;
 
 	if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) {
 		cmd &= ELS_CMD_MASK;
@@ -3429,105 +3427,109 @@
 	/* ELS command <elsCmd> received from NPORT <did> */
 	lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
 			"%d:0112 ELS command x%x received from NPORT x%x "
-			"Data: x%x\n", phba->brd_no, cmd, did, phba->hba_state);
+			"Data: x%x\n", phba->brd_no, cmd, did,
+			 vport->port_state);
 
 	switch (cmd) {
 	case ELS_CMD_PLOGI:
 		phba->fc_stat.elsRcvPLOGI++;
-		if (phba->hba_state < LPFC_DISC_AUTH) {
+		if (vport->port_state < LPFC_DISC_AUTH) {
 			rjt_err = 1;
 			break;
 		}
 		ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp);
-		lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI);
+		lpfc_disc_state_machine(vport, ndlp, elsiocb,
+					NLP_EVT_RCV_PLOGI);
 		break;
 	case ELS_CMD_FLOGI:
 		phba->fc_stat.elsRcvFLOGI++;
-		lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode);
+		lpfc_els_rcv_flogi(vport, elsiocb, ndlp, newnode);
 		if (newnode)
-			lpfc_drop_node(phba, ndlp);
+			lpfc_drop_node(vport, ndlp);
 		break;
 	case ELS_CMD_LOGO:
 		phba->fc_stat.elsRcvLOGO++;
-		if (phba->hba_state < LPFC_DISC_AUTH) {
+		if (vport->port_state < LPFC_DISC_AUTH) {
 			rjt_err = 1;
 			break;
 		}
-		lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_LOGO);
+		lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_LOGO);
 		break;
 	case ELS_CMD_PRLO:
 		phba->fc_stat.elsRcvPRLO++;
-		if (phba->hba_state < LPFC_DISC_AUTH) {
+		if (vport->port_state < LPFC_DISC_AUTH) {
 			rjt_err = 1;
 			break;
 		}
-		lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PRLO);
+		lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLO);
 		break;
 	case ELS_CMD_RSCN:
 		phba->fc_stat.elsRcvRSCN++;
-		lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode);
+		lpfc_els_rcv_rscn(vport, elsiocb, ndlp, newnode);
 		if (newnode)
-			lpfc_drop_node(phba, ndlp);
+			lpfc_drop_node(vport, ndlp);
 		break;
 	case ELS_CMD_ADISC:
 		phba->fc_stat.elsRcvADISC++;
-		if (phba->hba_state < LPFC_DISC_AUTH) {
+		if (vport->port_state < LPFC_DISC_AUTH) {
 			rjt_err = 1;
 			break;
 		}
-		lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_ADISC);
+		lpfc_disc_state_machine(vport, ndlp, elsiocb,
+					NLP_EVT_RCV_ADISC);
 		break;
 	case ELS_CMD_PDISC:
 		phba->fc_stat.elsRcvPDISC++;
-		if (phba->hba_state < LPFC_DISC_AUTH) {
+		if (vport->port_state < LPFC_DISC_AUTH) {
 			rjt_err = 1;
 			break;
 		}
-		lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PDISC);
+		lpfc_disc_state_machine(vport, ndlp, elsiocb,
+					NLP_EVT_RCV_PDISC);
 		break;
 	case ELS_CMD_FARPR:
 		phba->fc_stat.elsRcvFARPR++;
-		lpfc_els_rcv_farpr(phba, elsiocb, ndlp);
+		lpfc_els_rcv_farpr(vport, elsiocb, ndlp);
 		break;
 	case ELS_CMD_FARP:
 		phba->fc_stat.elsRcvFARP++;
-		lpfc_els_rcv_farp(phba, elsiocb, ndlp);
+		lpfc_els_rcv_farp(vport, elsiocb, ndlp);
 		break;
 	case ELS_CMD_FAN:
 		phba->fc_stat.elsRcvFAN++;
-		lpfc_els_rcv_fan(phba, elsiocb, ndlp);
+		lpfc_els_rcv_fan(vport, elsiocb, ndlp);
 		break;
 	case ELS_CMD_PRLI:
 		phba->fc_stat.elsRcvPRLI++;
-		if (phba->hba_state < LPFC_DISC_AUTH) {
+		if (vport->port_state < LPFC_DISC_AUTH) {
 			rjt_err = 1;
 			break;
 		}
-		lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PRLI);
+		lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLI);
 		break;
 	case ELS_CMD_LIRR:
 		phba->fc_stat.elsRcvLIRR++;
-		lpfc_els_rcv_lirr(phba, elsiocb, ndlp);
+		lpfc_els_rcv_lirr(vport, elsiocb, ndlp);
 		if (newnode)
-			lpfc_drop_node(phba, ndlp);
+			lpfc_drop_node(vport, ndlp);
 		break;
 	case ELS_CMD_RPS:
 		phba->fc_stat.elsRcvRPS++;
-		lpfc_els_rcv_rps(phba, elsiocb, ndlp);
+		lpfc_els_rcv_rps(vport, elsiocb, ndlp);
 		if (newnode)
-			lpfc_drop_node(phba, ndlp);
+			lpfc_drop_node(vport, ndlp);
 		break;
 	case ELS_CMD_RPL:
 		phba->fc_stat.elsRcvRPL++;
-		lpfc_els_rcv_rpl(phba, elsiocb, ndlp);
+		lpfc_els_rcv_rpl(vport, elsiocb, ndlp);
 		if (newnode)
-			lpfc_drop_node(phba, ndlp);
+			lpfc_drop_node(vport, ndlp);
 		break;
 	case ELS_CMD_RNID:
 		phba->fc_stat.elsRcvRNID++;
-		lpfc_els_rcv_rnid(phba, elsiocb, ndlp);
+		lpfc_els_rcv_rnid(vport, elsiocb, ndlp);
 		if (newnode)
-			lpfc_drop_node(phba, ndlp);
+			lpfc_drop_node(vport, ndlp);
 		break;
 	default:
 		/* Unsupported ELS command, reject */
@@ -3538,7 +3540,7 @@
 				"%d:0115 Unknown ELS command x%x received from "
 				"NPORT x%x\n", phba->brd_no, cmd, did);
 		if (newnode)
-			lpfc_drop_node(phba, ndlp);
+			lpfc_drop_node(vport, ndlp);
 		break;
 	}
 
@@ -3548,7 +3550,7 @@
 		stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
 		stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
 		stat.un.b.vendorUnique = 0;
-		lpfc_els_rsp_reject(phba, stat.un.lsRjtError, elsiocb, ndlp);
+		lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp);
 	}
 
 	lpfc_nlp_put(elsiocb->context1);
@@ -3567,5 +3569,4 @@
 				icmd->ulpTimeout);
 		phba->fc_stat.elsRcvDrop++;
 	}
-	return;
 }