diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 82e8f90c46178472c3cb24243250dea996cdcd46..8d718964f2813c3ec416b832290495f63754c23c 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -19,6 +19,8 @@
  * included with this package.                                     *
  *******************************************************************/
 
+#include <scsi/scsi_host.h>
+
 struct lpfc_sli2_slim;
 
 
@@ -165,48 +167,143 @@ struct lpfc_sysfs_mbox {
 	struct lpfcMboxq *    mbox;
 };
 
+struct lpfc_hba;
+
+enum discovery_state {
+	LPFC_STATE_UNKNOWN   =  0,    /* HBA state is unknown */
+	LPFC_LOCAL_CFG_LINK  =  6,    /* local NPORT Id configured */
+	LPFC_FLOGI           =  7,    /* FLOGI sent to Fabric */
+	LPFC_FABRIC_CFG_LINK =  8,    /* Fabric assigned NPORT Id
+				       * configured */
+	LPFC_NS_REG          =  9,    /* Register with NameServer */
+	LPFC_NS_QRY          =  10,   /* Query NameServer for NPort ID list */
+	LPFC_BUILD_DISC_LIST =  11,   /* Build ADISC and PLOGI lists for
+				       * device authentication / discovery */
+	LPFC_DISC_AUTH       =  12,   /* Processing ADISC list */
+	LPFC_VPORT_READY     =  32,
+};
+
+enum hba_state {
+	LPFC_LINK_UNKNOWN    =   0,   /* HBA state is unknown */
+	LPFC_WARM_START      =   1,   /* HBA state after selective reset */
+	LPFC_INIT_START      =   2,   /* Initial state after board reset */
+	LPFC_INIT_MBX_CMDS   =   3,   /* Initialize HBA with mbox commands */
+	LPFC_LINK_DOWN       =   4,   /* HBA initialized, link is down */
+	LPFC_LINK_UP         =   5,   /* Link is up  - issue READ_LA */
+	LPFC_CLEAR_LA        =  13,   /* authentication cmplt - issue
+				       * CLEAR_LA */
+	LPFC_HBA_ERROR       =  -1
+};
+
+struct lpfc_vport {
+	struct list_head listentry;
+	struct lpfc_hba *phba;
+	uint8_t port_type;
+#define LPFC_PHYSICAL_PORT 1
+#define LPFC_NPIV_PORT  2
+#define LPFC_FABRIC_PORT 3
+	enum discovery_state port_state;
+
+
+	uint32_t fc_flag;	/* FC flags */
+/* Several of these flags are HBA centric and should be moved to
+ * phba->link_flag (e.g. FC_PTP, FC_PUBLIC_LOOP)
+ */
+#define FC_PT2PT                0x1	/* pt2pt with no fabric */
+#define FC_PT2PT_PLOGI          0x2	/* pt2pt initiate PLOGI */
+#define FC_DISC_TMO             0x4	/* Discovery timer running */
+#define FC_PUBLIC_LOOP          0x8	/* Public loop */
+#define FC_LBIT                 0x10	/* LOGIN bit in loopinit set */
+#define FC_RSCN_MODE            0x20	/* RSCN cmd rcv'ed */
+#define FC_NLP_MORE             0x40	/* More node to process in node tbl */
+#define FC_OFFLINE_MODE         0x80	/* Interface is offline for diag */
+#define FC_FABRIC               0x100	/* We are fabric attached */
+#define FC_ESTABLISH_LINK       0x200	/* Reestablish Link */
+#define FC_RSCN_DISCOVERY       0x400	/* Authenticate all devices after RSCN*/
+#define FC_SCSI_SCAN_TMO        0x4000	/* scsi scan timer running */
+#define FC_ABORT_DISCOVERY      0x8000	/* we want to abort discovery */
+#define FC_NDISC_ACTIVE         0x10000	/* NPort discovery active */
+#define FC_BYPASSED_MODE        0x20000	/* NPort is in bypassed mode */
+
+	struct list_head fc_nodes;
+
+	/* Keep counters for the number of entries in each list. */
+	uint16_t fc_plogi_cnt;
+	uint16_t fc_adisc_cnt;
+	uint16_t fc_reglogin_cnt;
+	uint16_t fc_prli_cnt;
+	uint16_t fc_unmap_cnt;
+	uint16_t fc_map_cnt;
+	uint16_t fc_npr_cnt;
+	uint16_t fc_unused_cnt;
+	struct serv_parm fc_sparam;	/* buffer for our service parameters */
+
+	uint32_t fc_myDID;	/* fibre channel S_ID */
+	uint32_t fc_prevDID;	/* previous fibre channel S_ID */
+
+	int32_t stopped;   /* HBA has not been restarted since last ERATT */
+	uint8_t fc_linkspeed;	/* Link speed after last READ_LA */
+
+	uint32_t num_disc_nodes;	/*in addition to hba_state */
+
+	uint32_t fc_nlp_cnt;	/* outstanding NODELIST requests */
+	uint32_t fc_rscn_id_cnt;	/* count of RSCNs payloads in list */
+	struct lpfc_dmabuf *fc_rscn_id_list[FC_MAX_HOLD_RSCN];
+	struct lpfc_name fc_nodename;	/* fc nodename */
+	struct lpfc_name fc_portname;	/* fc portname */
+
+	struct lpfc_work_evt disc_timeout_evt;
+
+	struct timer_list fc_disctmo;	/* Discovery rescue timer */
+	uint8_t fc_ns_retry;	/* retries for fabric nameserver */
+	uint32_t fc_prli_sent;	/* cntr for outstanding PRLIs */
+
+	spinlock_t work_port_lock;
+	uint32_t work_port_events; /* Timeout to be handled  */
+#define WORKER_DISC_TMO                0x1	/* Discovery timeout */
+#define WORKER_ELS_TMO                 0x2	/* ELS timeout */
+#define WORKER_MBOX_TMO                0x4	/* MBOX timeout */
+#define WORKER_FDMI_TMO                0x8	/* FDMI timeout */
+
+	struct timer_list fc_fdmitmo;
+	struct timer_list els_tmofunc;
+
+	int unreg_vpi_cmpl;
+
+	uint8_t load_flag;
+#define FC_LOADING		0x1	/* HBA in process of loading drvr */
+#define FC_UNLOADING		0x2	/* HBA in process of unloading drvr */
+
+};
+
 struct lpfc_hba {
 	struct lpfc_sli sli;
+
+	enum hba_state link_state;
+	uint32_t link_flag;	/* link state flags */
+#define LS_LOOPBACK_MODE        0x40000	/* NPort is in Loopback mode */
+					/* This flag is set while issuing */
+					/* INIT_LINK mailbox command */
+#define LS_IGNORE_ERATT         0x80000	/* intr handler should ignore ERATT */
+
+	uint32_t pgpOffset; /* PGP offset within host memory */
+
 	struct lpfc_sli2_slim *slim2p;
+	struct lpfc_dmabuf hbqslimp;
+
 	dma_addr_t slim2p_mapping;
+
+
 	uint16_t pci_cfg_value;
 
-	int32_t hba_state;
-
-#define LPFC_STATE_UNKNOWN        0    /* HBA state is unknown */
-#define LPFC_WARM_START           1    /* HBA state after selective reset */
-#define LPFC_INIT_START           2    /* Initial state after board reset */
-#define LPFC_INIT_MBX_CMDS        3    /* Initialize HBA with mbox commands */
-#define LPFC_LINK_DOWN            4    /* HBA initialized, link is down */
-#define LPFC_LINK_UP              5    /* Link is up  - issue READ_LA */
-#define LPFC_LOCAL_CFG_LINK       6    /* local NPORT Id configured */
-#define LPFC_FLOGI                7    /* FLOGI sent to Fabric */
-#define LPFC_FABRIC_CFG_LINK      8    /* Fabric assigned NPORT Id
-					   configured */
-#define LPFC_NS_REG               9	/* Register with NameServer */
-#define LPFC_NS_QRY               10	/* Query NameServer for NPort ID list */
-#define LPFC_BUILD_DISC_LIST      11	/* Build ADISC and PLOGI lists for
-					 * device authentication / discovery */
-#define LPFC_DISC_AUTH            12	/* Processing ADISC list */
-#define LPFC_CLEAR_LA             13	/* authentication cmplt - issue
-					   CLEAR_LA */
-#define LPFC_HBA_READY            32
-#define LPFC_HBA_ERROR            -1
 
-	int32_t stopped;   /* HBA has not been restarted since last ERATT */
 	uint8_t fc_linkspeed;	/* Link speed after last READ_LA */
 
 	uint32_t fc_eventTag;	/* event tag for link attention */
-	uint32_t fc_prli_sent;	/* cntr for outstanding PRLIs */
 
-	uint32_t num_disc_nodes;	/*in addition to hba_state */
 
 	struct timer_list fc_estabtmo;	/* link establishment timer */
-	struct timer_list fc_disctmo;	/* Discovery rescue timer */
-	struct timer_list fc_fdmitmo;	/* fdmi timer */
 	/* These fields used to be binfo */
-	struct lpfc_name fc_nodename;	/* fc nodename */
-	struct lpfc_name fc_portname;	/* fc portname */
 	uint32_t fc_pref_DID;	/* preferred D_ID */
 	uint8_t fc_pref_ALPA;	/* preferred AL_PA */
 	uint32_t fc_edtov;	/* E_D_TOV timer value */
@@ -216,61 +313,21 @@ struct lpfc_hba {
 	uint32_t fc_altov;	/* AL_TOV timer value */
 	uint32_t fc_crtov;	/* C_R_TOV timer value */
 	uint32_t fc_citov;	/* C_I_TOV timer value */
-	uint32_t fc_myDID;	/* fibre channel S_ID */
-	uint32_t fc_prevDID;	/* previous fibre channel S_ID */
 
-	struct serv_parm fc_sparam;	/* buffer for our service parameters */
 	struct serv_parm fc_fabparam;	/* fabric service parameters buffer */
 	uint8_t alpa_map[128];	/* AL_PA map from READ_LA */
 
-	uint8_t fc_ns_retry;	/* retries for fabric nameserver */
-	uint32_t fc_nlp_cnt;	/* outstanding NODELIST requests */
-	uint32_t fc_rscn_id_cnt;	/* count of RSCNs payloads in list */
-	struct lpfc_dmabuf *fc_rscn_id_list[FC_MAX_HOLD_RSCN];
 	uint32_t lmt;
-	uint32_t fc_flag;	/* FC flags */
-#define FC_PT2PT                0x1	/* pt2pt with no fabric */
-#define FC_PT2PT_PLOGI          0x2	/* pt2pt initiate PLOGI */
-#define FC_DISC_TMO             0x4	/* Discovery timer running */
-#define FC_PUBLIC_LOOP          0x8	/* Public loop */
-#define FC_LBIT                 0x10	/* LOGIN bit in loopinit set */
-#define FC_RSCN_MODE            0x20	/* RSCN cmd rcv'ed */
-#define FC_NLP_MORE             0x40	/* More node to process in node tbl */
-#define FC_OFFLINE_MODE         0x80	/* Interface is offline for diag */
-#define FC_FABRIC               0x100	/* We are fabric attached */
-#define FC_ESTABLISH_LINK       0x200	/* Reestablish Link */
-#define FC_RSCN_DISCOVERY       0x400	/* Authenticate all devices after RSCN*/
-#define FC_BLOCK_MGMT_IO        0x800   /* Don't allow mgmt mbx or iocb cmds */
-#define FC_LOADING		0x1000	/* HBA in process of loading drvr */
-#define FC_UNLOADING		0x2000	/* HBA in process of unloading drvr */
-#define FC_SCSI_SCAN_TMO        0x4000	/* scsi scan timer running */
-#define FC_ABORT_DISCOVERY      0x8000	/* we want to abort discovery */
-#define FC_NDISC_ACTIVE         0x10000	/* NPort discovery active */
-#define FC_BYPASSED_MODE        0x20000	/* NPort is in bypassed mode */
-#define FC_LOOPBACK_MODE        0x40000	/* NPort is in Loopback mode */
-					/* This flag is set while issuing */
-					/* INIT_LINK mailbox command */
-#define FC_IGNORE_ERATT         0x80000	/* intr handler should ignore ERATT */
 
 	uint32_t fc_topology;	/* link topology, from LINK INIT */
 
 	struct lpfc_stats fc_stat;
 
-	struct list_head fc_nodes;
-
-	/* Keep counters for the number of entries in each list. */
-	uint16_t fc_plogi_cnt;
-	uint16_t fc_adisc_cnt;
-	uint16_t fc_reglogin_cnt;
-	uint16_t fc_prli_cnt;
-	uint16_t fc_unmap_cnt;
-	uint16_t fc_map_cnt;
-	uint16_t fc_npr_cnt;
-	uint16_t fc_unused_cnt;
 	struct lpfc_nodelist fc_fcpnodev; /* nodelist entry for no device */
 	uint32_t nport_event_cnt;	/* timestamp for nlplist entry */
 
-	uint32_t wwnn[2];
+	uint8_t  wwnn[8];
+	uint8_t  wwpn[8];
 	uint32_t RandomData[7];
 
 	uint32_t cfg_log_verbose;
@@ -304,18 +361,12 @@ struct lpfc_hba {
 
 	lpfc_vpd_t vpd;		/* vital product data */
 
-	struct Scsi_Host *host;
 	struct pci_dev *pcidev;
 	struct list_head      work_list;
 	uint32_t              work_ha;      /* Host Attention Bits for WT */
 	uint32_t              work_ha_mask; /* HA Bits owned by WT        */
 	uint32_t              work_hs;      /* HS stored in case of ERRAT */
 	uint32_t              work_status[2]; /* Extra status from SLIM */
-	uint32_t              work_hba_events; /* Timeout to be handled  */
-#define WORKER_DISC_TMO                0x1	/* Discovery timeout */
-#define WORKER_ELS_TMO                 0x2	/* ELS timeout */
-#define WORKER_MBOX_TMO                0x4	/* MBOX timeout */
-#define WORKER_FDMI_TMO                0x8	/* FDMI timeout */
 
 	wait_queue_head_t    *work_wait;
 	struct task_struct   *worker_thread;
@@ -353,7 +404,6 @@ struct lpfc_hba {
 	uint8_t soft_wwn_enable;
 
 	struct timer_list fcp_poll_timer;
-	struct timer_list els_tmofunc;
 
 	/*
 	 * stat  counters
@@ -370,6 +420,7 @@ struct lpfc_hba {
 	uint32_t total_scsi_bufs;
 	struct list_head lpfc_iocb_list;
 	uint32_t total_iocbq_bufs;
+	spinlock_t hbalock;
 
 	/* pci_mem_pools */
 	struct pci_pool *lpfc_scsi_dma_buf_pool;
@@ -380,21 +431,33 @@ struct lpfc_hba {
 	mempool_t *nlp_mem_pool;
 
 	struct fc_host_statistics link_stats;
+	struct list_head port_list;
+	struct lpfc_vport *pport; /* physical lpfc_vport pointer */
 };
 
+static inline struct Scsi_Host *
+lpfc_shost_from_vport(struct lpfc_vport *vport)
+{
+	return container_of((void *) vport, struct Scsi_Host, hostdata[0]);
+}
+
 static inline void
-lpfc_set_loopback_flag(struct lpfc_hba *phba) {
+lpfc_set_loopback_flag(struct lpfc_hba *phba)
+{
 	if (phba->cfg_topology == FLAGS_LOCAL_LB)
-		phba->fc_flag |= FC_LOOPBACK_MODE;
+		phba->link_flag |= LS_LOOPBACK_MODE;
 	else
-		phba->fc_flag &= ~FC_LOOPBACK_MODE;
+		phba->link_flag &= ~LS_LOOPBACK_MODE;
+}
+
+static inline int
+lpfc_is_link_up(struct lpfc_hba *phba)
+{
+	return  phba->link_state == LPFC_LINK_UP ||
+		phba->link_state == LPFC_CLEAR_LA;
 }
 
-struct rnidrsp {
-	void *buf;
-	uint32_t uniqueid;
-	struct list_head list;
-	uint32_t data;
-};
+
 
 #define FC_REG_DUMP_EVENT	0x10	/* Register for Dump events */
+
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 95fe77e816f80a756b937f6012b8ab989e14ac74..b8adff8cea6adee5c7ec1d431cbd644290cf37a7 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -76,55 +76,68 @@ static ssize_t
 lpfc_info_show(struct class_device *cdev, char *buf)
 {
 	struct Scsi_Host *host = class_to_shost(cdev);
+
 	return snprintf(buf, PAGE_SIZE, "%s\n",lpfc_info(host));
 }
 
 static ssize_t
 lpfc_serialnum_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+
 	return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber);
 }
 
 static ssize_t
 lpfc_modeldesc_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+
 	return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc);
 }
 
 static ssize_t
 lpfc_modelname_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+
 	return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName);
 }
 
 static ssize_t
 lpfc_programtype_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+
 	return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType);
 }
 
 static ssize_t
-lpfc_portnum_show(struct class_device *cdev, char *buf)
+lpfc_vportnum_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+
 	return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port);
 }
 
 static ssize_t
 lpfc_fwrev_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	char fwrev[32];
+
 	lpfc_decode_firmware_rev(phba, fwrev, 1);
 	return snprintf(buf, PAGE_SIZE, "%s\n",fwrev);
 }
@@ -133,59 +146,80 @@ static ssize_t
 lpfc_hdw_show(struct class_device *cdev, char *buf)
 {
 	char hdw[9];
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	lpfc_vpd_t *vp = &phba->vpd;
+
 	lpfc_jedec_to_ascii(vp->rev.biuRev, hdw);
 	return snprintf(buf, PAGE_SIZE, "%s\n", hdw);
 }
 static ssize_t
 lpfc_option_rom_version_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+
 	return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion);
 }
 static ssize_t
 lpfc_state_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
-	int len = 0;
-	switch (phba->hba_state) {
-	case LPFC_STATE_UNKNOWN:
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+	int  len = 0;
+
+	switch (phba->link_state) {
+	case LPFC_LINK_UNKNOWN:
 	case LPFC_WARM_START:
 	case LPFC_INIT_START:
 	case LPFC_INIT_MBX_CMDS:
 	case LPFC_LINK_DOWN:
-		len += snprintf(buf + len, PAGE_SIZE-len, "Link Down\n");
+	case LPFC_HBA_ERROR:
+		len += snprintf(buf + len, PAGE_SIZE-len, "Link Down");
 		break;
 	case LPFC_LINK_UP:
-	case LPFC_LOCAL_CFG_LINK:
-		len += snprintf(buf + len, PAGE_SIZE-len, "Link Up\n");
-		break;
-	case LPFC_FLOGI:
-	case LPFC_FABRIC_CFG_LINK:
-	case LPFC_NS_REG:
-	case LPFC_NS_QRY:
-	case LPFC_BUILD_DISC_LIST:
-	case LPFC_DISC_AUTH:
 	case LPFC_CLEAR_LA:
-		len += snprintf(buf + len, PAGE_SIZE-len,
-				"Link Up - Discovery\n");
-		break;
-	case LPFC_HBA_READY:
-		len += snprintf(buf + len, PAGE_SIZE-len,
-				"Link Up - Ready:\n");
+		len += snprintf(buf + len, PAGE_SIZE-len, "Link Up - \n");
+
+		switch (vport->port_state) {
+			len += snprintf(buf + len, PAGE_SIZE-len,
+					"initializing\n");
+			break;
+		case LPFC_LOCAL_CFG_LINK:
+			len += snprintf(buf + len, PAGE_SIZE-len,
+					"configuring\n");
+			break;
+		case LPFC_FLOGI:
+		case LPFC_FABRIC_CFG_LINK:
+		case LPFC_NS_REG:
+		case LPFC_NS_QRY:
+		case LPFC_BUILD_DISC_LIST:
+		case LPFC_DISC_AUTH:
+			len += snprintf(buf + len, PAGE_SIZE - len,
+					"Discovery\n");
+			break;
+		case LPFC_VPORT_READY:
+			len += snprintf(buf + len, PAGE_SIZE - len, "Ready\n");
+			break;
+
+		case LPFC_STATE_UNKNOWN:
+			len += snprintf(buf + len, PAGE_SIZE - len,
+					"Unknown\n");
+			break;
+		}
+
 		if (phba->fc_topology == TOPOLOGY_LOOP) {
-			if (phba->fc_flag & FC_PUBLIC_LOOP)
+			if (vport->fc_flag & FC_PUBLIC_LOOP)
 				len += snprintf(buf + len, PAGE_SIZE-len,
 						"   Public Loop\n");
 			else
 				len += snprintf(buf + len, PAGE_SIZE-len,
 						"   Private Loop\n");
 		} else {
-			if (phba->fc_flag & FC_FABRIC)
+			if (vport->fc_flag & FC_FABRIC)
 				len += snprintf(buf + len, PAGE_SIZE-len,
 						"   Fabric\n");
 			else
@@ -193,29 +227,32 @@ lpfc_state_show(struct class_device *cdev, char *buf)
 						"   Point-2-Point\n");
 		}
 	}
+
 	return len;
 }
 
 static ssize_t
 lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
-	return snprintf(buf, PAGE_SIZE, "%d\n", phba->fc_map_cnt +
-							phba->fc_unmap_cnt);
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			vport->fc_map_cnt + vport->fc_unmap_cnt);
 }
 
 
 static int
-lpfc_issue_lip(struct Scsi_Host *host)
+lpfc_issue_lip(struct Scsi_Host *shost)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	LPFC_MBOXQ_t *pmboxq;
 	int mbxstatus = MBXERR_ERROR;
 
-	if ((phba->fc_flag & FC_OFFLINE_MODE) ||
-	    (phba->fc_flag & FC_BLOCK_MGMT_IO) ||
-	    (phba->hba_state != LPFC_HBA_READY))
+	if ((vport->fc_flag & FC_OFFLINE_MODE) ||
+	    (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) ||
+	    (vport->port_state != LPFC_VPORT_READY))
 		return -EPERM;
 
 	pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL);
@@ -320,8 +357,10 @@ lpfc_selective_reset(struct lpfc_hba *phba)
 static ssize_t
 lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+
 	int status = -EINVAL;
 
 	if (strncmp(buf, "selective", sizeof("selective") - 1) == 0)
@@ -336,23 +375,26 @@ lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count)
 static ssize_t
 lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+
 	return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
 }
 
 static ssize_t
 lpfc_board_mode_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	char  * state;
 
-	if (phba->hba_state == LPFC_HBA_ERROR)
+	if (phba->link_state == LPFC_HBA_ERROR)
 		state = "error";
-	else if (phba->hba_state == LPFC_WARM_START)
+	else if (phba->link_state == LPFC_WARM_START)
 		state = "warm start";
-	else if (phba->hba_state == LPFC_INIT_START)
+	else if (phba->link_state == LPFC_INIT_START)
 		state = "offline";
 	else
 		state = "online";
@@ -363,8 +405,9 @@ lpfc_board_mode_show(struct class_device *cdev, char *buf)
 static ssize_t
 lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	struct completion online_compl;
 	int status=0;
 
@@ -392,8 +435,9 @@ lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count)
 static ssize_t
 lpfc_poll_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 
 	return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll);
 }
@@ -402,8 +446,9 @@ static ssize_t
 lpfc_poll_store(struct class_device *cdev, const char *buf,
 		size_t count)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	uint32_t creg_val;
 	uint32_t old_val;
 	int val=0;
@@ -417,7 +462,7 @@ lpfc_poll_store(struct class_device *cdev, const char *buf,
 	if ((val & 0x3) != val)
 		return -EINVAL;
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 
 	old_val = phba->cfg_poll;
 
@@ -432,16 +477,16 @@ lpfc_poll_store(struct class_device *cdev, const char *buf,
 			lpfc_poll_start_timer(phba);
 		}
 	} else if (val != 0x0) {
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(&phba->hbalock);
 		return -EINVAL;
 	}
 
 	if (!(val & DISABLE_FCP_RING_INT) &&
 	    (old_val & DISABLE_FCP_RING_INT))
 	{
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(&phba->hbalock);
 		del_timer(&phba->fcp_poll_timer);
-		spin_lock_irq(phba->host->host_lock);
+		spin_lock_irq(&phba->hbalock);
 		creg_val = readl(phba->HCregaddr);
 		creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
 		writel(creg_val, phba->HCregaddr);
@@ -450,7 +495,7 @@ lpfc_poll_store(struct class_device *cdev, const char *buf,
 
 	phba->cfg_poll = val;
 
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	return strlen(buf);
 }
@@ -459,8 +504,9 @@ lpfc_poll_store(struct class_device *cdev, const char *buf,
 static ssize_t \
 lpfc_##attr##_show(struct class_device *cdev, char *buf) \
 { \
-	struct Scsi_Host *host = class_to_shost(cdev);\
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\
+	struct Scsi_Host  *shost = class_to_shost(cdev);\
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
+	struct lpfc_hba   *phba = vport->phba;\
 	int val = 0;\
 	val = phba->cfg_##attr;\
 	return snprintf(buf, PAGE_SIZE, "%d\n",\
@@ -471,8 +517,9 @@ lpfc_##attr##_show(struct class_device *cdev, char *buf) \
 static ssize_t \
 lpfc_##attr##_show(struct class_device *cdev, char *buf) \
 { \
-	struct Scsi_Host *host = class_to_shost(cdev);\
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\
+	struct Scsi_Host  *shost = class_to_shost(cdev);\
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
+	struct lpfc_hba   *phba = vport->phba;\
 	int val = 0;\
 	val = phba->cfg_##attr;\
 	return snprintf(buf, PAGE_SIZE, "%#x\n",\
@@ -514,8 +561,9 @@ lpfc_##attr##_set(struct lpfc_hba *phba, int val) \
 static ssize_t \
 lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \
 { \
-	struct Scsi_Host *host = class_to_shost(cdev);\
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\
+	struct Scsi_Host  *shost = class_to_shost(cdev);\
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
+	struct lpfc_hba   *phba = vport->phba;\
 	int val=0;\
 	if (!isdigit(buf[0]))\
 		return -EINVAL;\
@@ -576,7 +624,7 @@ static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL);
 static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL);
 static CLASS_DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL);
 static CLASS_DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL);
-static CLASS_DEVICE_ATTR(portnum, S_IRUGO, lpfc_portnum_show, NULL);
+static CLASS_DEVICE_ATTR(portnum, S_IRUGO, lpfc_vportnum_show, NULL);
 static CLASS_DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL);
 static CLASS_DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL);
 static CLASS_DEVICE_ATTR(state, S_IRUGO, lpfc_state_show, NULL);
@@ -600,8 +648,9 @@ static ssize_t
 lpfc_soft_wwn_enable_store(struct class_device *cdev, const char *buf,
 				size_t count)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	unsigned int cnt = count;
 
 	/*
@@ -634,8 +683,10 @@ static CLASS_DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL,
 static ssize_t
 lpfc_soft_wwpn_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+
 	return snprintf(buf, PAGE_SIZE, "0x%llx\n",
 			(unsigned long long)phba->cfg_soft_wwpn);
 }
@@ -644,8 +695,9 @@ lpfc_soft_wwpn_show(struct class_device *cdev, char *buf)
 static ssize_t
 lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	struct completion online_compl;
 	int stat1=0, stat2=0;
 	unsigned int i, j, cnt=count;
@@ -680,9 +732,9 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count)
 		}
 	}
 	phba->cfg_soft_wwpn = wwn_to_u64(wwpn);
-	fc_host_port_name(host) = phba->cfg_soft_wwpn;
+	fc_host_port_name(shost) = phba->cfg_soft_wwpn;
 	if (phba->cfg_soft_wwnn)
-		fc_host_node_name(host) = phba->cfg_soft_wwnn;
+		fc_host_node_name(shost) = phba->cfg_soft_wwnn;
 
 	dev_printk(KERN_NOTICE, &phba->pcidev->dev,
 		   "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no);
@@ -790,8 +842,9 @@ MODULE_PARM_DESC(lpfc_nodev_tmo,
 static ssize_t
 lpfc_nodev_tmo_show(struct class_device *cdev, char *buf)
 {
-	struct Scsi_Host *host = class_to_shost(cdev);
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	int val = 0;
 	val = phba->cfg_devloss_tmo;
 	return snprintf(buf, PAGE_SIZE, "%d\n",
@@ -829,18 +882,6 @@ lpfc_nodev_tmo_init(struct lpfc_hba *phba, int val)
 	return -EINVAL;
 }
 
-static void
-lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba)
-{
-	struct lpfc_nodelist  *ndlp;
-
-	spin_lock_irq(phba->host->host_lock);
-	list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp)
-		if (ndlp->rport)
-			ndlp->rport->dev_loss_tmo = phba->cfg_devloss_tmo;
-	spin_unlock_irq(phba->host->host_lock);
-}
-
 static int
 lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val)
 {
@@ -856,7 +897,6 @@ lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val)
 	if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
 		phba->cfg_nodev_tmo = val;
 		phba->cfg_devloss_tmo = val;
-		lpfc_update_rport_devloss_tmo(phba);
 		return 0;
 	}
 
@@ -892,7 +932,6 @@ lpfc_devloss_tmo_set(struct lpfc_hba *phba, int val)
 		phba->cfg_nodev_tmo = val;
 		phba->cfg_devloss_tmo = val;
 		phba->dev_loss_tmo_changed = 1;
-		lpfc_update_rport_devloss_tmo(phba);
 		return 0;
 	}
 
@@ -1088,7 +1127,7 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
 LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible");
 
 
-struct class_device_attribute *lpfc_host_attrs[] = {
+struct class_device_attribute *lpfc_hba_attrs[] = {
 	&class_device_attr_info,
 	&class_device_attr_serialnum,
 	&class_device_attr_modeldesc,
@@ -1136,9 +1175,11 @@ static ssize_t
 sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
 {
 	size_t buf_off;
-	struct Scsi_Host *host = class_to_shost(container_of(kobj,
-					     struct class_device, kobj));
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct class_device *cdev = container_of(kobj, struct class_device,
+						 kobj);
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 
 	if ((off + count) > FF_REG_AREA_SIZE)
 		return -ERANGE;
@@ -1148,18 +1189,16 @@ sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
 	if (off % 4 || count % 4 || (unsigned long)buf % 4)
 		return -EINVAL;
 
-	spin_lock_irq(phba->host->host_lock);
-
-	if (!(phba->fc_flag & FC_OFFLINE_MODE)) {
-		spin_unlock_irq(phba->host->host_lock);
+	if (!(vport->fc_flag & FC_OFFLINE_MODE)) {
 		return -EPERM;
 	}
 
+	spin_lock_irq(&phba->hbalock);
 	for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t))
 		writel(*((uint32_t *)(buf + buf_off)),
 		       phba->ctrl_regs_memmap_p + off + buf_off);
 
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	return count;
 }
@@ -1169,9 +1208,11 @@ sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
 {
 	size_t buf_off;
 	uint32_t * tmp_ptr;
-	struct Scsi_Host *host = class_to_shost(container_of(kobj,
-					     struct class_device, kobj));
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct class_device *cdev = container_of(kobj, struct class_device,
+						 kobj);
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 
 	if (off > FF_REG_AREA_SIZE)
 		return -ERANGE;
@@ -1184,14 +1225,14 @@ sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
 	if (off % 4 || count % 4 || (unsigned long)buf % 4)
 		return -EINVAL;
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 
 	for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) {
 		tmp_ptr = (uint32_t *)(buf + buf_off);
 		*tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off);
 	}
 
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	return count;
 }
@@ -1209,7 +1250,7 @@ static struct bin_attribute sysfs_ctlreg_attr = {
 
 
 static void
-sysfs_mbox_idle (struct lpfc_hba * phba)
+sysfs_mbox_idle(struct lpfc_hba *phba)
 {
 	phba->sysfs_mbox.state = SMBOX_IDLE;
 	phba->sysfs_mbox.offset = 0;
@@ -1224,10 +1265,12 @@ sysfs_mbox_idle (struct lpfc_hba * phba)
 static ssize_t
 sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
 {
-	struct Scsi_Host * host =
-		class_to_shost(container_of(kobj, struct class_device, kobj));
-	struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata;
-	struct lpfcMboxq * mbox = NULL;
+	struct class_device *cdev = container_of(kobj, struct class_device,
+						 kobj);
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+	struct lpfcMboxq  *mbox = NULL;
 
 	if ((count + off) > MAILBOX_CMD_SIZE)
 		return -ERANGE;
@@ -1245,7 +1288,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
 		memset(mbox, 0, sizeof (LPFC_MBOXQ_t));
 	}
 
-	spin_lock_irq(host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 
 	if (off == 0) {
 		if (phba->sysfs_mbox.mbox)
@@ -1258,7 +1301,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
 		    phba->sysfs_mbox.offset != off           ||
 		    phba->sysfs_mbox.mbox   == NULL ) {
 			sysfs_mbox_idle(phba);
-			spin_unlock_irq(host->host_lock);
+			spin_unlock_irq(&phba->hbalock);
 			return -EAGAIN;
 		}
 	}
@@ -1268,7 +1311,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
 
 	phba->sysfs_mbox.offset = off + count;
 
-	spin_unlock_irq(host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	return count;
 }
@@ -1276,10 +1319,11 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
 static ssize_t
 sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
 {
-	struct Scsi_Host *host =
-		class_to_shost(container_of(kobj, struct class_device,
-					    kobj));
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct class_device *cdev = container_of(kobj, struct class_device,
+						 kobj);
+	struct Scsi_Host  *shost = class_to_shost(cdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	int rc;
 
 	if (off > MAILBOX_CMD_SIZE)
@@ -1294,7 +1338,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
 	if (off && count == 0)
 		return 0;
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 
 	if (off == 0 &&
 	    phba->sysfs_mbox.state  == SMBOX_WRITING &&
@@ -1317,12 +1361,12 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
 		case MBX_SET_MASK:
 		case MBX_SET_SLIM:
 		case MBX_SET_DEBUG:
-			if (!(phba->fc_flag & FC_OFFLINE_MODE)) {
+			if (!(vport->fc_flag & FC_OFFLINE_MODE)) {
 				printk(KERN_WARNING "mbox_read:Command 0x%x "
 				       "is illegal in on-line state\n",
 				       phba->sysfs_mbox.mbox->mb.mbxCommand);
 				sysfs_mbox_idle(phba);
-				spin_unlock_irq(phba->host->host_lock);
+				spin_unlock_irq(&phba->hbalock);
 				return -EPERM;
 			}
 		case MBX_LOAD_SM:
@@ -1352,38 +1396,38 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
 			printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n",
 			       phba->sysfs_mbox.mbox->mb.mbxCommand);
 			sysfs_mbox_idle(phba);
-			spin_unlock_irq(phba->host->host_lock);
+			spin_unlock_irq(&phba->hbalock);
 			return -EPERM;
 		default:
 			printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n",
 			       phba->sysfs_mbox.mbox->mb.mbxCommand);
 			sysfs_mbox_idle(phba);
-			spin_unlock_irq(phba->host->host_lock);
+			spin_unlock_irq(&phba->hbalock);
 			return -EPERM;
 		}
 
-		if (phba->fc_flag & FC_BLOCK_MGMT_IO) {
+		if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) {
 			sysfs_mbox_idle(phba);
-			spin_unlock_irq(host->host_lock);
+			spin_unlock_irq(&phba->hbalock);
 			return  -EAGAIN;
 		}
 
-		if ((phba->fc_flag & FC_OFFLINE_MODE) ||
+		if ((vport->fc_flag & FC_OFFLINE_MODE) ||
 		    (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){
 
-			spin_unlock_irq(phba->host->host_lock);
+			spin_unlock_irq(&phba->hbalock);
 			rc = lpfc_sli_issue_mbox (phba,
 						  phba->sysfs_mbox.mbox,
 						  MBX_POLL);
-			spin_lock_irq(phba->host->host_lock);
+			spin_lock_irq(&phba->hbalock);
 
 		} else {
-			spin_unlock_irq(phba->host->host_lock);
+			spin_unlock_irq(&phba->hbalock);
 			rc = lpfc_sli_issue_mbox_wait (phba,
 						       phba->sysfs_mbox.mbox,
 				lpfc_mbox_tmo_val(phba,
 				    phba->sysfs_mbox.mbox->mb.mbxCommand) * HZ);
-			spin_lock_irq(phba->host->host_lock);
+			spin_lock_irq(&phba->hbalock);
 		}
 
 		if (rc != MBX_SUCCESS) {
@@ -1393,7 +1437,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
 				phba->sysfs_mbox.mbox = NULL;
 			}
 			sysfs_mbox_idle(phba);
-			spin_unlock_irq(host->host_lock);
+			spin_unlock_irq(&phba->hbalock);
 			return  (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV;
 		}
 		phba->sysfs_mbox.state = SMBOX_READING;
@@ -1402,7 +1446,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
 		 phba->sysfs_mbox.state  != SMBOX_READING) {
 		printk(KERN_WARNING  "mbox_read: Bad State\n");
 		sysfs_mbox_idle(phba);
-		spin_unlock_irq(host->host_lock);
+		spin_unlock_irq(&phba->hbalock);
 		return -EAGAIN;
 	}
 
@@ -1413,7 +1457,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
 	if (phba->sysfs_mbox.offset == MAILBOX_CMD_SIZE)
 		sysfs_mbox_idle(phba);
 
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	return count;
 }
@@ -1430,35 +1474,35 @@ static struct bin_attribute sysfs_mbox_attr = {
 };
 
 int
-lpfc_alloc_sysfs_attr(struct lpfc_hba *phba)
+lpfc_alloc_sysfs_attr(struct lpfc_vport *vport)
 {
-	struct Scsi_Host *host = phba->host;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 	int error;
 
-	error = sysfs_create_bin_file(&host->shost_classdev.kobj,
+	error = sysfs_create_bin_file(&shost->shost_classdev.kobj,
 							&sysfs_ctlreg_attr);
 	if (error)
 		goto out;
 
-	error = sysfs_create_bin_file(&host->shost_classdev.kobj,
+	error = sysfs_create_bin_file(&shost->shost_classdev.kobj,
 							&sysfs_mbox_attr);
 	if (error)
 		goto out_remove_ctlreg_attr;
 
 	return 0;
 out_remove_ctlreg_attr:
-	sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr);
+	sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_ctlreg_attr);
 out:
 	return error;
 }
 
 void
-lpfc_free_sysfs_attr(struct lpfc_hba *phba)
+lpfc_free_sysfs_attr(struct lpfc_vport *vport)
 {
-	struct Scsi_Host *host = phba->host;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 
-	sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_mbox_attr);
-	sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr);
+	sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_mbox_attr);
+	sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_ctlreg_attr);
 }
 
 
@@ -1469,26 +1513,28 @@ lpfc_free_sysfs_attr(struct lpfc_hba *phba)
 static void
 lpfc_get_host_port_id(struct Scsi_Host *shost)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+
 	/* note: fc_myDID already in cpu endianness */
-	fc_host_port_id(shost) = phba->fc_myDID;
+	fc_host_port_id(shost) = vport->fc_myDID;
 }
 
 static void
 lpfc_get_host_port_type(struct Scsi_Host *shost)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 
 	spin_lock_irq(shost->host_lock);
 
-	if (phba->hba_state == LPFC_HBA_READY) {
+	if (lpfc_is_link_up(phba)) {
 		if (phba->fc_topology == TOPOLOGY_LOOP) {
-			if (phba->fc_flag & FC_PUBLIC_LOOP)
+			if (vport->fc_flag & FC_PUBLIC_LOOP)
 				fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
 			else
 				fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
 		} else {
-			if (phba->fc_flag & FC_FABRIC)
+			if (vport->fc_flag & FC_FABRIC)
 				fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
 			else
 				fc_host_port_type(shost) = FC_PORTTYPE_PTP;
@@ -1502,31 +1548,21 @@ lpfc_get_host_port_type(struct Scsi_Host *shost)
 static void
 lpfc_get_host_port_state(struct Scsi_Host *shost)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 
 	spin_lock_irq(shost->host_lock);
 
-	if (phba->fc_flag & FC_OFFLINE_MODE)
+	if (vport->fc_flag & FC_OFFLINE_MODE)
 		fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
 	else {
-		switch (phba->hba_state) {
-		case LPFC_STATE_UNKNOWN:
-		case LPFC_WARM_START:
-		case LPFC_INIT_START:
-		case LPFC_INIT_MBX_CMDS:
+		switch (phba->link_state) {
+		case LPFC_LINK_UNKNOWN:
 		case LPFC_LINK_DOWN:
 			fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
 			break;
 		case LPFC_LINK_UP:
-		case LPFC_LOCAL_CFG_LINK:
-		case LPFC_FLOGI:
-		case LPFC_FABRIC_CFG_LINK:
-		case LPFC_NS_REG:
-		case LPFC_NS_QRY:
-		case LPFC_BUILD_DISC_LIST:
-		case LPFC_DISC_AUTH:
 		case LPFC_CLEAR_LA:
-		case LPFC_HBA_READY:
 			/* Links up, beyond this port_type reports state */
 			fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
 			break;
@@ -1545,11 +1581,12 @@ lpfc_get_host_port_state(struct Scsi_Host *shost)
 static void
 lpfc_get_host_speed(struct Scsi_Host *shost)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 
 	spin_lock_irq(shost->host_lock);
 
-	if (phba->hba_state == LPFC_HBA_READY) {
+	if (lpfc_is_link_up(phba)) {
 		switch(phba->fc_linkspeed) {
 			case LA_1GHZ_LINK:
 				fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
@@ -1575,39 +1612,31 @@ lpfc_get_host_speed(struct Scsi_Host *shost)
 static void
 lpfc_get_host_fabric_name (struct Scsi_Host *shost)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	u64 node_name;
 
 	spin_lock_irq(shost->host_lock);
 
-	if ((phba->fc_flag & FC_FABRIC) ||
+	if ((vport->fc_flag & FC_FABRIC) ||
 	    ((phba->fc_topology == TOPOLOGY_LOOP) &&
-	     (phba->fc_flag & FC_PUBLIC_LOOP)))
+	     (vport->fc_flag & FC_PUBLIC_LOOP)))
 		node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
 	else
 		/* fabric is local port if there is no F/FL_Port */
-		node_name = wwn_to_u64(phba->fc_nodename.u.wwn);
+		node_name = wwn_to_u64(vport->fc_nodename.u.wwn);
 
 	spin_unlock_irq(shost->host_lock);
 
 	fc_host_fabric_name(shost) = node_name;
 }
 
-static void
-lpfc_get_host_symbolic_name (struct Scsi_Host *shost)
-{
-	struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata;
-
-	spin_lock_irq(shost->host_lock);
-	lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(shost));
-	spin_unlock_irq(shost->host_lock);
-}
-
 static struct fc_host_statistics *
 lpfc_get_stats(struct Scsi_Host *shost)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
-	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+	struct lpfc_sli   *psli = &phba->sli;
 	struct fc_host_statistics *hs = &phba->link_stats;
 	struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets;
 	LPFC_MBOXQ_t *pmboxq;
@@ -1615,7 +1644,15 @@ lpfc_get_stats(struct Scsi_Host *shost)
 	unsigned long seconds;
 	int rc = 0;
 
-	if (phba->fc_flag & FC_BLOCK_MGMT_IO)
+				/* prevent udev from issuing mailbox commands
+				 * until the port is configured.
+				 */
+	if (phba->link_state < LPFC_LINK_DOWN ||
+	    !phba->mbox_mem_pool ||
+	    (phba->sli.sli_flag & LPFC_SLI2_ACTIVE) == 0)
+			return NULL;
+
+	if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
 		return NULL;
 
 	pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@@ -1628,7 +1665,7 @@ lpfc_get_stats(struct Scsi_Host *shost)
 	pmb->mbxOwner = OWN_HOST;
 	pmboxq->context1 = NULL;
 
-	if ((phba->fc_flag & FC_OFFLINE_MODE) ||
+	if ((vport->fc_flag & FC_OFFLINE_MODE) ||
 		(!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
 		rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
 	else
@@ -1654,7 +1691,7 @@ lpfc_get_stats(struct Scsi_Host *shost)
 	pmb->mbxOwner = OWN_HOST;
 	pmboxq->context1 = NULL;
 
-	if ((phba->fc_flag & FC_OFFLINE_MODE) ||
+	if ((vport->fc_flag & FC_OFFLINE_MODE) ||
 	    (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
 		rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
 	else
@@ -1711,14 +1748,15 @@ lpfc_get_stats(struct Scsi_Host *shost)
 static void
 lpfc_reset_stats(struct Scsi_Host *shost)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
-	struct lpfc_sli *psli = &phba->sli;
-	struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+	struct lpfc_sli   *psli = &phba->sli;
+	struct lpfc_lnk_stat *lso = &psli->lnk_stat_offsets;
 	LPFC_MBOXQ_t *pmboxq;
 	MAILBOX_t *pmb;
 	int rc = 0;
 
-	if (phba->fc_flag & FC_BLOCK_MGMT_IO)
+	if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
 		return;
 
 	pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@@ -1732,7 +1770,7 @@ lpfc_reset_stats(struct Scsi_Host *shost)
 	pmb->un.varWords[0] = 0x1; /* reset request */
 	pmboxq->context1 = NULL;
 
-	if ((phba->fc_flag & FC_OFFLINE_MODE) ||
+	if ((vport->fc_flag & FC_OFFLINE_MODE) ||
 		(!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
 		rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
 	else
@@ -1751,7 +1789,7 @@ lpfc_reset_stats(struct Scsi_Host *shost)
 	pmb->mbxOwner = OWN_HOST;
 	pmboxq->context1 = NULL;
 
-	if ((phba->fc_flag & FC_OFFLINE_MODE) ||
+	if ((vport->fc_flag & FC_OFFLINE_MODE) ||
 	    (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
 		rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
 	else
@@ -1789,13 +1827,13 @@ lpfc_reset_stats(struct Scsi_Host *shost)
 static struct lpfc_nodelist *
 lpfc_get_node_by_target(struct scsi_target *starget)
 {
-	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
-	struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata;
+	struct Scsi_Host  *shost = dev_to_shost(starget->dev.parent);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
 	struct lpfc_nodelist *ndlp;
 
 	spin_lock_irq(shost->host_lock);
 	/* Search for this, mapped, target ID */
-	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_MAPPED_NODE &&
 		    starget->id == ndlp->nlp_sid) {
 			spin_unlock_irq(shost->host_lock);
@@ -1885,9 +1923,6 @@ struct fc_function_template lpfc_transport_functions = {
 	.get_host_fabric_name = lpfc_get_host_fabric_name,
 	.show_host_fabric_name = 1,
 
-	.get_host_symbolic_name = lpfc_get_host_symbolic_name,
-	.show_host_symbolic_name = 1,
-
 	/*
 	 * The LPFC driver treats linkdown handling as target loss events
 	 * so there are no sysfs handlers for link_down_tmo.
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index b8c2a8862d8cbc8dda943a54f0153bfb19ed3f22..0081cffd9280878a63029a385f89c7f4a5979ff3 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -26,6 +26,7 @@ void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
 int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb,
 		 struct lpfc_dmabuf *mp);
 void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport);
 void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
 int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -36,7 +37,6 @@ void lpfc_unreg_login(struct lpfc_hba *, uint32_t, LPFC_MBOXQ_t *);
 void lpfc_unreg_did(struct lpfc_hba *, uint32_t, LPFC_MBOXQ_t *);
 void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
 
-
 int lpfc_linkdown(struct lpfc_hba *);
 void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
 
@@ -45,70 +45,70 @@ void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
-void lpfc_dequeue_node(struct lpfc_hba *, struct lpfc_nodelist *);
-void lpfc_nlp_set_state(struct lpfc_hba *, struct lpfc_nodelist *, int);
-void lpfc_drop_node(struct lpfc_hba *, struct lpfc_nodelist *);
-void lpfc_set_disctmo(struct lpfc_hba *);
-int lpfc_can_disctmo(struct lpfc_hba *);
-int lpfc_unreg_rpi(struct lpfc_hba *, struct lpfc_nodelist *);
+void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *);
+void lpfc_nlp_set_state(struct lpfc_vport *, struct lpfc_nodelist *, int);
+void lpfc_drop_node(struct lpfc_vport *, struct lpfc_nodelist *);
+void lpfc_set_disctmo(struct lpfc_vport *);
+int  lpfc_can_disctmo(struct lpfc_vport *);
+int  lpfc_unreg_rpi(struct lpfc_vport *, struct lpfc_nodelist *);
 int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *,
-		    struct lpfc_iocbq *, struct lpfc_nodelist *);
-void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t);
+			struct lpfc_iocbq *, struct lpfc_nodelist *);
+void lpfc_nlp_init(struct lpfc_vport *, struct lpfc_nodelist *, uint32_t);
 struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *);
 int  lpfc_nlp_put(struct lpfc_nodelist *);
-struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t);
-void lpfc_disc_list_loopmap(struct lpfc_hba *);
-void lpfc_disc_start(struct lpfc_hba *);
-void lpfc_disc_flush_list(struct lpfc_hba *);
+struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_vport *, uint32_t);
+void lpfc_disc_list_loopmap(struct lpfc_vport *);
+void lpfc_disc_start(struct lpfc_vport *);
+void lpfc_disc_flush_list(struct lpfc_vport *);
 void lpfc_disc_timeout(unsigned long);
 
-struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi);
-struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi);
+struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);
+struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);
 
 int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t);
 int lpfc_do_work(void *);
-int lpfc_disc_state_machine(struct lpfc_hba *, struct lpfc_nodelist *, void *,
+int lpfc_disc_state_machine(struct lpfc_vport *, struct lpfc_nodelist *, void *,
 			    uint32_t);
 
-int lpfc_check_sparm(struct lpfc_hba *, struct lpfc_nodelist *,
+int lpfc_check_sparm(struct lpfc_vport *, struct lpfc_nodelist *,
 		     struct serv_parm *, uint32_t);
 int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist * ndlp);
 int lpfc_els_abort_flogi(struct lpfc_hba *);
-int lpfc_initial_flogi(struct lpfc_hba *);
-int lpfc_issue_els_plogi(struct lpfc_hba *, uint32_t, uint8_t);
-int lpfc_issue_els_prli(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
-int lpfc_issue_els_adisc(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
-int lpfc_issue_els_logo(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
-int lpfc_issue_els_scr(struct lpfc_hba *, uint32_t, uint8_t);
+int lpfc_initial_flogi(struct lpfc_vport *);
+int lpfc_issue_els_plogi(struct lpfc_vport *, uint32_t, uint8_t);
+int lpfc_issue_els_prli(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
+int lpfc_issue_els_adisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
+int lpfc_issue_els_logo(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
+int lpfc_issue_els_scr(struct lpfc_vport *, uint32_t, uint8_t);
 int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
-int lpfc_els_rsp_acc(struct lpfc_hba *, uint32_t, struct lpfc_iocbq *,
+int lpfc_els_rsp_acc(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *,
 		     struct lpfc_nodelist *, LPFC_MBOXQ_t *, uint8_t);
-int lpfc_els_rsp_reject(struct lpfc_hba *, uint32_t, struct lpfc_iocbq *,
+int lpfc_els_rsp_reject(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *,
 			struct lpfc_nodelist *);
-int lpfc_els_rsp_adisc_acc(struct lpfc_hba *, struct lpfc_iocbq *,
+int lpfc_els_rsp_adisc_acc(struct lpfc_vport *, struct lpfc_iocbq *,
 			   struct lpfc_nodelist *);
-int lpfc_els_rsp_prli_acc(struct lpfc_hba *, struct lpfc_iocbq *,
+int lpfc_els_rsp_prli_acc(struct lpfc_vport *, struct lpfc_iocbq *,
 			  struct lpfc_nodelist *);
-void lpfc_cancel_retry_delay_tmo(struct lpfc_hba *, struct lpfc_nodelist *);
+void lpfc_cancel_retry_delay_tmo(struct lpfc_vport *, struct lpfc_nodelist *);
 void lpfc_els_retry_delay(unsigned long);
 void lpfc_els_retry_delay_handler(struct lpfc_nodelist *);
 void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
 			  struct lpfc_iocbq *);
-int lpfc_els_handle_rscn(struct lpfc_hba *);
-int lpfc_els_flush_rscn(struct lpfc_hba *);
-int lpfc_rscn_payload_check(struct lpfc_hba *, uint32_t);
-void lpfc_els_flush_cmd(struct lpfc_hba *);
-int lpfc_els_disc_adisc(struct lpfc_hba *);
-int lpfc_els_disc_plogi(struct lpfc_hba *);
+int lpfc_els_handle_rscn(struct lpfc_vport *);
+int lpfc_els_flush_rscn(struct lpfc_vport *);
+int lpfc_rscn_payload_check(struct lpfc_vport *, uint32_t);
+void lpfc_els_flush_cmd(struct lpfc_vport *);
+int lpfc_els_disc_adisc(struct lpfc_vport *);
+int lpfc_els_disc_plogi(struct lpfc_vport *);
 void lpfc_els_timeout(unsigned long);
-void lpfc_els_timeout_handler(struct lpfc_hba *);
+void lpfc_els_timeout_handler(struct lpfc_vport *);
 
 void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
 			 struct lpfc_iocbq *);
-int lpfc_ns_cmd(struct lpfc_hba *, struct lpfc_nodelist *, int);
-int lpfc_fdmi_cmd(struct lpfc_hba *, struct lpfc_nodelist *, int);
+int lpfc_ns_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int);
+int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int);
 void lpfc_fdmi_tmo(unsigned long);
-void lpfc_fdmi_tmo_handler(struct lpfc_hba *);
+void lpfc_fdmi_timeout_handler(struct lpfc_vport *vport);
 
 int lpfc_config_port_prep(struct lpfc_hba *);
 int lpfc_config_port_post(struct lpfc_hba *);
@@ -146,6 +146,7 @@ void lpfc_poll_start_timer(struct lpfc_hba * phba);
 void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba);
 struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
 void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
+void __lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
 uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
 
 void lpfc_reset_barrier(struct lpfc_hba * phba);
@@ -154,6 +155,7 @@ int lpfc_sli_brdkill(struct lpfc_hba *);
 int lpfc_sli_brdreset(struct lpfc_hba *);
 int lpfc_sli_brdrestart(struct lpfc_hba *);
 int lpfc_sli_hba_setup(struct lpfc_hba *);
+int lpfc_sli_host_down(struct lpfc_vport *);
 int lpfc_sli_hba_down(struct lpfc_hba *);
 int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
 int lpfc_sli_handle_mb_event(struct lpfc_hba *);
@@ -164,7 +166,7 @@ void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
 int lpfc_sli_issue_iocb(struct lpfc_hba *, struct lpfc_sli_ring *,
 			struct lpfc_iocbq *, uint32_t);
 void lpfc_sli_pcimem_bcopy(void *, void *, uint32_t);
-int lpfc_sli_abort_iocb_ring(struct lpfc_hba *, struct lpfc_sli_ring *);
+void lpfc_sli_abort_iocb_ring(struct lpfc_hba *, struct lpfc_sli_ring *);
 int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *,
 			     struct lpfc_dmabuf *);
 struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *,
@@ -173,15 +175,16 @@ struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *,
 int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *,
 			       struct lpfc_iocbq *);
 int lpfc_sli_sum_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t,
-			  uint64_t, lpfc_ctx_cmd);
+		      uint64_t, lpfc_ctx_cmd);
 int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t,
-			    uint64_t, uint32_t, lpfc_ctx_cmd);
+			uint64_t, uint32_t, lpfc_ctx_cmd);
 
 void lpfc_mbox_timeout(unsigned long);
 void lpfc_mbox_timeout_handler(struct lpfc_hba *);
 
-struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba *, uint32_t);
-struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_hba *, struct lpfc_name *);
+struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_vport *, uint32_t);
+struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *,
+					 struct lpfc_name *);
 
 int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
 			 uint32_t timeout);
@@ -196,6 +199,7 @@ void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba,
 			     struct lpfc_iocbq * rspiocb);
 
 void *lpfc_mbuf_alloc(struct lpfc_hba *, int, dma_addr_t *);
+void __lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t);
 void lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t);
 
 /* Function prototypes. */
@@ -204,17 +208,18 @@ void lpfc_scan_start(struct Scsi_Host *);
 int lpfc_scan_finished(struct Scsi_Host *, unsigned long);
 
 void lpfc_get_cfgparam(struct lpfc_hba *);
-int lpfc_alloc_sysfs_attr(struct lpfc_hba *);
-void lpfc_free_sysfs_attr(struct lpfc_hba *);
-extern struct class_device_attribute *lpfc_host_attrs[];
+int lpfc_alloc_sysfs_attr(struct lpfc_vport *);
+void lpfc_free_sysfs_attr(struct lpfc_vport *);
+extern struct class_device_attribute *lpfc_hba_attrs[];
 extern struct scsi_host_template lpfc_template;
 extern struct fc_function_template lpfc_transport_functions;
 
-void lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp);
+void lpfc_get_hba_sym_node_name(struct lpfc_hba *phba, uint8_t *symbp);
 void lpfc_terminate_rport_io(struct fc_rport *);
 void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport);
 
+struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int);
+void lpfc_post_hba_setup_vport_init(struct lpfc_vport *);
+void destroy_port(struct lpfc_vport *);
+
 #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
-#define HBA_EVENT_RSCN                   5
-#define HBA_EVENT_LINK_UP                2
-#define HBA_EVENT_LINK_DOWN              3
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 34a9e3bb2614058c9ca827be246b65539564e0cb..dc25a53524c47e4dc6ee23e06e7329c768b20574 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -59,13 +59,13 @@ static char *lpfc_release_version = LPFC_DRIVER_VERSION;
  * lpfc_ct_unsol_event
  */
 void
-lpfc_ct_unsol_event(struct lpfc_hba * phba,
-		    struct lpfc_sli_ring * pring, struct lpfc_iocbq * piocbq)
+lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+		    struct lpfc_iocbq *piocbq)
 {
 
 	struct lpfc_iocbq *next_piocbq;
 	struct lpfc_dmabuf *pmbuf = NULL;
-	struct lpfc_dmabuf *matp, *next_matp;
+	struct lpfc_dmabuf *matp = NULL, *next_matp;
 	uint32_t ctx = 0, size = 0, cnt = 0;
 	IOCB_t *icmd = &piocbq->iocb;
 	IOCB_t *save_icmd = icmd;
@@ -145,7 +145,7 @@ ct_unsol_event_exit_piocbq:
 }
 
 static void
-lpfc_free_ct_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mlist)
+lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist)
 {
 	struct lpfc_dmabuf *mlast, *next_mlast;
 
@@ -160,7 +160,7 @@ lpfc_free_ct_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mlist)
 }
 
 static struct lpfc_dmabuf *
-lpfc_alloc_ct_rsp(struct lpfc_hba * phba, int cmdcode, struct ulp_bde64 * bpl,
+lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl,
 		  uint32_t size, int *entries)
 {
 	struct lpfc_dmabuf *mlist = NULL;
@@ -216,23 +216,21 @@ lpfc_alloc_ct_rsp(struct lpfc_hba * phba, int cmdcode, struct ulp_bde64 * bpl,
 }
 
 static int
-lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp,
+lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
 	     struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp,
 	     void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
 		     struct lpfc_iocbq *),
 	     struct lpfc_nodelist *ndlp, uint32_t usr_flg, uint32_t num_entry,
 	     uint32_t tmo)
 {
-
-	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_hba  *phba = vport->phba;
+	struct lpfc_sli  *psli = &phba->sli;
 	struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
 	IOCB_t *icmd;
 	struct lpfc_iocbq *geniocb;
 
 	/* Allocate buffer for  command iocb */
-	spin_lock_irq(phba->host->host_lock);
 	geniocb = lpfc_sli_get_iocbq(phba);
-	spin_unlock_irq(phba->host->host_lock);
 
 	if (geniocb == NULL)
 		return 1;
@@ -276,27 +274,26 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp,
 	lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
 			"%d:0119 Issue GEN REQ IOCB for NPORT x%x "
 			"Data: x%x x%x\n", phba->brd_no, icmd->un.ulpWord[5],
-			icmd->ulpIoTag, phba->hba_state);
+			icmd->ulpIoTag, vport->port_state);
 	geniocb->iocb_cmpl = cmpl;
 	geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
-	spin_lock_irq(phba->host->host_lock);
+	geniocb->vport = vport;
 	if (lpfc_sli_issue_iocb(phba, pring, geniocb, 0) == IOCB_ERROR) {
 		lpfc_sli_release_iocbq(phba, geniocb);
-		spin_unlock_irq(phba->host->host_lock);
 		return 1;
 	}
-	spin_unlock_irq(phba->host->host_lock);
 
 	return 0;
 }
 
 static int
-lpfc_ct_cmd(struct lpfc_hba *phba, struct lpfc_dmabuf *inmp,
+lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp,
 	    struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp,
 	    void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
 			  struct lpfc_iocbq *),
 	    uint32_t rsp_size)
 {
+	struct lpfc_hba  *phba = vport->phba;
 	struct ulp_bde64 *bpl = (struct ulp_bde64 *) bmp->virt;
 	struct lpfc_dmabuf *outmp;
 	int cnt = 0, status;
@@ -310,7 +307,7 @@ lpfc_ct_cmd(struct lpfc_hba *phba, struct lpfc_dmabuf *inmp,
 	if (!outmp)
 		return -ENOMEM;
 
-	status = lpfc_gen_req(phba, bmp, inmp, outmp, cmpl, ndlp, 0,
+	status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp, 0,
 			      cnt+1, 0);
 	if (status) {
 		lpfc_free_ct_rsp(phba, outmp);
@@ -320,19 +317,20 @@ lpfc_ct_cmd(struct lpfc_hba *phba, struct lpfc_dmabuf *inmp,
 }
 
 static int
-lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size)
+lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
 	struct lpfc_sli_ct_request *Response =
 		(struct lpfc_sli_ct_request *) mp->virt;
 	struct lpfc_nodelist *ndlp = NULL;
 	struct lpfc_dmabuf *mlast, *next_mp;
 	uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType;
-	uint32_t Did;
-	uint32_t CTentry;
+	uint32_t Did, CTentry;
 	int Cnt;
 	struct list_head head;
 
-	lpfc_set_disctmo(phba);
+	lpfc_set_disctmo(vport);
 
 
 	list_add_tail(&head, &mp->list);
@@ -350,39 +348,31 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size)
 
 		/* Loop through entire NameServer list of DIDs */
 		while (Cnt >= sizeof (uint32_t)) {
-
 			/* Get next DID from NameServer List */
 			CTentry = *ctptr++;
 			Did = ((be32_to_cpu(CTentry)) & Mask_DID);
-
 			ndlp = NULL;
-			if (Did != phba->fc_myDID) {
-				/* Check for rscn processing or not */
-				ndlp = lpfc_setup_disc_node(phba, Did);
-			}
-			/* Mark all node table entries that are in the
-			   Nameserver */
+			/* Check for rscn processing or not */
+			if (Did != vport->fc_myDID)
+				ndlp = lpfc_setup_disc_node(vport, Did);
 			if (ndlp) {
-				/* NameServer Rsp */
 				lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
 						"%d:0238 Process x%x NameServer"
 						" Rsp Data: x%x x%x x%x\n",
 						phba->brd_no,
 						Did, ndlp->nlp_flag,
-						phba->fc_flag,
-						phba->fc_rscn_id_cnt);
+						vport->fc_flag,
+						vport->fc_rscn_id_cnt);
 			} else {
-				/* NameServer Rsp */
 				lpfc_printf_log(phba,
 						KERN_INFO,
 						LOG_DISCOVERY,
 						"%d:0239 Skip x%x NameServer "
 						"Rsp Data: x%x x%x x%x\n",
 						phba->brd_no,
-						Did, Size, phba->fc_flag,
-						phba->fc_rscn_id_cnt);
+						Did, Size, vport->fc_flag,
+						vport->fc_rscn_id_cnt);
 			}
-
 			if (CTentry & (be32_to_cpu(SLI_CT_LAST_ENTRY)))
 				goto nsout1;
 			Cnt -= sizeof (uint32_t);
@@ -395,15 +385,15 @@ nsout1:
 	list_del(&head);
 
 	/*
- 	 * The driver has cycled through all Nports in the RSCN payload.
- 	 * Complete the handling by cleaning up and marking the
- 	 * current driver state.
- 	 */
-	if (phba->hba_state == LPFC_HBA_READY) {
-		lpfc_els_flush_rscn(phba);
-		spin_lock_irq(phba->host->host_lock);
-		phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */
-		spin_unlock_irq(phba->host->host_lock);
+	 * The driver has cycled through all Nports in the RSCN payload.
+	 * Complete the handling by cleaning up and marking the
+	 * current driver state.
+	 */
+	if (vport->port_state == LPFC_VPORT_READY) {
+		lpfc_els_flush_rscn(vport);
+		spin_lock_irq(shost->host_lock);
+		vport->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */
+		spin_unlock_irq(shost->host_lock);
 	}
 	return 0;
 }
@@ -412,18 +402,18 @@ nsout1:
 
 
 static void
-lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-			struct lpfc_iocbq * rspiocb)
+lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+			struct lpfc_iocbq *rspiocb)
 {
+	struct lpfc_vport *vport = cmdiocb->vport;
 	IOCB_t *irsp;
-	struct lpfc_sli *psli;
 	struct lpfc_dmabuf *bmp;
 	struct lpfc_dmabuf *inp;
 	struct lpfc_dmabuf *outp;
 	struct lpfc_nodelist *ndlp;
 	struct lpfc_sli_ct_request *CTrsp;
+	int rc;
 
-	psli = &phba->sli;
 	/* we pass cmdiocb to state machine which needs rspiocb as well */
 	cmdiocb->context_un.rsp_iocb = rspiocb;
 
@@ -435,22 +425,20 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 	if (irsp->ulpStatus) {
 		if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
 			((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) ||
-			 (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED))) {
+			 (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED)))
 			goto out;
-		}
 
 		/* Check for retry */
-		if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) {
-			phba->fc_ns_retry++;
+		if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
+			vport->fc_ns_retry++;
 			/* CT command is being retried */
-			ndlp = lpfc_findnode_did(phba, NameServer_DID);
+			ndlp = lpfc_findnode_did(vport, NameServer_DID);
 			if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
-				if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) ==
-				    0) {
+				rc = lpfc_ns_cmd(vport, ndlp, SLI_CTNS_GID_FT);
+				if (rc == 0)
 					goto out;
 				}
 			}
-		}
 	} else {
 		/* Good status, continue checking */
 		CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
@@ -460,8 +448,8 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 					"%d:0208 NameServer Rsp "
 					"Data: x%x\n",
 					phba->brd_no,
-					phba->fc_flag);
-			lpfc_ns_rsp(phba, outp,
+					vport->fc_flag);
+			lpfc_ns_rsp(vport, outp,
 				    (uint32_t) (irsp->un.genreq64.bdl.bdeSize));
 		} else if (CTrsp->CommandResponse.bits.CmdRsp ==
 			   be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
@@ -473,7 +461,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 					CTrsp->CommandResponse.bits.CmdRsp,
 					(uint32_t) CTrsp->ReasonCode,
 					(uint32_t) CTrsp->Explanation,
-					phba->fc_flag);
+					vport->fc_flag);
 		} else {
 			/* NameServer Rsp Error */
 			lpfc_printf_log(phba,
@@ -485,35 +473,31 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 					CTrsp->CommandResponse.bits.CmdRsp,
 					(uint32_t) CTrsp->ReasonCode,
 					(uint32_t) CTrsp->Explanation,
-					phba->fc_flag);
+					vport->fc_flag);
 		}
 	}
 	/* Link up / RSCN discovery */
-	lpfc_disc_start(phba);
+	lpfc_disc_start(vport);
 out:
 	lpfc_free_ct_rsp(phba, outp);
 	lpfc_mbuf_free(phba, inp->virt, inp->phys);
 	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
 	kfree(inp);
 	kfree(bmp);
-	spin_lock_irq(phba->host->host_lock);
 	lpfc_sli_release_iocbq(phba, cmdiocb);
-	spin_unlock_irq(phba->host->host_lock);
 	return;
 }
 
 static void
-lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-			struct lpfc_iocbq * rspiocb)
+lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+			struct lpfc_iocbq *rspiocb)
 {
-	struct lpfc_sli *psli;
 	struct lpfc_dmabuf *bmp;
 	struct lpfc_dmabuf *inp;
 	struct lpfc_dmabuf *outp;
 	IOCB_t *irsp;
 	struct lpfc_sli_ct_request *CTrsp;
 
-	psli = &phba->sli;
 	/* we pass cmdiocb to state machine which needs rspiocb as well */
 	cmdiocb->context_un.rsp_iocb = rspiocb;
 
@@ -527,31 +511,31 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 	/* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */
 	lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
 			"%d:0209 RFT request completes ulpStatus x%x "
-			"CmdRsp x%x\n", phba->brd_no, irsp->ulpStatus,
-			CTrsp->CommandResponse.bits.CmdRsp);
+			"CmdRsp x%x, Context x%x, Tag x%x\n",
+			phba->brd_no, irsp->ulpStatus,
+			CTrsp->CommandResponse.bits.CmdRsp,
+			cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag);
 
 	lpfc_free_ct_rsp(phba, outp);
 	lpfc_mbuf_free(phba, inp->virt, inp->phys);
 	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
 	kfree(inp);
 	kfree(bmp);
-	spin_lock_irq(phba->host->host_lock);
 	lpfc_sli_release_iocbq(phba, cmdiocb);
-	spin_unlock_irq(phba->host->host_lock);
 	return;
 }
 
 static void
-lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-			struct lpfc_iocbq * rspiocb)
+lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+			struct lpfc_iocbq *rspiocb)
 {
 	lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
 	return;
 }
 
 static void
-lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-			 struct lpfc_iocbq * rspiocb)
+lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+			 struct lpfc_iocbq *rspiocb)
 {
 	lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
 	return;
@@ -566,7 +550,7 @@ lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 }
 
 void
-lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp)
+lpfc_get_hba_sym_node_name(struct lpfc_hba *phba, uint8_t *symbp)
 {
 	char fwrev[16];
 
@@ -585,8 +569,9 @@ lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp)
  *       LI_CTNS_RFT_ID
  */
 int
-lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
+lpfc_ns_cmd(struct lpfc_vport *vport, struct lpfc_nodelist * ndlp, int cmdcode)
 {
+	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_dmabuf *mp, *bmp;
 	struct lpfc_sli_ct_request *CtReq;
 	struct ulp_bde64 *bpl;
@@ -620,8 +605,8 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 			KERN_INFO,
 			LOG_DISCOVERY,
 			"%d:0236 NameServer Req Data: x%x x%x x%x\n",
-			phba->brd_no, cmdcode, phba->fc_flag,
-			phba->fc_rscn_id_cnt);
+			phba->brd_no, cmdcode, vport->fc_flag,
+			vport->fc_rscn_id_cnt);
 
 	bpl = (struct ulp_bde64 *) bmp->virt;
 	memset(bpl, 0, sizeof(struct ulp_bde64));
@@ -654,9 +639,9 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 		CtReq->CommandResponse.bits.CmdRsp =
 		    be16_to_cpu(SLI_CTNS_GID_FT);
 		CtReq->un.gid.Fc4Type = SLI_CTPT_FCP;
-		if (phba->hba_state < LPFC_HBA_READY)
-			phba->hba_state = LPFC_NS_QRY;
-		lpfc_set_disctmo(phba);
+		if (vport->port_state < LPFC_VPORT_READY)
+			vport->port_state = LPFC_NS_QRY;
+		lpfc_set_disctmo(vport);
 		cmpl = lpfc_cmpl_ct_cmd_gid_ft;
 		rsp_size = FC_MAX_NS_RSP;
 		break;
@@ -664,7 +649,7 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 	case SLI_CTNS_RFT_ID:
 		CtReq->CommandResponse.bits.CmdRsp =
 		    be16_to_cpu(SLI_CTNS_RFT_ID);
-		CtReq->un.rft.PortId = be32_to_cpu(phba->fc_myDID);
+		CtReq->un.rft.PortId = be32_to_cpu(vport->fc_myDID);
 		CtReq->un.rft.fcpReg = 1;
 		cmpl = lpfc_cmpl_ct_cmd_rft_id;
 		break;
@@ -672,7 +657,7 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 	case SLI_CTNS_RFF_ID:
 		CtReq->CommandResponse.bits.CmdRsp =
 			be16_to_cpu(SLI_CTNS_RFF_ID);
-		CtReq->un.rff.PortId = be32_to_cpu(phba->fc_myDID);
+		CtReq->un.rff.PortId = be32_to_cpu(vport->fc_myDID);
 		CtReq->un.rff.feature_res = 0;
 		CtReq->un.rff.feature_tgt = 0;
 		CtReq->un.rff.type_code = FC_FCP_DATA;
@@ -683,8 +668,8 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 	case SLI_CTNS_RNN_ID:
 		CtReq->CommandResponse.bits.CmdRsp =
 		    be16_to_cpu(SLI_CTNS_RNN_ID);
-		CtReq->un.rnn.PortId = be32_to_cpu(phba->fc_myDID);
-		memcpy(CtReq->un.rnn.wwnn,  &phba->fc_nodename,
+		CtReq->un.rnn.PortId = be32_to_cpu(vport->fc_myDID);
+		memcpy(CtReq->un.rnn.wwnn,  &vport->fc_nodename,
 		       sizeof (struct lpfc_name));
 		cmpl = lpfc_cmpl_ct_cmd_rnn_id;
 		break;
@@ -692,7 +677,7 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 	case SLI_CTNS_RSNN_NN:
 		CtReq->CommandResponse.bits.CmdRsp =
 		    be16_to_cpu(SLI_CTNS_RSNN_NN);
-		memcpy(CtReq->un.rsnn.wwnn, &phba->fc_nodename,
+		memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename,
 		       sizeof (struct lpfc_name));
 		lpfc_get_hba_sym_node_name(phba, CtReq->un.rsnn.symbname);
 		CtReq->un.rsnn.len = strlen(CtReq->un.rsnn.symbname);
@@ -700,7 +685,7 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 		break;
 	}
 
-	if (!lpfc_ct_cmd(phba, mp, bmp, ndlp, cmpl, rsp_size))
+	if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size))
 		/* On success, The cmpl function will free the buffers */
 		return 0;
 
@@ -716,8 +701,8 @@ ns_cmd_exit:
 }
 
 static void
-lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba,
-		      struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb)
+lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+		      struct lpfc_iocbq * rspiocb)
 {
 	struct lpfc_dmabuf *bmp = cmdiocb->context3;
 	struct lpfc_dmabuf *inp = cmdiocb->context1;
@@ -727,8 +712,9 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba,
 	struct lpfc_nodelist *ndlp;
 	uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp;
 	uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp;
+	struct lpfc_vport *vport = cmdiocb->vport;
 
-	ndlp = lpfc_findnode_did(phba, FDMI_DID);
+	ndlp = lpfc_findnode_did(vport, FDMI_DID);
 	if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
 		/* FDMI rsp failed */
 		lpfc_printf_log(phba,
@@ -741,18 +727,18 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba,
 
 	switch (be16_to_cpu(fdmi_cmd)) {
 	case SLI_MGMT_RHBA:
-		lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_RPA);
+		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA);
 		break;
 
 	case SLI_MGMT_RPA:
 		break;
 
 	case SLI_MGMT_DHBA:
-		lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DPRT);
+		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT);
 		break;
 
 	case SLI_MGMT_DPRT:
-		lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_RHBA);
+		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA);
 		break;
 	}
 
@@ -761,14 +747,14 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba,
 	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
 	kfree(inp);
 	kfree(bmp);
-	spin_lock_irq(phba->host->host_lock);
 	lpfc_sli_release_iocbq(phba, cmdiocb);
-	spin_unlock_irq(phba->host->host_lock);
 	return;
 }
+
 int
-lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
+lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
 {
+	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_dmabuf *mp, *bmp;
 	struct lpfc_sli_ct_request *CtReq;
 	struct ulp_bde64 *bpl;
@@ -810,7 +796,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 		        LOG_DISCOVERY,
 		        "%d:0218 FDMI Request Data: x%x x%x x%x\n",
 		        phba->brd_no,
-		       phba->fc_flag, phba->hba_state, cmdcode);
+			vport->fc_flag, vport->port_state, cmdcode);
 
 	CtReq = (struct lpfc_sli_ct_request *) mp->virt;
 
@@ -833,11 +819,11 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 			    be16_to_cpu(SLI_MGMT_RHBA);
 			CtReq->CommandResponse.bits.Size = 0;
 			rh = (REG_HBA *) & CtReq->un.PortID;
-			memcpy(&rh->hi.PortName, &phba->fc_sparam.portName,
+			memcpy(&rh->hi.PortName, &vport->fc_sparam.portName,
 			       sizeof (struct lpfc_name));
 			/* One entry (port) per adapter */
 			rh->rpl.EntryCnt = be32_to_cpu(1);
-			memcpy(&rh->rpl.pe, &phba->fc_sparam.portName,
+			memcpy(&rh->rpl.pe, &vport->fc_sparam.portName,
 			       sizeof (struct lpfc_name));
 
 			/* point to the HBA attribute block */
@@ -853,7 +839,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 			ae->ad.bits.AttrType = be16_to_cpu(NODE_NAME);
 			ae->ad.bits.AttrLen =  be16_to_cpu(FOURBYTES
 						+ sizeof (struct lpfc_name));
-			memcpy(&ae->un.NodeName, &phba->fc_sparam.nodeName,
+			memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName,
 			       sizeof (struct lpfc_name));
 			ab->EntryCnt++;
 			size += FOURBYTES + sizeof (struct lpfc_name);
@@ -991,7 +977,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 			pab = (REG_PORT_ATTRIBUTE *) & CtReq->un.PortID;
 			size = sizeof (struct lpfc_name) + FOURBYTES;
 			memcpy((uint8_t *) & pab->PortName,
-			       (uint8_t *) & phba->fc_sparam.portName,
+			       (uint8_t *) & vport->fc_sparam.portName,
 			       sizeof (struct lpfc_name));
 			pab->ab.EntryCnt = 0;
 
@@ -1053,7 +1039,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 			ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
 			ae->ad.bits.AttrType = be16_to_cpu(MAX_FRAME_SIZE);
 			ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
-			hsp = (struct serv_parm *) & phba->fc_sparam;
+			hsp = (struct serv_parm *) & vport->fc_sparam;
 			ae->un.MaxFrameSize =
 			    (((uint32_t) hsp->cmn.
 			      bbRcvSizeMsb) << 8) | (uint32_t) hsp->cmn.
@@ -1097,7 +1083,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 		CtReq->CommandResponse.bits.Size = 0;
 		pe = (PORT_ENTRY *) & CtReq->un.PortID;
 		memcpy((uint8_t *) & pe->PortName,
-		       (uint8_t *) & phba->fc_sparam.portName,
+		       (uint8_t *) & vport->fc_sparam.portName,
 		       sizeof (struct lpfc_name));
 		size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name);
 		break;
@@ -1107,7 +1093,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 		CtReq->CommandResponse.bits.Size = 0;
 		pe = (PORT_ENTRY *) & CtReq->un.PortID;
 		memcpy((uint8_t *) & pe->PortName,
-		       (uint8_t *) & phba->fc_sparam.portName,
+		       (uint8_t *) & vport->fc_sparam.portName,
 		       sizeof (struct lpfc_name));
 		size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name);
 		break;
@@ -1122,7 +1108,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
 
 	cmpl = lpfc_cmpl_ct_cmd_fdmi;
 
-	if (!lpfc_ct_cmd(phba, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP))
+	if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP))
 		return 0;
 
 	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
@@ -1146,37 +1132,36 @@ fdmi_cmd_exit:
 void
 lpfc_fdmi_tmo(unsigned long ptr)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba *)ptr;
+	struct lpfc_vport *vport = (struct lpfc_vport *)ptr;
+	struct lpfc_hba   *phba = vport->phba;
 	unsigned long iflag;
 
-	spin_lock_irqsave(phba->host->host_lock, iflag);
-	if (!(phba->work_hba_events & WORKER_FDMI_TMO)) {
-		phba->work_hba_events |= WORKER_FDMI_TMO;
+	spin_lock_irqsave(&vport->work_port_lock, iflag);
+	if (!(vport->work_port_events & WORKER_FDMI_TMO)) {
+		vport->work_port_events |= WORKER_FDMI_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);
 }
 
 void
-lpfc_fdmi_tmo_handler(struct lpfc_hba *phba)
+lpfc_fdmi_timeout_handler(struct lpfc_vport *vport)
 {
 	struct lpfc_nodelist *ndlp;
 
-	ndlp = lpfc_findnode_did(phba, FDMI_DID);
+	ndlp = lpfc_findnode_did(vport, FDMI_DID);
 	if (ndlp) {
-		if (init_utsname()->nodename[0] != '\0') {
-			lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA);
-		} else {
-			mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60);
-		}
+		if (init_utsname()->nodename[0] != '\0')
+			lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA);
+		else
+			mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60);
 	}
 	return;
 }
 
-
 void
-lpfc_decode_firmware_rev(struct lpfc_hba * phba, char *fwrevision, int flag)
+lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
 {
 	struct lpfc_sli *psli = &phba->sli;
 	lpfc_vpd_t *vp = &phba->vpd;
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 498059f3f7f43583727fd98d7ea7120a08e686d2..20bace56c8fdce53a38c2ca315b9919eee1df5bb 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -49,8 +49,8 @@ struct lpfc_work_evt {
 
 struct lpfc_nodelist {
 	struct list_head nlp_listp;
-	struct lpfc_name nlp_portname;		/* port name */
-	struct lpfc_name nlp_nodename;		/* node name */
+	struct lpfc_name nlp_portname;
+	struct lpfc_name nlp_nodename;
 	uint32_t         nlp_flag;		/* entry  flags */
 	uint32_t         nlp_DID;		/* FC D_ID of entry */
 	uint32_t         nlp_last_elscmd;	/* Last ELS cmd sent */
@@ -75,7 +75,7 @@ struct lpfc_nodelist {
 	struct timer_list   nlp_delayfunc;	/* Used for delayed ELS cmds */
 	struct fc_rport *rport;			/* Corresponding FC transport
 						   port structure */
-	struct lpfc_hba      *nlp_phba;
+	struct lpfc_vport *vport;
 	struct lpfc_work_evt els_retry_evt;
 	unsigned long last_ramp_up_time;        /* jiffy of last ramp up */
 	unsigned long last_q_full_time;		/* jiffy of last queue full */
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 638b3cd677bdd30d68e82523901b50b23ada97b3..0af33bead30242a1c6f740e94ab25617c9d30f48 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -41,23 +41,20 @@ static int lpfc_els_retry(struct lpfc_hba *, struct lpfc_iocbq *,
 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_els_chk_latt(struct lpfc_hba * phba)
 	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 @@ lpfc_els_chk_latt(struct lpfc_hba * phba)
 	 * 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 @@ lpfc_els_chk_latt(struct lpfc_hba * phba)
 }
 
 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 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp,
 					   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 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp,
 			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 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp,
 	    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 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp,
 	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 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp,
 	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 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp,
 		/* 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 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp,
 
 
 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 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
 	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 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
 				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 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
 	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 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
  * 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 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
 
 		/* 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_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
 		}
 		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 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
 			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 @@ static void
 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 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 	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 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 			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 @@ flogifail:
 	    (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 @@ out:
 }
 
 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 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
 	pring = &phba->sli.ring[LPFC_ELS_RING];
 
 	cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm));
-	elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp,
-						 ndlp->nlp_DID, ELS_CMD_FLOGI);
+	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_FLOGI);
 	if (!elsiocb)
 		return 1;
 
@@ -527,7 +531,7 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
 	/* 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 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
 
 	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 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
 }
 
 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 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba)
 	 * 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 @@ static struct lpfc_nodelist *
 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 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, struct lpfc_dmabuf *prsp,
 	/* 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 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 	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 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 			"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 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 		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 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 		   (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 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 			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 @@ out:
 }
 
 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 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry)
 	pring = &psli->ring[LPFC_ELS_RING];	/* ELS ring */
 
 	cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm));
-	elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, NULL, did,
-								ELS_CMD_PLOGI);
+	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, NULL, did,
+				     ELS_CMD_PLOGI);
 	if (!elsiocb)
 		return 1;
 
@@ -829,7 +838,7 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry)
 	/* 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 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry)
 
 	phba->fc_stat.elsXmitPLOGI++;
 	elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi;
-	spin_lock_irq(phba->host->host_lock);
 	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 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 
 	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 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 			"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 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 		   (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 @@ out:
 }
 
 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 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
 	pring = &psli->ring[LPFC_ELS_RING];	/* ELS ring */
 
 	cmdsize = (sizeof (uint32_t) + sizeof (PRLI));
-	elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp,
-					ndlp->nlp_DID, ELS_CMD_PRLI);
+	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_PRLI);
 	if (!elsiocb)
 		return 1;
 
@@ -957,79 +968,80 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
 
 	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 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 	/* 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 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 			"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 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 		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 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 		   ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) &&
 		   (irsp->un.ulpWord[4] != IOERR_LINK_DOWN) &&
 		   (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) {
-			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 @@ out:
 }
 
 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 @@ lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
 	/* 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 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 			"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 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 		   (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 @@ out:
 }
 
 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 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
 	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 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
 	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 @@ lpfc_cmpl_els_cmd(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 			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 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
 	if (!ndlp)
 		return 1;
 
-	lpfc_nlp_init(phba, ndlp, nportid);
+	lpfc_nlp_init(vport, ndlp, nportid);
+
+	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_SCR);
 
-	elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp,
-						ndlp->nlp_DID, ELS_CMD_SCR);
 	if (!elsiocb) {
 		lpfc_nlp_put(ndlp);
 		return 1;
@@ -1349,21 +1344,19 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
 
 	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 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
 	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 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
 	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 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
 
 	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 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_hba *phba, struct lpfc_nodelist * nlp)
 		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);
-
-			if (phba->num_disc_nodes == 0) {
-				phba->fc_flag &= ~FC_NDISC_ACTIVE;
-				lpfc_can_disctmo(phba);
-				if (phba->fc_flag & FC_RSCN_MODE) {
+			lpfc_more_plogi(vport);
+
+			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 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_hba *phba, struct lpfc_nodelist * nlp)
 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 @@ lpfc_els_retry_delay(unsigned long ptr)
 	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 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
 
 	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 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
 }
 
 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 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 	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 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 	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 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 			break;
 
 		case IOERR_NO_RESOURCES:
-			if (cmd == ELS_CMD_PLOGI) {
+			if (cmd == ELS_CMD_PLOGI)
 				delay = 1;
-			}
 			retry = 1;
 			break;
 
@@ -1706,10 +1700,9 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 
 		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 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 			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_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
 		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 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 
 	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 @@ static void
 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 @@ lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 			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 @@ lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 			       (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 @@ lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 	}
 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 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
 	switch (flag) {
 	case ELS_CMD_ACC:
 		cmdsize = sizeof (uint32_t);
-		elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
-					ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
+		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 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
 		break;
 	case ELS_CMD_PLOGI:
 		cmdsize = (sizeof (struct serv_parm) + sizeof (uint32_t));
-		elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
-					ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
+		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 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
 
 		*((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 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
 			ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
 
 	if (ndlp->nlp_flag & NLP_LOGO_ACC) {
-		spin_lock_irq(phba->host->host_lock);
+		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 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
 }
 
 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 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError,
 	pring = &psli->ring[LPFC_ELS_RING];	/* ELS ring */
 
 	cmdsize = 2 * sizeof (uint32_t);
-	elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
-					ndlp, ndlp->nlp_DID, ELS_CMD_LS_RJT);
+	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 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError,
 
 	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 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError,
 }
 
 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 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba,
 
 	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 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba,
 }
 
 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 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb,
 	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 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb,
 	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 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb,
 }
 
 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 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format,
 	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 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format,
 	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 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format,
 	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 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format,
 	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 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format,
 }
 
 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 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did)
 			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 @@ lpfc_rscn_recovery_check(struct lpfc_hba *phba)
 	 * 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 @@ lpfc_rscn_recovery_check(struct lpfc_hba *phba)
 		 * 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 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba,
 			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 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba,
 	/* 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_els_rcv_rscn(struct lpfc_hba * phba,
 			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 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba)
 			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 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba,
 
 	/* 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 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba,
 
 	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 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba,
 			}
 			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 @@ lpfc_els_rcv_rnid(struct lpfc_hba * phba,
 	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 @@ lpfc_els_rcv_rnid(struct lpfc_hba * phba,
 		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 @@ lpfc_els_rcv_lirr(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 	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 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 	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 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 
 	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 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 		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 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 }
 
 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 @@ lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 		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 @@ lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 
 	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 @@ lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 	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 @@ lpfc_els_rsp_rpl_acc(struct lpfc_hba * phba, uint16_t cmdsize,
 	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 @@ lpfc_els_rsp_rpl_acc(struct lpfc_hba * phba, uint16_t cmdsize,
 }
 
 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 @@ lpfc_els_rcv_rpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 		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 @@ lpfc_els_rcv_rpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 	} 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 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba,
 	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 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba,
 			/* 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 @@ lpfc_els_rcv_farpr(struct lpfc_hba * phba,
 			 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 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 	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 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 
 	/* 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 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 			 */
 
 			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 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 					 * 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 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 			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 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 		}
 
 		/* Start discovery - this should just do CLEAR_LA */
-		lpfc_disc_start(phba);
+		lpfc_disc_start(vport);
 	}
 	return 0;
 }
@@ -3187,42 +3183,37 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 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 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
 	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 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
 			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_els_timeout_handler(struct lpfc_hba *phba)
 
 		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 @@ lpfc_els_flush_cmd(struct lpfc_hba *phba)
 		    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 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
 	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 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
 	}
 
 	/* 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 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
 	}
 
 	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 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
 			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_els_unsol_event(struct lpfc_hba * phba,
 		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 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
 	/* 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 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
 				"%d:0115 Unknown ELS command x%x received from "
 				"NPORT x%x\n", phba->brd_no, cmd, did);
 		if (newnode)
-			lpfc_drop_node(phba, ndlp);
+			lpfc_drop_node(vport, ndlp);
 		break;
 	}
 
@@ -3548,7 +3550,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
 		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 @@ dropit:
 				icmd->ulpTimeout);
 		phba->fc_stat.elsRcvDrop++;
 	}
-	return;
 }
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 61caa8d379e2dc7a120481da5f8ad54f671289f5..dee875ee61657538611008ea09c0eaa45ee1675a 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -54,7 +54,7 @@ static uint8_t lpfcAlpaArray[] = {
 	0x10, 0x0F, 0x08, 0x04, 0x02, 0x01
 };
 
-static void lpfc_disc_timeout_handler(struct lpfc_hba *);
+static void lpfc_disc_timeout_handler(struct lpfc_vport *);
 
 void
 lpfc_terminate_rport_io(struct fc_rport *rport)
@@ -74,14 +74,12 @@ lpfc_terminate_rport_io(struct fc_rport *rport)
 		return;
 	}
 
-	phba = ndlp->nlp_phba;
+	phba  = ndlp->vport->phba;
 
-	spin_lock_irq(phba->host->host_lock);
 	if (ndlp->nlp_sid != NLP_NO_SID) {
 		lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
 			ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
 	}
-	spin_unlock_irq(phba->host->host_lock);
 
 	return;
 }
@@ -97,6 +95,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
 	uint8_t *name;
 	int warn_on = 0;
 	struct lpfc_hba *phba;
+	struct lpfc_vport *vport;
 
 	rdata = rport->dd_data;
 	ndlp = rdata->pnode;
@@ -113,9 +112,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
 		return;
 
 	name = (uint8_t *)&ndlp->nlp_portname;
-	phba = ndlp->nlp_phba;
-
-	spin_lock_irq(phba->host->host_lock);
+	vport = ndlp->vport;
+	phba  = vport->phba;
 
 	if (ndlp->nlp_sid != NLP_NO_SID) {
 		warn_on = 1;
@@ -123,11 +121,9 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
 		lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
 			ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
 	}
-	if (phba->fc_flag & FC_UNLOADING)
+	if (vport->load_flag & FC_UNLOADING)
 		warn_on = 0;
 
-	spin_unlock_irq(phba->host->host_lock);
-
 	if (warn_on) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
 				"%d:0203 Devloss timeout on "
@@ -150,11 +146,11 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
 				ndlp->nlp_state, ndlp->nlp_rpi);
 	}
 
-	if (!(phba->fc_flag & FC_UNLOADING) &&
+	if (!(vport->load_flag & FC_UNLOADING) &&
 	    !(ndlp->nlp_flag & NLP_DELAY_TMO) &&
 	    !(ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
 	    (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE))
-		lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RM);
+		lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM);
 	else {
 		rdata->pnode = NULL;
 		ndlp->rport = NULL;
@@ -166,33 +162,33 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
 }
 
 static void
-lpfc_work_list_done(struct lpfc_hba * phba)
+lpfc_work_list_done(struct lpfc_hba *phba)
 {
 	struct lpfc_work_evt  *evtp = NULL;
 	struct lpfc_nodelist  *ndlp;
 	int free_evt;
 
-	spin_lock_irq(phba->host->host_lock);
-	while(!list_empty(&phba->work_list)) {
+	spin_lock_irq(&phba->hbalock);
+	while (!list_empty(&phba->work_list)) {
 		list_remove_head((&phba->work_list), evtp, typeof(*evtp),
 				 evt_listp);
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(&phba->hbalock);
 		free_evt = 1;
 		switch (evtp->evt) {
 		case LPFC_EVT_ELS_RETRY:
-			ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1);
+			ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1);
 			lpfc_els_retry_delay_handler(ndlp);
 			free_evt = 0;
 			break;
 		case LPFC_EVT_ONLINE:
-			if (phba->hba_state < LPFC_LINK_DOWN)
-				*(int *)(evtp->evt_arg1)  = lpfc_online(phba);
+			if (phba->link_state < LPFC_LINK_DOWN)
+				*(int *) (evtp->evt_arg1) = lpfc_online(phba);
 			else
-				*(int *)(evtp->evt_arg1)  = 0;
+				*(int *) (evtp->evt_arg1) = 0;
 			complete((struct completion *)(evtp->evt_arg2));
 			break;
 		case LPFC_EVT_OFFLINE_PREP:
-			if (phba->hba_state >= LPFC_LINK_DOWN)
+			if (phba->link_state >= LPFC_LINK_DOWN)
 				lpfc_offline_prep(phba);
 			*(int *)(evtp->evt_arg1) = 0;
 			complete((struct completion *)(evtp->evt_arg2));
@@ -218,33 +214,32 @@ lpfc_work_list_done(struct lpfc_hba * phba)
 		case LPFC_EVT_KILL:
 			lpfc_offline(phba);
 			*(int *)(evtp->evt_arg1)
-				= (phba->stopped) ? 0 : lpfc_sli_brdkill(phba);
+				= (phba->pport->stopped)
+				        ? 0 : lpfc_sli_brdkill(phba);
 			lpfc_unblock_mgmt_io(phba);
 			complete((struct completion *)(evtp->evt_arg2));
 			break;
 		}
 		if (free_evt)
 			kfree(evtp);
-		spin_lock_irq(phba->host->host_lock);
+		spin_lock_irq(&phba->hbalock);
 	}
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 }
 
 static void
-lpfc_work_done(struct lpfc_hba * phba)
+lpfc_work_done(struct lpfc_hba *phba)
 {
 	struct lpfc_sli_ring *pring;
 	int i;
-	uint32_t ha_copy;
-	uint32_t control;
-	uint32_t work_hba_events;
+	uint32_t ha_copy, control, work_port_events;
+	struct lpfc_vport *vport;
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	ha_copy = phba->work_ha;
 	phba->work_ha = 0;
-	work_hba_events=phba->work_hba_events;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	if (ha_copy & HA_ERATT)
 		lpfc_handle_eratt(phba);
@@ -255,21 +250,25 @@ lpfc_work_done(struct lpfc_hba * phba)
 	if (ha_copy & HA_LATT)
 		lpfc_handle_latt(phba);
 
-	if (work_hba_events & WORKER_DISC_TMO)
-		lpfc_disc_timeout_handler(phba);
+	vport = phba->pport;
 
-	if (work_hba_events & WORKER_ELS_TMO)
-		lpfc_els_timeout_handler(phba);
+	work_port_events = vport->work_port_events;
 
-	if (work_hba_events & WORKER_MBOX_TMO)
+	if (work_port_events & WORKER_DISC_TMO)
+		lpfc_disc_timeout_handler(vport);
+
+	if (work_port_events & WORKER_ELS_TMO)
+		lpfc_els_timeout_handler(vport);
+
+	if (work_port_events & WORKER_MBOX_TMO)
 		lpfc_mbox_timeout_handler(phba);
 
-	if (work_hba_events & WORKER_FDMI_TMO)
-		lpfc_fdmi_tmo_handler(phba);
+	if (work_port_events & WORKER_FDMI_TMO)
+		lpfc_fdmi_timeout_handler(vport);
 
-	spin_lock_irq(phba->host->host_lock);
-	phba->work_hba_events &= ~work_hba_events;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
+	vport->work_port_events &= ~work_port_events;
+	spin_unlock_irq(&phba->hbalock);
 
 	for (i = 0; i < phba->sli.num_rings; i++, ha_copy >>= 4) {
 		pring = &phba->sli.ring[i];
@@ -286,33 +285,37 @@ lpfc_work_done(struct lpfc_hba * phba)
 			/*
 			 * Turn on Ring interrupts
 			 */
-			spin_lock_irq(phba->host->host_lock);
+			spin_lock_irq(&phba->hbalock);
 			control = readl(phba->HCregaddr);
 			control |= (HC_R0INT_ENA << i);
 			writel(control, phba->HCregaddr);
 			readl(phba->HCregaddr); /* flush */
-			spin_unlock_irq(phba->host->host_lock);
+			spin_unlock_irq(&phba->hbalock);
 		}
 	}
 
-	lpfc_work_list_done (phba);
-
+	lpfc_work_list_done(phba);
 }
 
 static int
-check_work_wait_done(struct lpfc_hba *phba) {
+check_work_wait_done(struct lpfc_hba *phba)
+{
+	struct lpfc_vport *vport = phba->pport;
+	int rc = 0;
+
+
+	if (!vport)
+		return 0;
+	spin_lock_irq(&phba->hbalock);
 
-	spin_lock_irq(phba->host->host_lock);
 	if (phba->work_ha ||
-	    phba->work_hba_events ||
+	    vport->work_port_events ||
 	    (!list_empty(&phba->work_list)) ||
-	    kthread_should_stop()) {
-		spin_unlock_irq(phba->host->host_lock);
-		return 1;
-	} else {
-		spin_unlock_irq(phba->host->host_lock);
-		return 0;
-	}
+	    kthread_should_stop())
+		rc = 1;
+
+	spin_unlock_irq(&phba->hbalock);
+	return rc;
 }
 
 int
@@ -347,7 +350,7 @@ lpfc_do_work(void *p)
  * embedding it in the IOCB.
  */
 int
-lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2,
+lpfc_workq_post_event(struct lpfc_hba *phba, void *arg1, void *arg2,
 		      uint32_t evt)
 {
 	struct lpfc_work_evt  *evtp;
@@ -364,11 +367,11 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2,
 	evtp->evt_arg2  = arg2;
 	evtp->evt       = evt;
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	list_add_tail(&evtp->evt_listp, &phba->work_list);
 	if (phba->work_wait)
 		wake_up(phba->work_wait);
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	return 1;
 }
@@ -376,75 +379,77 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2,
 int
 lpfc_linkdown(struct lpfc_hba *phba)
 {
-	struct lpfc_sli       *psli;
+	struct lpfc_vport *vport = phba->pport;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_sli   *psli;
 	struct lpfc_nodelist  *ndlp, *next_ndlp;
 	LPFC_MBOXQ_t          *mb;
 	int                   rc;
 
 	psli = &phba->sli;
-	/* sysfs or selective reset may call this routine to clean up */
-	if (phba->hba_state >= LPFC_LINK_DOWN) {
-		if (phba->hba_state == LPFC_LINK_DOWN)
-			return 0;
-
-		spin_lock_irq(phba->host->host_lock);
-		phba->hba_state = LPFC_LINK_DOWN;
-		spin_unlock_irq(phba->host->host_lock);
+	if (phba->link_state == LPFC_LINK_DOWN) {
+		return 0;
 	}
+	spin_lock_irq(&phba->hbalock);
+	if (phba->link_state > LPFC_LINK_DOWN)
+		phba->link_state = LPFC_LINK_DOWN;
+	spin_unlock_irq(&phba->hbalock);
 
-	fc_host_post_event(phba->host, fc_get_event_number(),
-			FCH_EVT_LINKDOWN, 0);
+	fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKDOWN, 0);
 
 	/* Clean up any firmware default rpi's */
-	if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) {
+	mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (mb) {
 		lpfc_unreg_did(phba, 0xffffffff, mb);
-		mb->mbox_cmpl=lpfc_sli_def_mbox_cmpl;
+		mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
 		if (lpfc_sli_issue_mbox(phba, mb, (MBX_NOWAIT | MBX_STOP_IOCB))
 		    == MBX_NOT_FINISHED) {
-			mempool_free( mb, phba->mbox_mem_pool);
+			mempool_free(mb, phba->mbox_mem_pool);
 		}
 	}
 
 	/* Cleanup any outstanding RSCN activity */
-	lpfc_els_flush_rscn(phba);
+	lpfc_els_flush_rscn(vport);
 
 	/* Cleanup any outstanding ELS commands */
-	lpfc_els_flush_cmd(phba);
+	lpfc_els_flush_cmd(vport);
 
 	/*
 	 * Issue a LINK DOWN event to all nodes.
 	 */
-	list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) {
-				/* free any ndlp's on unused list */
+	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
+				/* free any ndlp's on unused state */
 		if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
-			lpfc_drop_node(phba, ndlp);
+			lpfc_drop_node(vport, ndlp);
 		else		/* otherwise, force node recovery. */
-			rc = lpfc_disc_state_machine(phba, ndlp, NULL,
+			rc = lpfc_disc_state_machine(vport, ndlp, NULL,
 						     NLP_EVT_DEVICE_RECOVERY);
 	}
 
 	/* Setup myDID for link up if we are in pt2pt mode */
-	if (phba->fc_flag & FC_PT2PT) {
-		phba->fc_myDID = 0;
-		if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) {
+	if (vport->fc_flag & FC_PT2PT) {
+		vport->fc_myDID = 0;
+		mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+		if (mb) {
 			lpfc_config_link(phba, mb);
 			mb->mbox_cmpl=lpfc_sli_def_mbox_cmpl;
-			if (lpfc_sli_issue_mbox
-			    (phba, mb, (MBX_NOWAIT | MBX_STOP_IOCB))
+			if (lpfc_sli_issue_mbox(phba, mb,
+						(MBX_NOWAIT | MBX_STOP_IOCB))
 			    == MBX_NOT_FINISHED) {
-				mempool_free( mb, phba->mbox_mem_pool);
+				mempool_free(mb, phba->mbox_mem_pool);
 			}
 		}
-		spin_lock_irq(phba->host->host_lock);
-		phba->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI);
-		spin_unlock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
+		vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI);
+		spin_unlock_irq(shost->host_lock);
 	}
-	spin_lock_irq(phba->host->host_lock);
-	phba->fc_flag &= ~FC_LBIT;
-	spin_unlock_irq(phba->host->host_lock);
+
+	spin_lock_irq(shost->host_lock);
+	vport->fc_flag &= ~FC_LBIT;
+	spin_unlock_irq(shost->host_lock);
 
 	/* Turn off discovery timer if its running */
-	lpfc_can_disctmo(phba);
+	lpfc_can_disctmo(vport);
 
 	/* Must process IOCBs on all rings to handle ABORTed I/Os */
 	return 0;
@@ -453,46 +458,47 @@ lpfc_linkdown(struct lpfc_hba *phba)
 static int
 lpfc_linkup(struct lpfc_hba *phba)
 {
+	struct lpfc_vport *vport = phba->pport;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
 	struct lpfc_nodelist *ndlp, *next_ndlp;
 
-	fc_host_post_event(phba->host, fc_get_event_number(),
-			FCH_EVT_LINKUP, 0);
+	fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKUP, 0);
 
-	spin_lock_irq(phba->host->host_lock);
-	phba->hba_state = LPFC_LINK_UP;
-	phba->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY |
-			   FC_RSCN_MODE | FC_NLP_MORE | FC_RSCN_DISCOVERY);
-	phba->fc_flag |= FC_NDISC_ACTIVE;
-	phba->fc_ns_retry = 0;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	phba->link_state = LPFC_LINK_UP;
+	vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY |
+			    FC_RSCN_MODE | FC_NLP_MORE | FC_RSCN_DISCOVERY);
+	vport->fc_flag |= FC_NDISC_ACTIVE;
+	vport->fc_ns_retry = 0;
+	spin_unlock_irq(shost->host_lock);
 
 
-	if (phba->fc_flag & FC_LBIT) {
-		list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
+	if (vport->fc_flag & FC_LBIT) {
+		list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
 			if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) {
 				if (ndlp->nlp_type & NLP_FABRIC) {
 					/*
 					 * On Linkup its safe to clean up the
 					 * ndlp from Fabric connections.
 					 */
-					lpfc_nlp_set_state(phba, ndlp,
+					lpfc_nlp_set_state(vport, ndlp,
 							   NLP_STE_UNUSED_NODE);
 				} else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
 					/*
 					 * Fail outstanding IO now since
 					 * device is marked for PLOGI.
 					 */
-					lpfc_unreg_rpi(phba, ndlp);
+					lpfc_unreg_rpi(vport, ndlp);
 				}
 			}
 		}
 	}
 
-	/* free any ndlp's on unused list */
-	list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes,
+	/* free any ndlp's in unused state */
+	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
 				 nlp_listp) {
 		if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
-			lpfc_drop_node(phba, ndlp);
+			lpfc_drop_node(vport, ndlp);
 	}
 
 	return 0;
@@ -505,14 +511,14 @@ lpfc_linkup(struct lpfc_hba *phba)
  * handed off to the SLI layer.
  */
 void
-lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
-	struct lpfc_sli *psli;
-	MAILBOX_t *mb;
+	struct lpfc_vport *vport = pmb->vport;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_sli   *psli = &phba->sli;
+	MAILBOX_t *mb = &pmb->mb;
 	uint32_t control;
 
-	psli = &phba->sli;
-	mb = &pmb->mb;
 	/* Since we don't do discovery right now, turn these off here */
 	psli->ring[psli->extra_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
 	psli->ring[psli->fcp_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
@@ -520,32 +526,33 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 	/* Check for error */
 	if ((mb->mbxStatus) && (mb->mbxStatus != 0x1601)) {
-		/* CLEAR_LA mbox error <mbxStatus> state <hba_state> */
+		/* CLEAR_LA mbox error <mbxStatus> state <port_state> */
 		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
 				"%d:0320 CLEAR_LA mbxStatus error x%x hba "
 				"state x%x\n",
-				phba->brd_no, mb->mbxStatus, phba->hba_state);
+				phba->brd_no, mb->mbxStatus, vport->port_state);
 
-		phba->hba_state = LPFC_HBA_ERROR;
+		phba->link_state = LPFC_HBA_ERROR;
 		goto out;
 	}
 
-	if (phba->fc_flag & FC_ABORT_DISCOVERY)
+	if (vport->fc_flag & FC_ABORT_DISCOVERY)
 		goto out;
 
-	phba->num_disc_nodes = 0;
-	/* go thru NPR list and issue ELS PLOGIs */
-	if (phba->fc_npr_cnt) {
-		lpfc_els_disc_plogi(phba);
-	}
+	vport->num_disc_nodes = 0;
+	/* go thru NPR nodes and issue ELS PLOGIs */
+	if (vport->fc_npr_cnt)
+		lpfc_els_disc_plogi(vport);
 
-	if (!phba->num_disc_nodes) {
-		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) {
+		spin_lock_irq(shost->host_lock);
+		vport->fc_flag &= ~FC_NDISC_ACTIVE;
+		spin_unlock_irq(shost->host_lock);
 	}
 
-	phba->hba_state = LPFC_HBA_READY;
+	printk(KERN_ERR "%s (%d): vport ready\n",
+	       __FUNCTION__, __LINE__);
+	vport->port_state = LPFC_VPORT_READY;
 
 out:
 	/* Device Discovery completes */
@@ -555,34 +562,34 @@ out:
 			 "%d:0225 Device Discovery completes\n",
 			 phba->brd_no);
 
-	mempool_free( pmb, phba->mbox_mem_pool);
+	mempool_free(pmb, phba->mbox_mem_pool);
 
-	spin_lock_irq(phba->host->host_lock);
-	phba->fc_flag &= ~FC_ABORT_DISCOVERY;
-	if (phba->fc_flag & FC_ESTABLISH_LINK) {
-		phba->fc_flag &= ~FC_ESTABLISH_LINK;
-	}
-	spin_unlock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_ESTABLISH_LINK);
+	spin_unlock_irq(shost->host_lock);
 
 	del_timer_sync(&phba->fc_estabtmo);
 
-	lpfc_can_disctmo(phba);
+	lpfc_can_disctmo(vport);
 
 	/* turn on Link Attention interrupts */
-	spin_lock_irq(phba->host->host_lock);
+
+	spin_lock_irq(&phba->hbalock);
 	psli->sli_flag |= LPFC_PROCESS_LA;
 	control = readl(phba->HCregaddr);
 	control |= HC_LAINT_ENA;
 	writel(control, phba->HCregaddr);
 	readl(phba->HCregaddr); /* flush */
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	return;
 }
 
+
 static void
 lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
+	struct lpfc_vport *vport = pmb->vport;
 	struct lpfc_sli *psli = &phba->sli;
 	int rc;
 
@@ -592,58 +599,64 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 	mempool_free(pmb, phba->mbox_mem_pool);
 
 	if (phba->fc_topology == TOPOLOGY_LOOP &&
-		phba->fc_flag & FC_PUBLIC_LOOP &&
-		 !(phba->fc_flag & FC_LBIT)) {
+	    vport->fc_flag & FC_PUBLIC_LOOP &&
+	    !(vport->fc_flag & FC_LBIT)) {
 			/* Need to wait for FAN - use discovery timer
-			 * for timeout.  hba_state is identically
+			 * for timeout.  port_state is identically
 			 * LPFC_LOCAL_CFG_LINK while waiting for FAN
 			 */
-			lpfc_set_disctmo(phba);
+			lpfc_set_disctmo(vport);
 			return;
 		}
 
-	/* Start discovery by sending a FLOGI. hba_state is identically
+	/* Start discovery by sending a FLOGI. port_state is identically
 	 * LPFC_FLOGI while waiting for FLOGI cmpl
 	 */
-	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;
 
 out:
 	lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
 			"%d:0306 CONFIG_LINK mbxStatus error x%x "
 			"HBA state x%x\n",
-			phba->brd_no, pmb->mb.mbxStatus, phba->hba_state);
+			phba->brd_no, pmb->mb.mbxStatus, vport->port_state);
 
 	lpfc_linkdown(phba);
 
-	phba->hba_state = LPFC_HBA_ERROR;
+	phba->link_state = LPFC_HBA_ERROR;
 
 	lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
 			"%d:0200 CONFIG_LINK bad hba state x%x\n",
-			phba->brd_no, phba->hba_state);
+			phba->brd_no, vport->port_state);
 
 	lpfc_clear_la(phba, pmb);
+	printk(KERN_ERR "%s (%d): do clear_la\n",
+	       __FUNCTION__, __LINE__);
 	pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
+	pmb->vport = vport;
 	rc = lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB));
 	if (rc == MBX_NOT_FINISHED) {
 		mempool_free(pmb, phba->mbox_mem_pool);
-		lpfc_disc_flush_list(phba);
+		lpfc_disc_flush_list(vport);
 		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;
+		printk(KERN_ERR "%s (%d): vport ready\n",
+		       __FUNCTION__, __LINE__);
+		vport->port_state = LPFC_VPORT_READY;
 	}
 	return;
 }
 
 static void
-lpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
 	struct lpfc_sli *psli = &phba->sli;
 	MAILBOX_t *mb = &pmb->mb;
 	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1;
+	struct lpfc_vport  *vport = pmb->vport;
 
 
 	/* Check for error */
@@ -652,67 +665,78 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
 				"%d:0319 READ_SPARAM mbxStatus error x%x "
 				"hba state x%x>\n",
-				phba->brd_no, mb->mbxStatus, phba->hba_state);
+				phba->brd_no, mb->mbxStatus, vport->port_state);
 
 		lpfc_linkdown(phba);
-		phba->hba_state = LPFC_HBA_ERROR;
+		phba->link_state = LPFC_HBA_ERROR;
 		goto out;
 	}
 
-	memcpy((uint8_t *) & phba->fc_sparam, (uint8_t *) mp->virt,
+	memcpy((uint8_t *) &vport->fc_sparam, (uint8_t *) mp->virt,
 	       sizeof (struct serv_parm));
 	if (phba->cfg_soft_wwnn)
-		u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn);
+		u64_to_wwn(phba->cfg_soft_wwnn,
+			   vport->fc_sparam.nodeName.u.wwn);
 	if (phba->cfg_soft_wwpn)
-		u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn);
-	memcpy((uint8_t *) & phba->fc_nodename,
-	       (uint8_t *) & phba->fc_sparam.nodeName,
+		u64_to_wwn(phba->cfg_soft_wwpn,
+			   vport->fc_sparam.portName.u.wwn);
+	memcpy((uint8_t *) &vport->fc_nodename,
+	       (uint8_t *) &vport->fc_sparam.nodeName,
 	       sizeof (struct lpfc_name));
-	memcpy((uint8_t *) & phba->fc_portname,
-	       (uint8_t *) & phba->fc_sparam.portName,
+	memcpy((uint8_t *) &vport->fc_portname,
+	       (uint8_t *) &vport->fc_sparam.portName,
 	       sizeof (struct lpfc_name));
 	lpfc_mbuf_free(phba, mp->virt, mp->phys);
 	kfree(mp);
-	mempool_free( pmb, phba->mbox_mem_pool);
+	mempool_free(pmb, phba->mbox_mem_pool);
 	return;
 
 out:
 	pmb->context1 = NULL;
 	lpfc_mbuf_free(phba, mp->virt, mp->phys);
 	kfree(mp);
-	if (phba->hba_state != LPFC_CLEAR_LA) {
+	if (phba->link_state != LPFC_CLEAR_LA) {
+		struct lpfc_sli_ring *extra_ring =
+			&psli->ring[psli->extra_ring];
+		struct lpfc_sli_ring *fcp_ring  = &psli->ring[psli->fcp_ring];
+		struct lpfc_sli_ring *next_ring = &psli->ring[psli->next_ring];
+
 		lpfc_clear_la(phba, pmb);
+		printk(KERN_ERR "%s (%d): do clear_la\n",
+		       __FUNCTION__, __LINE__);
 		pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
+		pmb->vport = vport;
 		if (lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB))
 		    == MBX_NOT_FINISHED) {
-			mempool_free( pmb, 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;
+			mempool_free(pmb, phba->mbox_mem_pool);
+			lpfc_disc_flush_list(vport);
+			extra_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
+			fcp_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
+			next_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
+			printk(KERN_ERR "%s (%d): vport ready\n",
+			       __FUNCTION__, __LINE__);
+			vport->port_state = LPFC_VPORT_READY;
 		}
 	} else {
-		mempool_free( pmb, phba->mbox_mem_pool);
+		mempool_free(pmb, phba->mbox_mem_pool);
 	}
 	return;
 }
 
 static void
-lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
+lpfc_mbx_process_link_up(struct lpfc_vport *vport, READ_LA_VAR *la)
 {
-	int i;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba  = vport->phba;
 	LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox;
+	int i;
 	struct lpfc_dmabuf *mp;
 	int rc;
 
 	sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	switch (la->UlnkSpeed) {
 		case LA_1GHZ_LINK:
 			phba->fc_linkspeed = LA_1GHZ_LINK;
@@ -737,9 +761,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
 	/* Get Loop Map information */
 
 		if (la->il)
-			phba->fc_flag |= FC_LBIT;
+			vport->fc_flag |= FC_LBIT;
 
-		phba->fc_myDID = la->granted_AL_PA;
+		vport->fc_myDID = la->granted_AL_PA;
 		i = la->un.lilpBde64.tus.f.bdeSize;
 
 		if (i == 0) {
@@ -781,14 +805,15 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
 			}
 		}
 	} else {
-		phba->fc_myDID = phba->fc_pref_DID;
-		phba->fc_flag |= FC_LBIT;
+		vport->fc_myDID = phba->fc_pref_DID;
+		vport->fc_flag |= FC_LBIT;
 	}
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 
 	lpfc_linkup(phba);
 	if (sparam_mbox) {
 		lpfc_read_sparam(phba, sparam_mbox);
+		sparam_mbox->vport = vport;
 		sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
 		rc = lpfc_sli_issue_mbox(phba, sparam_mbox,
 						(MBX_NOWAIT | MBX_STOP_IOCB));
@@ -804,8 +829,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
 	}
 
 	if (cfglink_mbox) {
-		phba->hba_state = LPFC_LOCAL_CFG_LINK;
+		vport->port_state = LPFC_LOCAL_CFG_LINK;
 		lpfc_config_link(phba, cfglink_mbox);
+		cfglink_mbox->vport = vport;
 		cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link;
 		rc = lpfc_sli_issue_mbox(phba, cfglink_mbox,
 						(MBX_NOWAIT | MBX_STOP_IOCB));
@@ -815,20 +841,21 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
 }
 
 static void
-lpfc_mbx_issue_link_down(struct lpfc_hba *phba) {
+lpfc_mbx_issue_link_down(struct lpfc_hba *phba)
+{
 	uint32_t control;
 	struct lpfc_sli *psli = &phba->sli;
 
 	lpfc_linkdown(phba);
 
 	/* turn on Link Attention interrupts - no CLEAR_LA needed */
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	psli->sli_flag |= LPFC_PROCESS_LA;
 	control = readl(phba->HCregaddr);
 	control |= HC_LAINT_ENA;
 	writel(control, phba->HCregaddr);
 	readl(phba->HCregaddr); /* flush */
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 }
 
 /*
@@ -838,8 +865,10 @@ lpfc_mbx_issue_link_down(struct lpfc_hba *phba) {
  * handed off to the SLI layer.
  */
 void
-lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
+	struct lpfc_vport *vport = pmb->vport;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
 	READ_LA_VAR *la;
 	MAILBOX_t *mb = &pmb->mb;
 	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
@@ -851,9 +880,9 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 				LOG_LINK_EVENT,
 				"%d:1307 READ_LA mbox error x%x state x%x\n",
 				phba->brd_no,
-				mb->mbxStatus, phba->hba_state);
+				mb->mbxStatus, vport->port_state);
 		lpfc_mbx_issue_link_down(phba);
-		phba->hba_state = LPFC_HBA_ERROR;
+		phba->link_state = LPFC_HBA_ERROR;
 		goto lpfc_mbx_cmpl_read_la_free_mbuf;
 	}
 
@@ -861,27 +890,26 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 	memcpy(&phba->alpa_map[0], mp->virt, 128);
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	if (la->pb)
-		phba->fc_flag |= FC_BYPASSED_MODE;
+		vport->fc_flag |= FC_BYPASSED_MODE;
 	else
-		phba->fc_flag &= ~FC_BYPASSED_MODE;
-	spin_unlock_irq(phba->host->host_lock);
+		vport->fc_flag &= ~FC_BYPASSED_MODE;
+	spin_unlock_irq(shost->host_lock);
 
 	if (((phba->fc_eventTag + 1) < la->eventTag) ||
 	     (phba->fc_eventTag == la->eventTag)) {
 		phba->fc_stat.LinkMultiEvent++;
-		if (la->attType == AT_LINK_UP) {
+		if (la->attType == AT_LINK_UP)
 			if (phba->fc_eventTag != 0)
 				lpfc_linkdown(phba);
 		}
-	}
 
 	phba->fc_eventTag = la->eventTag;
 
 	if (la->attType == AT_LINK_UP) {
 		phba->fc_stat.LinkUp++;
-		if (phba->fc_flag & FC_LOOPBACK_MODE) {
+		if (phba->link_flag & LS_LOOPBACK_MODE) {
 			lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
 				"%d:1306 Link Up Event in loop back mode "
 				"x%x received Data: x%x x%x x%x x%x\n",
@@ -896,14 +924,14 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 				la->granted_AL_PA, la->UlnkSpeed,
 				phba->alpa_map[0]);
 		}
-		lpfc_mbx_process_link_up(phba, la);
+		lpfc_mbx_process_link_up(vport, la);
 	} else {
 		phba->fc_stat.LinkDown++;
 		lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
 				"%d:1305 Link Down Event x%x received "
 				"Data: x%x x%x x%x\n",
 				phba->brd_no, la->eventTag, phba->fc_eventTag,
-				phba->hba_state, phba->fc_flag);
+				phba->pport->port_state, vport->fc_flag);
 		lpfc_mbx_issue_link_down(phba);
 	}
 
@@ -921,26 +949,20 @@ lpfc_mbx_cmpl_read_la_free_mbuf:
  * handed off to the SLI layer.
  */
 void
-lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
-	struct lpfc_sli *psli;
-	MAILBOX_t *mb;
-	struct lpfc_dmabuf *mp;
-	struct lpfc_nodelist *ndlp;
-
-	psli = &phba->sli;
-	mb = &pmb->mb;
+	struct lpfc_vport  *vport = pmb->vport;
+	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1;
+	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
 
-	ndlp = (struct lpfc_nodelist *) pmb->context2;
-	mp = (struct lpfc_dmabuf *) (pmb->context1);
 
 	pmb->context1 = NULL;
 
 	/* Good status, call state machine */
-	lpfc_disc_state_machine(phba, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN);
+	lpfc_disc_state_machine(vport, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN);
 	lpfc_mbuf_free(phba, mp->virt, mp->phys);
 	kfree(mp);
-	mempool_free( pmb, phba->mbox_mem_pool);
+	mempool_free(pmb, phba->mbox_mem_pool);
 	lpfc_nlp_put(ndlp);
 
 	return;
@@ -953,20 +975,13 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
  * handed off to the SLI layer.
  */
 void
-lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
-	struct lpfc_sli *psli;
-	MAILBOX_t *mb;
-	struct lpfc_dmabuf *mp;
-	struct lpfc_nodelist *ndlp;
-	struct lpfc_nodelist *ndlp_fdmi;
-
-
-	psli = &phba->sli;
-	mb = &pmb->mb;
-
+	struct lpfc_vport  *vport = pmb->vport;
+	MAILBOX_t *mb = &pmb->mb;
+	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
+	struct lpfc_nodelist *ndlp, *ndlp_fdmi;
 	ndlp = (struct lpfc_nodelist *) pmb->context2;
-	mp = (struct lpfc_dmabuf *) (pmb->context1);
 
 	pmb->context1 = NULL;
 	pmb->context2 = NULL;
@@ -978,57 +993,59 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 		lpfc_nlp_put(ndlp);
 
 		/* 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);
 		return;
 	}
 
 	ndlp->nlp_rpi = mb->un.varWords[0];
 	ndlp->nlp_type |= NLP_FABRIC;
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
 
 	lpfc_nlp_put(ndlp);	/* Drop the reference from the mbox */
 
-	if (phba->hba_state == LPFC_FABRIC_CFG_LINK) {
+	if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
 		/* This NPort has been assigned an NPort_ID by the fabric as a
 		 * result of the completed fabric login.  Issue a State Change
 		 * Registration (SCR) ELS request to the fabric controller
 		 * (SCR_DID) so that this NPort gets RSCN events from the
 		 * fabric.
 		 */
-		lpfc_issue_els_scr(phba, SCR_DID, 0);
+		lpfc_issue_els_scr(vport, SCR_DID, 0);
 
-		ndlp = lpfc_findnode_did(phba, NameServer_DID);
+		ndlp = lpfc_findnode_did(vport, NameServer_DID);
 		if (!ndlp) {
-			/* Allocate a new node instance. If the pool is empty,
+			/* Allocate a new node instance.  If the pool is empty,
 			 * start the discovery process and skip the Nameserver
 			 * login process.  This is attempted again later on.
-			 * Otherwise, issue a Port Login (PLOGI) to NameServer.
+			 * Otherwise, issue a Port Login (PLOGI) to
+			 * the NameServer
 			 */
-			ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
+			ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
 			if (!ndlp) {
-				lpfc_disc_start(phba);
+				lpfc_disc_start(vport);
 				lpfc_mbuf_free(phba, mp->virt, mp->phys);
 				kfree(mp);
 				mempool_free(pmb, phba->mbox_mem_pool);
 				return;
 			} else {
-				lpfc_nlp_init(phba, ndlp, NameServer_DID);
+				lpfc_nlp_init(vport, ndlp, NameServer_DID);
 				ndlp->nlp_type |= NLP_FABRIC;
 			}
 		}
-		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);
 		if (phba->cfg_fdmi_on) {
 			ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
-								GFP_KERNEL);
+						  GFP_KERNEL);
 			if (ndlp_fdmi) {
-				lpfc_nlp_init(phba, ndlp_fdmi, FDMI_DID);
+				lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
 				ndlp_fdmi->nlp_type |= NLP_FABRIC;
 				ndlp_fdmi->nlp_state = NLP_STE_PLOGI_ISSUE;
-				lpfc_issue_els_plogi(phba, FDMI_DID, 0);
+				lpfc_issue_els_plogi(vport, FDMI_DID, 0);
 			}
 		}
 	}
@@ -1046,32 +1063,28 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
  * handed off to the SLI layer.
  */
 void
-lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
-	struct lpfc_sli *psli;
-	MAILBOX_t *mb;
-	struct lpfc_dmabuf *mp;
-	struct lpfc_nodelist *ndlp;
-
-	psli = &phba->sli;
-	mb = &pmb->mb;
-
-	ndlp = (struct lpfc_nodelist *) pmb->context2;
-	mp = (struct lpfc_dmabuf *) (pmb->context1);
+	MAILBOX_t *mb = &pmb->mb;
+	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
+	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
+	struct lpfc_vport *vport = pmb->vport;
 
 	if (mb->mbxStatus) {
 		lpfc_nlp_put(ndlp);
 		lpfc_mbuf_free(phba, mp->virt, mp->phys);
 		kfree(mp);
 		mempool_free(pmb, phba->mbox_mem_pool);
-		lpfc_drop_node(phba, ndlp);
+		lpfc_drop_node(vport, ndlp);
 
-		/* RegLogin failed, so just use loop map to make discovery
-		   list */
-		lpfc_disc_list_loopmap(phba);
+		/*
+		 * RegLogin failed, so just use loop map to make discovery
+		 * list
+		 */
+		lpfc_disc_list_loopmap(vport);
 
 		/* Start discovery */
-		lpfc_disc_start(phba);
+		lpfc_disc_start(vport);
 		return;
 	}
 
@@ -1079,37 +1092,39 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 	ndlp->nlp_rpi = mb->un.varWords[0];
 	ndlp->nlp_type |= NLP_FABRIC;
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
 
-	if (phba->hba_state < LPFC_HBA_READY) {
-		/* Link up discovery requires Fabrib registration. */
-		lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RNN_ID);
-		lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RSNN_NN);
-		lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFT_ID);
-		lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFF_ID);
+	if (vport->port_state < LPFC_VPORT_READY) {
+		/* Link up discovery requires Fabric registration. */
+		lpfc_ns_cmd(vport, ndlp, SLI_CTNS_RNN_ID);
+		lpfc_ns_cmd(vport, ndlp, SLI_CTNS_RSNN_NN);
+		lpfc_ns_cmd(vport, ndlp, SLI_CTNS_RFT_ID);
+		lpfc_ns_cmd(vport, ndlp, SLI_CTNS_RFF_ID);
 	}
 
-	phba->fc_ns_retry = 0;
+	vport->fc_ns_retry = 0;
 	/* Good status, issue CT Request to NameServer */
-	if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT)) {
+	if (lpfc_ns_cmd(vport, ndlp, SLI_CTNS_GID_FT)) {
 		/* Cannot issue NameServer Query, so finish up discovery */
-		lpfc_disc_start(phba);
+		lpfc_disc_start(vport);
 	}
 
 	lpfc_nlp_put(ndlp);
 	lpfc_mbuf_free(phba, mp->virt, mp->phys);
 	kfree(mp);
-	mempool_free( pmb, phba->mbox_mem_pool);
+	mempool_free(pmb, phba->mbox_mem_pool);
 
 	return;
 }
 
 static void
-lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
+lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 {
-	struct fc_rport *rport;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct fc_rport  *rport;
 	struct lpfc_rport_data *rdata;
 	struct fc_rport_identifiers rport_ids;
+	struct lpfc_hba  *phba = vport->phba;
 
 	/* Remote port has reappeared. Re-register w/ FC transport */
 	rport_ids.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
@@ -1128,7 +1143,7 @@ lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
 	    *(struct lpfc_rport_data **) ndlp->rport->dd_data) {
 		lpfc_nlp_put(ndlp);
 	}
-	ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids);
+	ndlp->rport = rport = fc_remote_port_add(shost, 0, &rport_ids);
 	if (!rport || !get_device(&rport->dev)) {
 		dev_printk(KERN_WARNING, &phba->pcidev->dev,
 			   "Warning: fc_remote_port_add failed\n");
@@ -1159,7 +1174,7 @@ lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
 }
 
 static void
-lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
+lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp)
 {
 	struct fc_rport *rport = ndlp->rport;
 	struct lpfc_rport_data *rdata = rport->dd_data;
@@ -1177,42 +1192,46 @@ lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
 }
 
 static void
-lpfc_nlp_counters(struct lpfc_hba *phba, int state, int count)
+lpfc_nlp_counters(struct lpfc_vport *vport, int state, int count)
 {
-	spin_lock_irq(phba->host->host_lock);
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
+	spin_lock_irq(shost->host_lock);
 	switch (state) {
 	case NLP_STE_UNUSED_NODE:
-		phba->fc_unused_cnt += count;
+		vport->fc_unused_cnt += count;
 		break;
 	case NLP_STE_PLOGI_ISSUE:
-		phba->fc_plogi_cnt += count;
+		vport->fc_plogi_cnt += count;
 		break;
 	case NLP_STE_ADISC_ISSUE:
-		phba->fc_adisc_cnt += count;
+		vport->fc_adisc_cnt += count;
 		break;
 	case NLP_STE_REG_LOGIN_ISSUE:
-		phba->fc_reglogin_cnt += count;
+		vport->fc_reglogin_cnt += count;
 		break;
 	case NLP_STE_PRLI_ISSUE:
-		phba->fc_prli_cnt += count;
+		vport->fc_prli_cnt += count;
 		break;
 	case NLP_STE_UNMAPPED_NODE:
-		phba->fc_unmap_cnt += count;
+		vport->fc_unmap_cnt += count;
 		break;
 	case NLP_STE_MAPPED_NODE:
-		phba->fc_map_cnt += count;
+		vport->fc_map_cnt += count;
 		break;
 	case NLP_STE_NPR_NODE:
-		phba->fc_npr_cnt += count;
+		vport->fc_npr_cnt += count;
 		break;
 	}
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 }
 
 static void
-lpfc_nlp_state_cleanup(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
+lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 		       int old_state, int new_state)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
 	if (new_state == NLP_STE_UNMAPPED_NODE) {
 		ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
 		ndlp->nlp_flag &= ~NLP_NODEV_REMOVE;
@@ -1226,19 +1245,19 @@ lpfc_nlp_state_cleanup(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
 	/* Transport interface */
 	if (ndlp->rport && (old_state == NLP_STE_MAPPED_NODE ||
 			    old_state == NLP_STE_UNMAPPED_NODE)) {
-		phba->nport_event_cnt++;
-		lpfc_unregister_remote_port(phba, ndlp);
+		vport->phba->nport_event_cnt++;
+		lpfc_unregister_remote_port(ndlp);
 	}
 
 	if (new_state ==  NLP_STE_MAPPED_NODE ||
 	    new_state == NLP_STE_UNMAPPED_NODE) {
-		phba->nport_event_cnt++;
+		vport->phba->nport_event_cnt++;
 			/*
 			 * Tell the fc transport about the port, if we haven't
 			 * already. If we have, and it's a scsi entity, be
 			 * sure to unblock any attached scsi devices
 			 */
-			lpfc_register_remote_port(phba, ndlp);
+			lpfc_register_remote_port(vport, ndlp);
 	}
 
 			/*
@@ -1251,10 +1270,10 @@ lpfc_nlp_state_cleanup(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
 	    (!ndlp->rport ||
 	     ndlp->rport->scsi_target_id == -1 ||
 	     ndlp->rport->scsi_target_id >= LPFC_MAX_TARGET)) {
-		spin_lock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag |= NLP_TGT_NO_SCSIID;
-		spin_unlock_irq(phba->host->host_lock);
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
+		spin_unlock_irq(shost->host_lock);
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
 	}
 }
 
@@ -1280,61 +1299,67 @@ lpfc_nlp_state_name(char *buffer, size_t size, int state)
 }
 
 void
-lpfc_nlp_set_state(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, int state)
+lpfc_nlp_set_state(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+		   int state)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 	int  old_state = ndlp->nlp_state;
 	char name1[16], name2[16];
 
-	lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
+	lpfc_printf_log(vport->phba, KERN_INFO, LOG_NODE,
 			"%d:0904 NPort state transition x%06x, %s -> %s\n",
-			phba->brd_no,
+			vport->phba->brd_no,
 			ndlp->nlp_DID,
 			lpfc_nlp_state_name(name1, sizeof(name1), old_state),
 			lpfc_nlp_state_name(name2, sizeof(name2), state));
 	if (old_state == NLP_STE_NPR_NODE &&
 	    (ndlp->nlp_flag & NLP_DELAY_TMO) != 0 &&
 	    state != NLP_STE_NPR_NODE)
-		lpfc_cancel_retry_delay_tmo(phba, ndlp);
+		lpfc_cancel_retry_delay_tmo(vport, ndlp);
 	if (old_state == NLP_STE_UNMAPPED_NODE) {
 		ndlp->nlp_flag &= ~NLP_TGT_NO_SCSIID;
 		ndlp->nlp_type &= ~NLP_FC_NODE;
 	}
 
 	if (list_empty(&ndlp->nlp_listp)) {
-		spin_lock_irq(phba->host->host_lock);
-		list_add_tail(&ndlp->nlp_listp, &phba->fc_nodes);
-		spin_unlock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
+		list_add_tail(&ndlp->nlp_listp, &vport->fc_nodes);
+		spin_unlock_irq(shost->host_lock);
 	} else if (old_state)
-		lpfc_nlp_counters(phba, old_state, -1);
+		lpfc_nlp_counters(vport, old_state, -1);
 
 	ndlp->nlp_state = state;
-	lpfc_nlp_counters(phba, state, 1);
-	lpfc_nlp_state_cleanup(phba, ndlp, old_state, state);
+	lpfc_nlp_counters(vport, state, 1);
+	lpfc_nlp_state_cleanup(vport, ndlp, old_state, state);
 }
 
 void
-lpfc_dequeue_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
+lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
 	if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0)
-		lpfc_cancel_retry_delay_tmo(phba, ndlp);
+		lpfc_cancel_retry_delay_tmo(vport, ndlp);
 	if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp))
-		lpfc_nlp_counters(phba, ndlp->nlp_state, -1);
-	spin_lock_irq(phba->host->host_lock);
+		lpfc_nlp_counters(vport, ndlp->nlp_state, -1);
+	spin_lock_irq(shost->host_lock);
 	list_del_init(&ndlp->nlp_listp);
-	spin_unlock_irq(phba->host->host_lock);
-	lpfc_nlp_state_cleanup(phba, ndlp, ndlp->nlp_state, 0);
+	spin_unlock_irq(shost->host_lock);
+	lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state, 0);
 }
 
 void
-lpfc_drop_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
+lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
 	if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0)
-		lpfc_cancel_retry_delay_tmo(phba, ndlp);
+		lpfc_cancel_retry_delay_tmo(vport, ndlp);
 	if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp))
-		lpfc_nlp_counters(phba, ndlp->nlp_state, -1);
-	spin_lock_irq(phba->host->host_lock);
+		lpfc_nlp_counters(vport, ndlp->nlp_state, -1);
+	spin_lock_irq(shost->host_lock);
 	list_del_init(&ndlp->nlp_listp);
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 	lpfc_nlp_put(ndlp);
 }
 
@@ -1342,11 +1367,13 @@ lpfc_drop_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
  * Start / ReStart rescue timer for Discovery / RSCN handling
  */
 void
-lpfc_set_disctmo(struct lpfc_hba * phba)
+lpfc_set_disctmo(struct lpfc_vport *vport)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
 	uint32_t tmo;
 
-	if (phba->hba_state == LPFC_LOCAL_CFG_LINK) {
+	if (vport->port_state == LPFC_LOCAL_CFG_LINK) {
 		/* For FAN, timeout should be greater then edtov */
 		tmo = (((phba->fc_edtov + 999) / 1000) + 1);
 	} else {
@@ -1356,18 +1383,18 @@ lpfc_set_disctmo(struct lpfc_hba * phba)
 		tmo = ((phba->fc_ratov * 3) + 3);
 	}
 
-	mod_timer(&phba->fc_disctmo, jiffies + HZ * tmo);
-	spin_lock_irq(phba->host->host_lock);
-	phba->fc_flag |= FC_DISC_TMO;
-	spin_unlock_irq(phba->host->host_lock);
+	mod_timer(&vport->fc_disctmo, jiffies + HZ * tmo);
+	spin_lock_irq(shost->host_lock);
+	vport->fc_flag |= FC_DISC_TMO;
+	spin_unlock_irq(shost->host_lock);
 
 	/* Start Discovery Timer state <hba_state> */
 	lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
 			"%d:0247 Start Discovery Timer state x%x "
 			"Data: x%x x%lx x%x x%x\n",
-			phba->brd_no,
-			phba->hba_state, tmo, (unsigned long)&phba->fc_disctmo,
-			phba->fc_plogi_cnt, phba->fc_adisc_cnt);
+			phba->brd_no, vport->port_state, tmo,
+			(unsigned long)&vport->fc_disctmo, vport->fc_plogi_cnt,
+			vport->fc_adisc_cnt);
 
 	return;
 }
@@ -1376,23 +1403,29 @@ lpfc_set_disctmo(struct lpfc_hba * phba)
  * Cancel rescue timer for Discovery / RSCN handling
  */
 int
-lpfc_can_disctmo(struct lpfc_hba * phba)
+lpfc_can_disctmo(struct lpfc_vport *vport)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
+	unsigned long iflags;
+
 	/* Turn off discovery timer if its running */
-	if (phba->fc_flag & FC_DISC_TMO) {
-		spin_lock_irq(phba->host->host_lock);
-		phba->fc_flag &= ~FC_DISC_TMO;
-		spin_unlock_irq(phba->host->host_lock);
-		del_timer_sync(&phba->fc_disctmo);
-		phba->work_hba_events &= ~WORKER_DISC_TMO;
+	if (vport->fc_flag & FC_DISC_TMO) {
+		spin_lock_irqsave(shost->host_lock, iflags);
+		vport->fc_flag &= ~FC_DISC_TMO;
+		spin_unlock_irqrestore(shost->host_lock, iflags);
+		del_timer_sync(&vport->fc_disctmo);
+		spin_lock_irqsave(&vport->work_port_lock, iflags);
+		vport->work_port_events &= ~WORKER_DISC_TMO;
+		spin_unlock_irqrestore(&vport->work_port_lock, iflags);
 	}
 
 	/* Cancel Discovery Timer state <hba_state> */
 	lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
 			"%d:0248 Cancel Discovery Timer state x%x "
 			"Data: x%x x%x x%x\n",
-			phba->brd_no, phba->hba_state, phba->fc_flag,
-			phba->fc_plogi_cnt, phba->fc_adisc_cnt);
+			phba->brd_no, vport->port_state, vport->fc_flag,
+			vport->fc_plogi_cnt, vport->fc_adisc_cnt);
 
 	return 0;
 }
@@ -1402,15 +1435,13 @@ lpfc_can_disctmo(struct lpfc_hba * phba)
  * Return true if iocb matches the specified nport
  */
 int
-lpfc_check_sli_ndlp(struct lpfc_hba * phba,
-		    struct lpfc_sli_ring * pring,
-		    struct lpfc_iocbq * iocb, struct lpfc_nodelist * ndlp)
+lpfc_check_sli_ndlp(struct lpfc_hba *phba,
+		    struct lpfc_sli_ring *pring,
+		    struct lpfc_iocbq *iocb,
+		    struct lpfc_nodelist *ndlp)
 {
-	struct lpfc_sli *psli;
-	IOCB_t *icmd;
-
-	psli = &phba->sli;
-	icmd = &iocb->iocb;
+	struct lpfc_sli *psli = &phba->sli;
+	IOCB_t *icmd = &iocb->iocb;
 	if (pring->ringno == LPFC_ELS_RING) {
 		switch (icmd->ulpCommand) {
 		case CMD_GEN_REQUEST64_CR:
@@ -1445,7 +1476,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba,
  * associated with nlp_rpi in the LPFC_NODELIST entry.
  */
 static int
-lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
+lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
 {
 	LIST_HEAD(completions);
 	struct lpfc_sli *psli;
@@ -1465,9 +1496,9 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
 		for (i = 0; i < psli->num_rings; i++) {
 			pring = &psli->ring[i];
 
-			spin_lock_irq(phba->host->host_lock);
+			spin_lock_irq(&phba->hbalock);
 			list_for_each_entry_safe(iocb, next_iocb, &pring->txq,
-						list) {
+						 list) {
 				/*
 				 * Check to see if iocb matches the nport we are
 				 * looking for
@@ -1481,8 +1512,7 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
 					pring->txq_cnt--;
 				}
 			}
-			spin_unlock_irq(phba->host->host_lock);
-
+			spin_unlock_irq(&phba->hbalock);
 		}
 	}
 
@@ -1490,13 +1520,14 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
 		iocb = list_get_first(&completions, struct lpfc_iocbq, list);
 		list_del(&iocb->list);
 
-		if (iocb->iocb_cmpl) {
+		if (!iocb->iocb_cmpl)
+			lpfc_sli_release_iocbq(phba, iocb);
+		else {
 			icmd = &iocb->iocb;
 			icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
 			icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
-			(iocb->iocb_cmpl) (phba, iocb, iocb);
-		} else
-			lpfc_sli_release_iocbq(phba, iocb);
+			(iocb->iocb_cmpl)(phba, iocb, iocb);
+		}
 	}
 
 	return 0;
@@ -1512,19 +1543,21 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
  * we are waiting to PLOGI back to the remote NPort.
  */
 int
-lpfc_unreg_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
+lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 {
-	LPFC_MBOXQ_t *mbox;
+	struct lpfc_hba *phba = vport->phba;
+	LPFC_MBOXQ_t    *mbox;
 	int rc;
 
 	if (ndlp->nlp_rpi) {
-		if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) {
+		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+		if (mbox) {
 			lpfc_unreg_login(phba, ndlp->nlp_rpi, mbox);
 			mbox->mbox_cmpl=lpfc_sli_def_mbox_cmpl;
 			rc = lpfc_sli_issue_mbox
 				    (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB));
 			if (rc == MBX_NOT_FINISHED)
-				mempool_free( mbox, phba->mbox_mem_pool);
+				mempool_free(mbox, phba->mbox_mem_pool);
 		}
 		lpfc_no_rpi(phba, ndlp);
 		ndlp->nlp_rpi = 0;
@@ -1538,10 +1571,11 @@ lpfc_unreg_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
  * so it can be freed.
  */
 static int
-lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
+lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 {
-	LPFC_MBOXQ_t       *mb;
-	LPFC_MBOXQ_t       *nextmb;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
+	LPFC_MBOXQ_t *mb, *nextmb;
 	struct lpfc_dmabuf *mp;
 
 	/* Cleanup node for NPort <nlp_DID> */
@@ -1551,7 +1585,7 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
 			phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag,
 			ndlp->nlp_state, ndlp->nlp_rpi);
 
-	lpfc_dequeue_node(phba, ndlp);
+	lpfc_dequeue_node(vport, ndlp);
 
 	/* cleanup any ndlp on mbox q waiting for reglogin cmpl */
 	if ((mb = phba->sli.mbox_active)) {
@@ -1562,13 +1596,13 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
 		}
 	}
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
 		if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) &&
 		   (ndlp == (struct lpfc_nodelist *) mb->context2)) {
 			mp = (struct lpfc_dmabuf *) (mb->context1);
 			if (mp) {
-				lpfc_mbuf_free(phba, mp->virt, mp->phys);
+				__lpfc_mbuf_free(phba, mp->virt, mp->phys);
 				kfree(mp);
 			}
 			list_del(&mb->list);
@@ -1576,12 +1610,12 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
 			lpfc_nlp_put(ndlp);
 		}
 	}
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	lpfc_els_abort(phba,ndlp);
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag &= ~NLP_DELAY_TMO;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 
 	ndlp->nlp_last_elscmd = 0;
 	del_timer_sync(&ndlp->nlp_delayfunc);
@@ -1589,7 +1623,7 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
 	if (!list_empty(&ndlp->els_retry_evt.evt_listp))
 		list_del_init(&ndlp->els_retry_evt.evt_listp);
 
-	lpfc_unreg_rpi(phba, ndlp);
+	lpfc_unreg_rpi(vport, ndlp);
 
 	return 0;
 }
@@ -1600,17 +1634,22 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
  * machine, defer the free till we reach the end of the state machine.
  */
 static void
-lpfc_nlp_remove(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
+lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 {
 	struct lpfc_rport_data *rdata;
 
 	if (ndlp->nlp_flag & NLP_DELAY_TMO) {
-		lpfc_cancel_retry_delay_tmo(phba, ndlp);
+		lpfc_cancel_retry_delay_tmo(vport, ndlp);
 	}
 
-	lpfc_cleanup_node(phba, ndlp);
+	lpfc_cleanup_node(vport, ndlp);
 
-	if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) {
+	/*
+	 * We should never get here with a non-NULL ndlp->rport.  But
+	 * if we do, drop the reference to the rport.  That seems the
+	 * intelligent thing to do.
+	 */
+	if (ndlp->rport && !(vport->load_flag & FC_UNLOADING)) {
 		put_device(&ndlp->rport->dev);
 		rdata = ndlp->rport->dd_data;
 		rdata->pnode = NULL;
@@ -1619,11 +1658,10 @@ lpfc_nlp_remove(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
 }
 
 static int
-lpfc_matchdid(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did)
+lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+	      uint32_t did)
 {
-	D_ID mydid;
-	D_ID ndlpdid;
-	D_ID matchdid;
+	D_ID mydid, ndlpdid, matchdid;
 
 	if (did == Bcast_DID)
 		return 0;
@@ -1637,7 +1675,7 @@ lpfc_matchdid(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did)
 		return 1;
 
 	/* Next check for area/domain identically equals 0 match */
-	mydid.un.word = phba->fc_myDID;
+	mydid.un.word = vport->fc_myDID;
 	if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) {
 		return 0;
 	}
@@ -1669,15 +1707,15 @@ lpfc_matchdid(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did)
 }
 
 /* Search for a nodelist entry */
-struct lpfc_nodelist *
-lpfc_findnode_did(struct lpfc_hba *phba, uint32_t did)
+static struct lpfc_nodelist *
+__lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did)
 {
+	struct lpfc_hba  *phba = vport->phba;
 	struct lpfc_nodelist *ndlp;
 	uint32_t data1;
 
-	spin_lock_irq(phba->host->host_lock);
-	list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
-		if (lpfc_matchdid(phba, ndlp, did)) {
+	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
+		if (lpfc_matchdid(vport, ndlp, did)) {
 			data1 = (((uint32_t) ndlp->nlp_state << 24) |
 				 ((uint32_t) ndlp->nlp_xri << 16) |
 				 ((uint32_t) ndlp->nlp_type << 8) |
@@ -1688,11 +1726,9 @@ lpfc_findnode_did(struct lpfc_hba *phba, uint32_t did)
 					phba->brd_no,
 					ndlp, ndlp->nlp_DID,
 					ndlp->nlp_flag, data1);
-			spin_unlock_irq(phba->host->host_lock);
 			return ndlp;
 		}
 	}
-	spin_unlock_irq(phba->host->host_lock);
 
 	/* FIND node did <did> NOT FOUND */
 	lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
@@ -1702,68 +1738,85 @@ lpfc_findnode_did(struct lpfc_hba *phba, uint32_t did)
 }
 
 struct lpfc_nodelist *
-lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did)
+lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did)
+{
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_nodelist *ndlp;
+
+	spin_lock_irq(shost->host_lock);
+	ndlp = __lpfc_findnode_did(vport, did);
+	spin_unlock_irq(shost->host_lock);
+	return ndlp;
+}
+
+struct lpfc_nodelist *
+lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 	struct lpfc_nodelist *ndlp;
 
-	ndlp = lpfc_findnode_did(phba, did);
+	ndlp = lpfc_findnode_did(vport, did);
 	if (!ndlp) {
-		if ((phba->fc_flag & FC_RSCN_MODE) &&
-		   ((lpfc_rscn_payload_check(phba, did) == 0)))
+		if ((vport->fc_flag & FC_RSCN_MODE) != 0 &&
+		    lpfc_rscn_payload_check(vport, did) == 0)
 			return NULL;
 		ndlp = (struct lpfc_nodelist *)
-		     mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
+		     mempool_alloc(vport->phba->nlp_mem_pool, GFP_KERNEL);
 		if (!ndlp)
 			return NULL;
-		lpfc_nlp_init(phba, ndlp, did);
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
+		lpfc_nlp_init(vport, ndlp, did);
+		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);
 		return ndlp;
 	}
-	if (phba->fc_flag & FC_RSCN_MODE) {
-		if (lpfc_rscn_payload_check(phba, did)) {
+	if (vport->fc_flag & FC_RSCN_MODE) {
+		if (lpfc_rscn_payload_check(vport, did)) {
+			spin_lock_irq(shost->host_lock);
 			ndlp->nlp_flag |= NLP_NPR_2B_DISC;
+			spin_unlock_irq(shost->host_lock);
 
 			/* Since this node is marked for discovery,
 			 * delay timeout is not needed.
 			 */
 			if (ndlp->nlp_flag & NLP_DELAY_TMO)
-				lpfc_cancel_retry_delay_tmo(phba, ndlp);
+				lpfc_cancel_retry_delay_tmo(vport, ndlp);
 		} else
 			ndlp = NULL;
 	} else {
 		if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE ||
 		    ndlp->nlp_state == NLP_STE_PLOGI_ISSUE)
 			return NULL;
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
+		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);
 	}
 	return ndlp;
 }
 
 /* Build a list of nodes to discover based on the loopmap */
 void
-lpfc_disc_list_loopmap(struct lpfc_hba * phba)
+lpfc_disc_list_loopmap(struct lpfc_vport *vport)
 {
+	struct lpfc_hba  *phba = vport->phba;
 	int j;
 	uint32_t alpa, index;
 
-	if (phba->hba_state <= LPFC_LINK_DOWN) {
+	if (!lpfc_is_link_up(phba))
 		return;
-	}
-	if (phba->fc_topology != TOPOLOGY_LOOP) {
+
+	if (phba->fc_topology != TOPOLOGY_LOOP)
 		return;
-	}
 
 	/* Check for loop map present or not */
 	if (phba->alpa_map[0]) {
 		for (j = 1; j <= phba->alpa_map[0]; j++) {
 			alpa = phba->alpa_map[j];
-
-			if (((phba->fc_myDID & 0xff) == alpa) || (alpa == 0)) {
+			if (((vport->fc_myDID & 0xff) == alpa) || (alpa == 0))
 				continue;
-			}
-			lpfc_setup_disc_node(phba, alpa);
+			lpfc_setup_disc_node(vport, alpa);
 		}
 	} else {
 		/* No alpamap, so try all alpa's */
@@ -1776,113 +1829,139 @@ lpfc_disc_list_loopmap(struct lpfc_hba * phba)
 			else
 				index = FC_MAXLOOP - j - 1;
 			alpa = lpfcAlpaArray[index];
-			if ((phba->fc_myDID & 0xff) == alpa) {
+			if ((vport->fc_myDID & 0xff) == alpa)
 				continue;
-			}
-
-			lpfc_setup_disc_node(phba, alpa);
+			lpfc_setup_disc_node(vport, alpa);
 		}
 	}
 	return;
 }
 
-/* Start Link up / RSCN discovery on NPR list */
 void
-lpfc_disc_start(struct lpfc_hba * phba)
+lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport)
 {
-	struct lpfc_sli *psli;
 	LPFC_MBOXQ_t *mbox;
+	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_sli_ring *extra_ring = &psli->ring[psli->extra_ring];
+	struct lpfc_sli_ring *fcp_ring   = &psli->ring[psli->fcp_ring];
+	struct lpfc_sli_ring *next_ring  = &psli->ring[psli->next_ring];
+	int  rc;
+
+			/* Link up discovery */
+	if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) != NULL) {
+		phba->link_state = LPFC_CLEAR_LA;
+		lpfc_clear_la(phba, mbox);
+		mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
+		mbox->vport = vport;
+		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(vport);
+			extra_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
+			fcp_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
+			next_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
+			vport->port_state = LPFC_VPORT_READY;
+		}
+	}
+}
+
+/* Start Link up / RSCN discovery on NPR nodes */
+void
+lpfc_disc_start(struct lpfc_vport *vport)
+{
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
 	struct lpfc_nodelist *ndlp, *next_ndlp;
 	uint32_t num_sent;
 	uint32_t clear_la_pending;
 	int did_changed;
-	int rc;
-
-	psli = &phba->sli;
 
-	if (phba->hba_state <= LPFC_LINK_DOWN) {
+	if (!lpfc_is_link_up(phba))
 		return;
-	}
-	if (phba->hba_state == LPFC_CLEAR_LA)
+
+	if (phba->link_state == LPFC_CLEAR_LA)
 		clear_la_pending = 1;
 	else
 		clear_la_pending = 0;
 
-	if (phba->hba_state < LPFC_HBA_READY) {
-		phba->hba_state = LPFC_DISC_AUTH;
-	}
-	lpfc_set_disctmo(phba);
+	if (vport->port_state < LPFC_VPORT_READY)
+		vport->port_state = LPFC_DISC_AUTH;
 
-	if (phba->fc_prevDID == phba->fc_myDID) {
+	lpfc_set_disctmo(vport);
+
+	if (vport->fc_prevDID == vport->fc_myDID)
 		did_changed = 0;
-	} else {
+	else
 		did_changed = 1;
-	}
-	phba->fc_prevDID = phba->fc_myDID;
-	phba->num_disc_nodes = 0;
+
+	vport->fc_prevDID = vport->fc_myDID;
+	vport->num_disc_nodes = 0;
 
 	/* Start Discovery state <hba_state> */
 	lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
 			"%d:0202 Start Discovery hba state x%x "
 			"Data: x%x x%x x%x\n",
-			phba->brd_no, phba->hba_state, phba->fc_flag,
-			phba->fc_plogi_cnt, phba->fc_adisc_cnt);
+			phba->brd_no, vport->port_state, vport->fc_flag,
+			vport->fc_plogi_cnt, vport->fc_adisc_cnt);
 
 	/* If our did changed, we MUST do PLOGI */
-	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 &&
 		    did_changed) {
-			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);
 		}
 	}
 
 	/* First do ADISCs - if any */
-	num_sent = lpfc_els_disc_adisc(phba);
+	num_sent = lpfc_els_disc_adisc(vport);
 
 	if (num_sent)
 		return;
 
-	if ((phba->hba_state < LPFC_HBA_READY) && (!clear_la_pending)) {
+	if (vport->port_state < LPFC_VPORT_READY && !clear_la_pending) {
+		if (vport->port_type == LPFC_PHYSICAL_PORT) {
 		/* If we get here, there is nothing to ADISC */
-		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;
+			printk(KERN_ERR "%s (%d): do clear_la\n",
+			       __FUNCTION__, __LINE__);
+			lpfc_issue_clear_la(phba, vport);
+		} else if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) {
+
+			vport->num_disc_nodes = 0;
+			/* go thru NPR nodes and issue ELS PLOGIs */
+			if (vport->fc_npr_cnt)
+				lpfc_els_disc_plogi(vport);
+
+			if (!vport->num_disc_nodes) {
+				spin_lock_irq(shost->host_lock);
+				vport->fc_flag &= ~FC_NDISC_ACTIVE;
+				spin_unlock_irq(shost->host_lock);
 			}
+			printk(KERN_ERR "%s (%d): vport ready\n",
+			       __FUNCTION__, __LINE__);
+			vport->port_state = LPFC_VPORT_READY;
 		}
 	} else {
 		/* Next do PLOGIs - if any */
-		num_sent = lpfc_els_disc_plogi(phba);
+		num_sent = lpfc_els_disc_plogi(vport);
 
 		if (num_sent)
 			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);
 		}
 	}
 	return;
@@ -1893,7 +1972,7 @@ lpfc_disc_start(struct lpfc_hba * phba)
  *  ring the match the sppecified nodelist.
  */
 static void
-lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
+lpfc_free_tx(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
 {
 	LIST_HEAD(completions);
 	struct lpfc_sli *psli;
@@ -1907,7 +1986,7 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
 	/* Error matching iocb on txq or txcmplq
 	 * First check the txq.
 	 */
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {
 		if (iocb->context1 != ndlp) {
 			continue;
@@ -1927,36 +2006,36 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
 			continue;
 		}
 		icmd = &iocb->iocb;
-		if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) ||
-		    (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) {
+		if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR ||
+		    icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX) {
 			lpfc_sli_issue_abort_iotag(phba, pring, iocb);
 		}
 	}
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	while (!list_empty(&completions)) {
 		iocb = list_get_first(&completions, struct lpfc_iocbq, list);
 		list_del(&iocb->list);
 
-		if (iocb->iocb_cmpl) {
+		if (!iocb->iocb_cmpl)
+			lpfc_sli_release_iocbq(phba, iocb);
+		else {
 			icmd = &iocb->iocb;
 			icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
 			icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
 			(iocb->iocb_cmpl) (phba, iocb, iocb);
-		} else
-			lpfc_sli_release_iocbq(phba, iocb);
+		}
 	}
-
-	return;
 }
 
 void
-lpfc_disc_flush_list(struct lpfc_hba * phba)
+lpfc_disc_flush_list(struct lpfc_vport *vport)
 {
 	struct lpfc_nodelist *ndlp, *next_ndlp;
+	struct lpfc_hba *phba = vport->phba;
 
-	if (phba->fc_plogi_cnt || phba->fc_adisc_cnt) {
-		list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes,
+	if (vport->fc_plogi_cnt || vport->fc_adisc_cnt) {
+		list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
 					 nlp_listp) {
 			if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE ||
 			    ndlp->nlp_state == NLP_STE_ADISC_ISSUE) {
@@ -1985,47 +2064,51 @@ lpfc_disc_flush_list(struct lpfc_hba * phba)
 void
 lpfc_disc_timeout(unsigned long ptr)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba *)ptr;
+	struct lpfc_vport *vport = (struct lpfc_vport *) ptr;
+	struct lpfc_hba   *phba = vport->phba;
 	unsigned long flags = 0;
 
 	if (unlikely(!phba))
 		return;
 
-	spin_lock_irqsave(phba->host->host_lock, flags);
-	if (!(phba->work_hba_events & WORKER_DISC_TMO)) {
-		phba->work_hba_events |= WORKER_DISC_TMO;
+	if ((vport->work_port_events & WORKER_DISC_TMO) == 0) {
+		spin_lock_irqsave(&vport->work_port_lock, flags);
+		vport->work_port_events |= WORKER_DISC_TMO;
+		spin_unlock_irqrestore(&vport->work_port_lock, flags);
+
 		if (phba->work_wait)
 			wake_up(phba->work_wait);
 	}
-	spin_unlock_irqrestore(phba->host->host_lock, flags);
 	return;
 }
 
 static void
-lpfc_disc_timeout_handler(struct lpfc_hba *phba)
+lpfc_disc_timeout_handler(struct lpfc_vport *vport)
 {
-	struct lpfc_sli *psli;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
+	struct lpfc_sli  *psli = &phba->sli;
 	struct lpfc_nodelist *ndlp, *next_ndlp;
-	LPFC_MBOXQ_t *clearlambox, *initlinkmbox;
+	LPFC_MBOXQ_t    *clearlambox, *initlinkmbox;
 	int rc, clrlaerr = 0;
 
-	if (unlikely(!phba))
+	if (!(vport->fc_flag & FC_DISC_TMO))
 		return;
 
-	if (!(phba->fc_flag & FC_DISC_TMO))
-		return;
-
-	psli = &phba->sli;
 
-	spin_lock_irq(phba->host->host_lock);
-	phba->fc_flag &= ~FC_DISC_TMO;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	vport->fc_flag &= ~FC_DISC_TMO;
+	spin_unlock_irq(shost->host_lock);
 
-	switch (phba->hba_state) {
+	printk(KERN_ERR "%s (%d): link_state = %d, port_state = %d\n",
+	       __FUNCTION__, __LINE__, phba->link_state, vport->port_state);
+	switch (vport->port_state) {
 
 	case LPFC_LOCAL_CFG_LINK:
-	/* hba_state is identically LPFC_LOCAL_CFG_LINK while waiting for FAN */
-		/* FAN timeout */
+	/* port_state is identically  LPFC_LOCAL_CFG_LINK while waiting for
+	 * FAN
+	 */
+				/* FAN timeout */
 		lpfc_printf_log(phba,
 				 KERN_WARNING,
 				 LOG_DISCOVERY,
@@ -2033,27 +2116,27 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
 				 phba->brd_no);
 
 		/* Start discovery by sending FLOGI, clean up old rpis */
-		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;
 			if (ndlp->nlp_type & NLP_FABRIC) {
 				/* Clean up the ndlp on Fabric connections */
-				lpfc_drop_node(phba, ndlp);
+				lpfc_drop_node(vport, ndlp);
 			} else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
 				/* Fail outstanding IO now since 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);
 		break;
 
 	case LPFC_FLOGI:
-	/* hba_state is identically LPFC_FLOGI while waiting for FLOGI cmpl */
+	/* port_state is identically LPFC_FLOGI while waiting for FLOGI cmpl */
 		/* Initial FLOGI timeout */
 		lpfc_printf_log(phba,
 				 KERN_ERR,
@@ -2066,10 +2149,10 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
 		 */
 
 		/* 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);
 		break;
 
 	case LPFC_FABRIC_CFG_LINK:
@@ -2080,11 +2163,11 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
 				"login\n", phba->brd_no);
 
 		/* Next look for NameServer ndlp */
-		ndlp = lpfc_findnode_did(phba, NameServer_DID);
+		ndlp = lpfc_findnode_did(vport, NameServer_DID);
 		if (ndlp)
 			lpfc_nlp_put(ndlp);
 		/* Start discovery */
-		lpfc_disc_start(phba);
+		lpfc_disc_start(vport);
 		break;
 
 	case LPFC_NS_QRY:
@@ -2093,17 +2176,17 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
 				"%d:0224 NameServer Query timeout "
 				"Data: x%x x%x\n",
 				phba->brd_no,
-				phba->fc_ns_retry, LPFC_MAX_NS_RETRY);
+				vport->fc_ns_retry, LPFC_MAX_NS_RETRY);
 
-		ndlp = lpfc_findnode_did(phba, NameServer_DID);
+		ndlp = lpfc_findnode_did(vport, NameServer_DID);
 		if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
-			if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) {
+			if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
 				/* Try it one more time */
-				rc = lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT);
+				rc = lpfc_ns_cmd(vport, ndlp, SLI_CTNS_GID_FT);
 				if (rc == 0)
 					break;
 			}
-			phba->fc_ns_retry = 0;
+			vport->fc_ns_retry = 0;
 		}
 
 		/* Nothing to authenticate, so CLEAR_LA right now */
@@ -2114,13 +2197,16 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
 					"%d:0226 Device Discovery "
 					"completion error\n",
 					phba->brd_no);
-			phba->hba_state = LPFC_HBA_ERROR;
+			phba->link_state = LPFC_HBA_ERROR;
 			break;
 		}
 
-		phba->hba_state = LPFC_CLEAR_LA;
+		phba->link_state = LPFC_CLEAR_LA;
 		lpfc_clear_la(phba, clearlambox);
+		printk(KERN_ERR "%s (%d): do clear_la\n",
+		       __FUNCTION__, __LINE__);
 		clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
+		clearlambox->vport = vport;
 		rc = lpfc_sli_issue_mbox(phba, clearlambox,
 					 (MBX_NOWAIT | MBX_STOP_IOCB));
 		if (rc == MBX_NOT_FINISHED) {
@@ -2136,7 +2222,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
 					"%d:0206 Device Discovery "
 					"completion error\n",
 					phba->brd_no);
-			phba->hba_state = LPFC_HBA_ERROR;
+			phba->link_state = LPFC_HBA_ERROR;
 			break;
 		}
 
@@ -2159,7 +2245,8 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
 				 LOG_DISCOVERY,
 				 "%d:0227 Node Authentication timeout\n",
 				 phba->brd_no);
-		lpfc_disc_flush_list(phba);
+		lpfc_disc_flush_list(vport);
+
 		clearlambox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 		if (!clearlambox) {
 			clrlaerr = 1;
@@ -2167,12 +2254,15 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
 					"%d:0207 Device Discovery "
 					"completion error\n",
 					phba->brd_no);
-			phba->hba_state = LPFC_HBA_ERROR;
+				phba->link_state = LPFC_HBA_ERROR;
 			break;
 		}
-		phba->hba_state = LPFC_CLEAR_LA;
+		phba->link_state = LPFC_CLEAR_LA;
 		lpfc_clear_la(phba, clearlambox);
+		printk(KERN_ERR "%s (%d): do clear_la\n",
+		       __FUNCTION__, __LINE__);
 		clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
+		clearlambox->vport = vport;
 		rc = lpfc_sli_issue_mbox(phba, clearlambox,
 					 (MBX_NOWAIT | MBX_STOP_IOCB));
 		if (rc == MBX_NOT_FINISHED) {
@@ -2181,40 +2271,73 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
 		}
 		break;
 
-	case LPFC_CLEAR_LA:
-	/* CLEAR LA timeout */
-		lpfc_printf_log(phba,
-				 KERN_ERR,
-				 LOG_DISCOVERY,
-				 "%d:0228 CLEAR LA timeout\n",
-				 phba->brd_no);
-		clrlaerr = 1;
-		break;
-
-	case LPFC_HBA_READY:
-		if (phba->fc_flag & FC_RSCN_MODE) {
+	case LPFC_VPORT_READY:
+		if (vport->fc_flag & FC_RSCN_MODE) {
 			lpfc_printf_log(phba,
 					KERN_ERR,
 					LOG_DISCOVERY,
 					"%d:0231 RSCN timeout Data: x%x x%x\n",
 					phba->brd_no,
-					phba->fc_ns_retry, LPFC_MAX_NS_RETRY);
+					vport->fc_ns_retry, LPFC_MAX_NS_RETRY);
 
 			/* Cleanup any outstanding ELS commands */
-			lpfc_els_flush_cmd(phba);
+			lpfc_els_flush_cmd(vport);
 
-			lpfc_els_flush_rscn(phba);
-			lpfc_disc_flush_list(phba);
+			lpfc_els_flush_rscn(vport);
+			lpfc_disc_flush_list(vport);
 		}
 		break;
+
+	case LPFC_STATE_UNKNOWN:
+	case LPFC_NS_REG:
+	case LPFC_BUILD_DISC_LIST:
+		lpfc_printf_log(phba,
+				KERN_ERR,
+				LOG_DISCOVERY,
+				"%d:0229 Unexpected discovery timeout, vport "
+				"State x%x\n",
+				vport->port_state,
+				phba->brd_no);
+
+		break;
+	}
+
+	switch (phba->link_state) {
+	case LPFC_CLEAR_LA:
+	/* CLEAR LA timeout */
+		lpfc_printf_log(phba,
+				KERN_ERR,
+				LOG_DISCOVERY,
+				"%d:0228 CLEAR LA timeout\n",
+				phba->brd_no);
+		clrlaerr = 1;
+		break;
+
+	case LPFC_LINK_UNKNOWN:
+	case LPFC_WARM_START:
+	case LPFC_INIT_START:
+	case LPFC_INIT_MBX_CMDS:
+	case LPFC_LINK_DOWN:
+	case LPFC_LINK_UP:
+	case LPFC_HBA_ERROR:
+		lpfc_printf_log(phba,
+				KERN_ERR,
+				LOG_DISCOVERY,
+				"%d:0230 Unexpected timeout, hba link "
+				"state x%x\n",
+				phba->brd_no, phba->link_state);
+		clrlaerr = 1;
+		break;
 	}
 
 	if (clrlaerr) {
-		lpfc_disc_flush_list(phba);
+		lpfc_disc_flush_list(vport);
 		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;
+		printk(KERN_ERR "%s (%d): vport ready\n",
+		       __FUNCTION__, __LINE__);
+		vport->port_state = LPFC_VPORT_READY;
 	}
 
 	return;
@@ -2227,37 +2350,29 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
  * handed off to the SLI layer.
  */
 void
-lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
-	struct lpfc_sli *psli;
-	MAILBOX_t *mb;
-	struct lpfc_dmabuf *mp;
-	struct lpfc_nodelist *ndlp;
-
-	psli = &phba->sli;
-	mb = &pmb->mb;
-
-	ndlp = (struct lpfc_nodelist *) pmb->context2;
-	mp = (struct lpfc_dmabuf *) (pmb->context1);
+	MAILBOX_t *mb = &pmb->mb;
+	struct lpfc_dmabuf   *mp = (struct lpfc_dmabuf *) (pmb->context1);
+	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
+	struct lpfc_vport    *vport = pmb->vport;
 
 	pmb->context1 = NULL;
 
 	ndlp->nlp_rpi = mb->un.varWords[0];
 	ndlp->nlp_type |= NLP_FABRIC;
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
 
-	/* Start issuing Fabric-Device Management Interface (FDMI)
-	 * command to 0xfffffa (FDMI well known port)
+	/*
+	 * Start issuing Fabric-Device Management Interface (FDMI) command to
+	 * 0xfffffa (FDMI well known port) or Delay issuing FDMI command if
+	 * fdmi-on=2 (supporting RPA/hostnmae)
 	 */
-	if (phba->cfg_fdmi_on == 1) {
-		lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA);
-	} else {
-		/*
-		 * Delay issuing FDMI command if fdmi-on=2
-		 * (supporting RPA/hostnmae)
-		 */
-		mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60);
-	}
+
+	if (phba->cfg_fdmi_on == 1)
+		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA);
+	else
+		mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60);
 
 				/* Mailbox took a reference to the node */
 	lpfc_nlp_put(ndlp);
@@ -2283,16 +2398,12 @@ lpfc_filter_by_wwpn(struct lpfc_nodelist *ndlp, void *param)
 		      sizeof(ndlp->nlp_portname)) == 0;
 }
 
-/*
- * Search node lists for a remote port matching filter criteria
- * Caller needs to hold host_lock before calling this routine.
- */
 struct lpfc_nodelist *
-__lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param)
+__lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
 {
 	struct lpfc_nodelist *ndlp;
 
-	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 &&
 		    filter(ndlp, param))
 			return ndlp;
@@ -2305,54 +2416,58 @@ __lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param)
  * This routine is used when the caller does NOT have host_lock.
  */
 struct lpfc_nodelist *
-lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param)
+lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
 {
+	struct Scsi_Host     *shost = lpfc_shost_from_vport(vport);
 	struct lpfc_nodelist *ndlp;
 
-	spin_lock_irq(phba->host->host_lock);
-	ndlp = __lpfc_find_node(phba, filter, param);
-	spin_unlock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	ndlp = __lpfc_find_node(vport, filter, param);
+	spin_unlock_irq(shost->host_lock);
 	return ndlp;
 }
 
 /*
  * This routine looks up the ndlp lists for the given RPI. If rpi found it
- * returns the node list pointer else return NULL.
+ * returns the node list element pointer else return NULL.
  */
 struct lpfc_nodelist *
-__lpfc_findnode_rpi(struct lpfc_hba *phba, uint16_t rpi)
+__lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
 {
-	return __lpfc_find_node(phba, lpfc_filter_by_rpi, &rpi);
+	return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi);
 }
 
 struct lpfc_nodelist *
-lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi)
+lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 	struct lpfc_nodelist *ndlp;
 
-	spin_lock_irq(phba->host->host_lock);
-	ndlp = __lpfc_findnode_rpi(phba, rpi);
-	spin_unlock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	ndlp = __lpfc_findnode_rpi(vport, rpi);
+	spin_unlock_irq(shost->host_lock);
 	return ndlp;
 }
 
 /*
  * This routine looks up the ndlp lists for the given WWPN. If WWPN found it
- * returns the node list pointer else return NULL.
+ * returns the node element list pointer else return NULL.
  */
 struct lpfc_nodelist *
-lpfc_findnode_wwpn(struct lpfc_hba *phba, struct lpfc_name *wwpn)
+lpfc_findnode_wwpn(struct lpfc_vport *vport, struct lpfc_name *wwpn)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 	struct lpfc_nodelist *ndlp;
 
-	spin_lock_irq(phba->host->host_lock);
-	ndlp = __lpfc_find_node(phba, lpfc_filter_by_wwpn, wwpn);
-	spin_unlock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	ndlp = __lpfc_find_node(vport, lpfc_filter_by_wwpn, wwpn);
+	spin_unlock_irq(shost->host_lock);
 	return NULL;
 }
 
 void
-lpfc_nlp_init(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did)
+lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+	      uint32_t did)
 {
 	memset(ndlp, 0, sizeof (struct lpfc_nodelist));
 	INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp);
@@ -2360,7 +2475,7 @@ lpfc_nlp_init(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did)
 	ndlp->nlp_delayfunc.function = lpfc_els_retry_delay;
 	ndlp->nlp_delayfunc.data = (unsigned long)ndlp;
 	ndlp->nlp_DID = did;
-	ndlp->nlp_phba = phba;
+	ndlp->vport = vport;
 	ndlp->nlp_sid = NLP_NO_SID;
 	INIT_LIST_HEAD(&ndlp->nlp_listp);
 	kref_init(&ndlp->kref);
@@ -2372,8 +2487,8 @@ lpfc_nlp_release(struct kref *kref)
 {
 	struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist,
 						  kref);
-	lpfc_nlp_remove(ndlp->nlp_phba, ndlp);
-	mempool_free(ndlp, ndlp->nlp_phba->nlp_mem_pool);
+	lpfc_nlp_remove(ndlp->vport, ndlp);
+	mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool);
 }
 
 struct lpfc_nodelist *
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 2623a9bc7775f0f4fe8bd5026f8964303ad42ee2..c4be6dc00c4c681d866af1b34422effafa4ee39f 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -312,8 +312,7 @@ struct csp {
 
 #ifdef __BIG_ENDIAN_BITFIELD
 	uint16_t increasingOffset:1;	/* FC Word 1, bit 31 */
-	uint16_t randomOffset:1;	/* FC Word 1, bit 30 */
-	uint16_t word1Reserved2:1;	/* FC Word 1, bit 29 */
+	uint16_t response_multiple_Nport:1;	/* FC Word 1, bit 29 */
 	uint16_t fPort:1;	/* FC Word 1, bit 28 */
 	uint16_t altBbCredit:1;	/* FC Word 1, bit 27 */
 	uint16_t edtovResolution:1;	/* FC Word 1, bit 26 */
@@ -2178,8 +2177,8 @@ typedef struct {
 #define  DMP_RSP_OFFSET          0x14   /* word 5 contains first word of rsp */
 #define  DMP_RSP_SIZE            0x6C   /* maximum of 27 words of rsp data */
 
-/* Structure for MB Command CONFIG_PORT (0x88) */
 
+/* Structure for MB Command CONFIG_PORT (0x88) */
 typedef struct {
 	uint32_t pcbLen;
 	uint32_t pcbLow;       /* bit 31:0  of memory based port config block */
@@ -2742,15 +2741,15 @@ struct lpfc_sli2_slim {
 	IOCB_t IOCBs[MAX_SLI2_IOCB];
 };
 
-/*******************************************************************
-This macro check PCI device to allow special handling for LC HBAs.
-
-Parameters:
-device : struct pci_dev 's device field
-
-return 1 => TRUE
-       0 => FALSE
- *******************************************************************/
+/*
+ * This function checks PCI device to allow special handling for LC HBAs.
+ *
+ * Parameters:
+ * device : struct pci_dev 's device field
+ *
+ * return 1 => TRUE
+ *        0 => FALSE
+ */
 static inline int
 lpfc_is_LC_HBA(unsigned short device)
 {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index dcb4ba0ecee1825067b2344562ab0e21d4df0601..e11c4cda0f3fad41dc6b9ec084ba9779c4b6d374 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -49,6 +49,8 @@ static int lpfc_post_rcv_buf(struct lpfc_hba *);
 static struct scsi_transport_template *lpfc_transport_template = NULL;
 static DEFINE_IDR(lpfc_hba_index);
 
+
+
 /************************************************************************/
 /*                                                                      */
 /*    lpfc_config_port_prep                                             */
@@ -61,7 +63,7 @@ static DEFINE_IDR(lpfc_hba_index);
 /*                                                                      */
 /************************************************************************/
 int
-lpfc_config_port_prep(struct lpfc_hba * phba)
+lpfc_config_port_prep(struct lpfc_hba *phba)
 {
 	lpfc_vpd_t *vp = &phba->vpd;
 	int i = 0, rc;
@@ -75,12 +77,12 @@ lpfc_config_port_prep(struct lpfc_hba * phba)
 
 	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!pmb) {
-		phba->hba_state = LPFC_HBA_ERROR;
+		phba->link_state = LPFC_HBA_ERROR;
 		return -ENOMEM;
 	}
 
 	mb = &pmb->mb;
-	phba->hba_state = LPFC_INIT_MBX_CMDS;
+	phba->link_state = LPFC_INIT_MBX_CMDS;
 
 	if (lpfc_is_LC_HBA(phba->pcidev->device)) {
 		if (init_key) {
@@ -112,7 +114,9 @@ lpfc_config_port_prep(struct lpfc_hba * phba)
 			return -ERESTART;
 		}
 		memcpy(phba->wwnn, (char *)mb->un.varRDnvp.nodename,
-		       sizeof (mb->un.varRDnvp.nodename));
+		       sizeof(phba->wwnn));
+		memcpy(phba->wwpn, (char *)mb->un.varRDnvp.portname,
+		       sizeof(phba->wwpn));
 	}
 
 	/* Setup and issue mailbox READ REV command */
@@ -212,37 +216,24 @@ out_free_mbox:
 /*                                                                      */
 /************************************************************************/
 int
-lpfc_config_port_post(struct lpfc_hba * phba)
+lpfc_config_port_post(struct lpfc_hba *phba)
 {
+	struct lpfc_vport *vport = phba->pport;
 	LPFC_MBOXQ_t *pmb;
 	MAILBOX_t *mb;
 	struct lpfc_dmabuf *mp;
 	struct lpfc_sli *psli = &phba->sli;
 	uint32_t status, timeout;
-	int i, j, rc;
+	int i, j;
+	int rc;
 
 	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!pmb) {
-		phba->hba_state = LPFC_HBA_ERROR;
+		phba->link_state = LPFC_HBA_ERROR;
 		return -ENOMEM;
 	}
 	mb = &pmb->mb;
 
-	lpfc_config_link(phba, pmb);
-	rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
-	if (rc != MBX_SUCCESS) {
-		lpfc_printf_log(phba,
-				KERN_ERR,
-				LOG_INIT,
-				"%d:0447 Adapter failed init, mbxCmd x%x "
-				"CONFIG_LINK mbxStatus x%x\n",
-				phba->brd_no,
-				mb->mbxCommand, mb->mbxStatus);
-		phba->hba_state = LPFC_HBA_ERROR;
-		mempool_free( pmb, phba->mbox_mem_pool);
-		return -EIO;
-	}
-
 	/* Get login parameters for NID.  */
 	lpfc_read_sparam(phba, pmb);
 	if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
@@ -253,7 +244,7 @@ lpfc_config_port_post(struct lpfc_hba * phba)
 				"READ_SPARM mbxStatus x%x\n",
 				phba->brd_no,
 				mb->mbxCommand, mb->mbxStatus);
-		phba->hba_state = LPFC_HBA_ERROR;
+		phba->link_state = LPFC_HBA_ERROR;
 		mp = (struct lpfc_dmabuf *) pmb->context1;
 		mempool_free( pmb, phba->mbox_mem_pool);
 		lpfc_mbuf_free(phba, mp->virt, mp->phys);
@@ -263,25 +254,27 @@ lpfc_config_port_post(struct lpfc_hba * phba)
 
 	mp = (struct lpfc_dmabuf *) pmb->context1;
 
-	memcpy(&phba->fc_sparam, mp->virt, sizeof (struct serv_parm));
+	memcpy(&vport->fc_sparam, mp->virt, sizeof (struct serv_parm));
 	lpfc_mbuf_free(phba, mp->virt, mp->phys);
 	kfree(mp);
 	pmb->context1 = NULL;
 
 	if (phba->cfg_soft_wwnn)
-		u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn);
+		u64_to_wwn(phba->cfg_soft_wwnn,
+			   vport->fc_sparam.nodeName.u.wwn);
 	if (phba->cfg_soft_wwpn)
-		u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn);
-	memcpy(&phba->fc_nodename, &phba->fc_sparam.nodeName,
+		u64_to_wwn(phba->cfg_soft_wwpn,
+			   vport->fc_sparam.portName.u.wwn);
+	memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName,
 	       sizeof (struct lpfc_name));
-	memcpy(&phba->fc_portname, &phba->fc_sparam.portName,
+	memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
 	       sizeof (struct lpfc_name));
 	/* If no serial number in VPD data, use low 6 bytes of WWNN */
 	/* This should be consolidated into parse_vpd ? - mr */
 	if (phba->SerialNumber[0] == 0) {
 		uint8_t *outptr;
 
-		outptr = &phba->fc_nodename.u.s.IEEE[0];
+		outptr = &vport->fc_nodename.u.s.IEEE[0];
 		for (i = 0; i < 12; i++) {
 			status = *outptr++;
 			j = ((status & 0xf0) >> 4);
@@ -311,7 +304,7 @@ lpfc_config_port_post(struct lpfc_hba * phba)
 				"READ_CONFIG, mbxStatus x%x\n",
 				phba->brd_no,
 				mb->mbxCommand, mb->mbxStatus);
-		phba->hba_state = LPFC_HBA_ERROR;
+		phba->link_state = LPFC_HBA_ERROR;
 		mempool_free( pmb, phba->mbox_mem_pool);
 		return -EIO;
 	}
@@ -348,7 +341,7 @@ lpfc_config_port_post(struct lpfc_hba * phba)
 			phba->cfg_link_speed = LINK_SPEED_AUTO;
 	}
 
-	phba->hba_state = LPFC_LINK_DOWN;
+	phba->link_state = LPFC_LINK_DOWN;
 
 	/* Only process IOCBs on ring 0 till hba_state is READY */
 	if (psli->ring[psli->extra_ring].cmdringaddr)
@@ -362,7 +355,7 @@ lpfc_config_port_post(struct lpfc_hba * phba)
 	lpfc_post_rcv_buf(phba);
 
 	/* Enable appropriate host interrupts */
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	status = readl(phba->HCregaddr);
 	status |= HC_MBINT_ENA | HC_ERINT_ENA | HC_LAINT_ENA;
 	if (psli->num_rings > 0)
@@ -380,13 +373,13 @@ lpfc_config_port_post(struct lpfc_hba * phba)
 
 	writel(status, phba->HCregaddr);
 	readl(phba->HCregaddr); /* flush */
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	/*
 	 * Setup the ring 0 (els)  timeout handler
 	 */
 	timeout = phba->fc_ratov << 1;
-	mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout);
+	mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout);
 
 	lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
 	pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
@@ -408,7 +401,7 @@ lpfc_config_port_post(struct lpfc_hba * phba)
 		writel(0xffffffff, phba->HAregaddr);
 		readl(phba->HAregaddr); /* flush */
 
-		phba->hba_state = LPFC_HBA_ERROR;
+		phba->link_state = LPFC_HBA_ERROR;
 		if (rc != MBX_BUSY)
 			mempool_free(pmb, phba->mbox_mem_pool);
 		return -EIO;
@@ -429,18 +422,20 @@ lpfc_config_port_post(struct lpfc_hba * phba)
 /*                                                                      */
 /************************************************************************/
 int
-lpfc_hba_down_prep(struct lpfc_hba * phba)
+lpfc_hba_down_prep(struct lpfc_hba *phba)
 {
+	struct lpfc_vport *vport = phba->pport;
+
 	/* Disable interrupts */
 	writel(0, phba->HCregaddr);
 	readl(phba->HCregaddr); /* flush */
 
-	/* Cleanup potential discovery resources */
-	lpfc_els_flush_rscn(phba);
-	lpfc_els_flush_cmd(phba);
-	lpfc_disc_flush_list(phba);
+				/* Cleanup potential discovery resources */
+	lpfc_els_flush_rscn(vport);
+	lpfc_els_flush_cmd(vport);
+	lpfc_disc_flush_list(vport);
 
-	return (0);
+	return 0;
 }
 
 /************************************************************************/
@@ -453,7 +448,7 @@ lpfc_hba_down_prep(struct lpfc_hba * phba)
 /*                                                                      */
 /************************************************************************/
 int
-lpfc_hba_down_post(struct lpfc_hba * phba)
+lpfc_hba_down_post(struct lpfc_hba *phba)
 {
 	struct lpfc_sli *psli = &phba->sli;
 	struct lpfc_sli_ring *pring;
@@ -486,11 +481,14 @@ lpfc_hba_down_post(struct lpfc_hba * phba)
 /*                                                                      */
 /************************************************************************/
 void
-lpfc_handle_eratt(struct lpfc_hba * phba)
+lpfc_handle_eratt(struct lpfc_hba *phba)
 {
-	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_vport *vport = phba->pport;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_sli   *psli = &phba->sli;
 	struct lpfc_sli_ring  *pring;
 	uint32_t event_data;
+
 	/* If the pci channel is offline, ignore possible errors,
 	 * since we cannot communicate with the pci card anyway. */
 	if (pci_channel_offline(phba->pcidev))
@@ -504,10 +502,10 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
 				"Data: x%x x%x x%x\n",
 				phba->brd_no, phba->work_hs,
 				phba->work_status[0], phba->work_status[1]);
-		spin_lock_irq(phba->host->host_lock);
-		phba->fc_flag |= FC_ESTABLISH_LINK;
+		spin_lock_irq(shost->host_lock);
+		vport->fc_flag |= FC_ESTABLISH_LINK;
 		psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 
 		/*
 		* Firmware stops when it triggled erratt with HS_FFER6.
@@ -544,7 +542,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
 				phba->work_status[0], phba->work_status[1]);
 
 		event_data = FC_REG_DUMP_EVENT;
-		fc_host_post_vendor_event(phba->host, fc_get_event_number(),
+		fc_host_post_vendor_event(shost, fc_get_event_number(),
 				sizeof(event_data), (char *) &event_data,
 				SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
 
@@ -552,7 +550,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
 		lpfc_offline_prep(phba);
 		lpfc_offline(phba);
 		lpfc_unblock_mgmt_io(phba);
-		phba->hba_state = LPFC_HBA_ERROR;
+		phba->link_state = LPFC_HBA_ERROR;
 		lpfc_hba_down_post(phba);
 	}
 }
@@ -566,9 +564,10 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
 /*                                                                      */
 /************************************************************************/
 void
-lpfc_handle_latt(struct lpfc_hba * phba)
+lpfc_handle_latt(struct lpfc_hba *phba)
 {
-	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_vport *vport = phba->pport;
+	struct lpfc_sli   *psli = &phba->sli;
 	LPFC_MBOXQ_t *pmb;
 	volatile uint32_t control;
 	struct lpfc_dmabuf *mp;
@@ -589,20 +588,21 @@ lpfc_handle_latt(struct lpfc_hba * phba)
 	rc = -EIO;
 
 	/* Cleanup any outstanding ELS commands */
-	lpfc_els_flush_cmd(phba);
+	lpfc_els_flush_cmd(vport);
 
 	psli->slistat.link_event++;
 	lpfc_read_la(phba, pmb, mp);
 	pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la;
+	pmb->vport = vport;
 	rc = lpfc_sli_issue_mbox (phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB));
 	if (rc == MBX_NOT_FINISHED)
 		goto lpfc_handle_latt_free_mbuf;
 
 	/* Clear Link Attention in HA REG */
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	writel(HA_LATT, phba->HAregaddr);
 	readl(phba->HAregaddr); /* flush */
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	return;
 
@@ -614,7 +614,7 @@ lpfc_handle_latt_free_pmb:
 	mempool_free(pmb, phba->mbox_mem_pool);
 lpfc_handle_latt_err_exit:
 	/* Enable Link attention interrupts */
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	psli->sli_flag |= LPFC_PROCESS_LA;
 	control = readl(phba->HCregaddr);
 	control |= HC_LAINT_ENA;
@@ -624,9 +624,9 @@ lpfc_handle_latt_err_exit:
 	/* Clear Link Attention in HA REG */
 	writel(HA_LATT, phba->HAregaddr);
 	readl(phba->HAregaddr); /* flush */
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 	lpfc_linkdown(phba);
-	phba->hba_state = LPFC_HBA_ERROR;
+	phba->link_state = LPFC_HBA_ERROR;
 
 	/* The other case is an error from issue_mbox */
 	if (rc == -ENOMEM)
@@ -646,7 +646,7 @@ lpfc_handle_latt_err_exit:
 /*                                                                      */
 /************************************************************************/
 static int
-lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len)
+lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
 {
 	uint8_t lenlo, lenhi;
 	int Length;
@@ -785,7 +785,7 @@ lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len)
 }
 
 static void
-lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
+lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
 {
 	lpfc_vpd_t *vp;
 	uint16_t dev_id = phba->pcidev->device;
@@ -943,7 +943,7 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
 /*   Returns the number of buffers NOT posted.    */
 /**************************************************/
 int
-lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
+lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt,
 		 int type)
 {
 	IOCB_t *icmd;
@@ -955,9 +955,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
 	/* While there are buffers to post */
 	while (cnt > 0) {
 		/* Allocate buffer for  command iocb */
-		spin_lock_irq(phba->host->host_lock);
 		iocb = lpfc_sli_get_iocbq(phba);
-		spin_unlock_irq(phba->host->host_lock);
 		if (iocb == NULL) {
 			pring->missbufcnt = cnt;
 			return cnt;
@@ -972,9 +970,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
 						&mp1->phys);
 		if (mp1 == 0 || mp1->virt == 0) {
 			kfree(mp1);
-			spin_lock_irq(phba->host->host_lock);
 			lpfc_sli_release_iocbq(phba, iocb);
-			spin_unlock_irq(phba->host->host_lock);
 			pring->missbufcnt = cnt;
 			return cnt;
 		}
@@ -990,9 +986,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
 				kfree(mp2);
 				lpfc_mbuf_free(phba, mp1->virt, mp1->phys);
 				kfree(mp1);
-				spin_lock_irq(phba->host->host_lock);
 				lpfc_sli_release_iocbq(phba, iocb);
-				spin_unlock_irq(phba->host->host_lock);
 				pring->missbufcnt = cnt;
 				return cnt;
 			}
@@ -1018,7 +1012,6 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
 		icmd->ulpCommand = CMD_QUE_RING_BUF64_CN;
 		icmd->ulpLe = 1;
 
-		spin_lock_irq(phba->host->host_lock);
 		if (lpfc_sli_issue_iocb(phba, pring, iocb, 0) == IOCB_ERROR) {
 			lpfc_mbuf_free(phba, mp1->virt, mp1->phys);
 			kfree(mp1);
@@ -1030,10 +1023,8 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
 			}
 			lpfc_sli_release_iocbq(phba, iocb);
 			pring->missbufcnt = cnt;
-			spin_unlock_irq(phba->host->host_lock);
 			return cnt;
 		}
-		spin_unlock_irq(phba->host->host_lock);
 		lpfc_sli_ringpostbuf_put(phba, pring, mp1);
 		if (mp2) {
 			lpfc_sli_ringpostbuf_put(phba, pring, mp2);
@@ -1050,7 +1041,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
 /*                                                                      */
 /************************************************************************/
 static int
-lpfc_post_rcv_buf(struct lpfc_hba * phba)
+lpfc_post_rcv_buf(struct lpfc_hba *phba)
 {
 	struct lpfc_sli *psli = &phba->sli;
 
@@ -1151,7 +1142,7 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit)
 {
 	int t;
 	uint32_t *HashWorking;
-	uint32_t *pwwnn = phba->wwnn;
+	uint32_t *pwwnn = (uint32_t *) phba->wwnn;
 
 	HashWorking = kmalloc(80 * sizeof(uint32_t), GFP_KERNEL);
 	if (!HashWorking)
@@ -1170,16 +1161,16 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit)
 }
 
 static void
-lpfc_cleanup(struct lpfc_hba * phba)
+lpfc_cleanup(struct lpfc_vport *vport)
 {
 	struct lpfc_nodelist *ndlp, *next_ndlp;
 
 	/* clean up phba - lpfc specific */
-	lpfc_can_disctmo(phba);
-	list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp)
+	lpfc_can_disctmo(vport);
+	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp)
 		lpfc_nlp_put(ndlp);
 
-	INIT_LIST_HEAD(&phba->fc_nodes);
+	INIT_LIST_HEAD(&vport->fc_nodes);
 
 	return;
 }
@@ -1187,7 +1178,9 @@ lpfc_cleanup(struct lpfc_hba * phba)
 static void
 lpfc_establish_link_tmo(unsigned long ptr)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba *)ptr;
+	struct lpfc_hba   *phba = (struct lpfc_hba *)ptr;
+	struct lpfc_vport *vport = phba->pport;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
 	unsigned long iflag;
 
 
@@ -1195,34 +1188,37 @@ lpfc_establish_link_tmo(unsigned long ptr)
 	lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
 			"%d:1300 Re-establishing Link, timer expired "
 			"Data: x%x x%x\n",
-			phba->brd_no, phba->fc_flag, phba->hba_state);
-	spin_lock_irqsave(phba->host->host_lock, iflag);
-	phba->fc_flag &= ~FC_ESTABLISH_LINK;
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
+			phba->brd_no, vport->fc_flag,
+			vport->port_state);
+	spin_lock_irqsave(shost->host_lock, iflag);
+	vport->fc_flag &= ~FC_ESTABLISH_LINK;
+	spin_unlock_irqrestore(shost->host_lock, iflag);
 }
 
-static int
-lpfc_stop_timer(struct lpfc_hba * phba)
+static void
+lpfc_stop_timer(struct lpfc_hba *phba)
 {
-	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_vport *vport = phba->pport;
 
 	del_timer_sync(&phba->fcp_poll_timer);
 	del_timer_sync(&phba->fc_estabtmo);
-	del_timer_sync(&phba->fc_disctmo);
-	del_timer_sync(&phba->fc_fdmitmo);
-	del_timer_sync(&phba->els_tmofunc);
-	psli = &phba->sli;
-	del_timer_sync(&psli->mbox_tmo);
-	return(1);
+	del_timer_sync(&vport->els_tmofunc);
+	del_timer_sync(&vport->fc_fdmitmo);
+	del_timer_sync(&vport->fc_disctmo);
+	del_timer_sync(&phba->sli.mbox_tmo);
+	return;
 }
 
 int
-lpfc_online(struct lpfc_hba * phba)
+lpfc_online(struct lpfc_hba *phba)
 {
+	struct lpfc_vport *vport = phba->pport;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
+
 	if (!phba)
 		return 0;
 
-	if (!(phba->fc_flag & FC_OFFLINE_MODE))
+	if (!(vport->fc_flag & FC_OFFLINE_MODE))
 		return 0;
 
 	lpfc_printf_log(phba,
@@ -1243,9 +1239,9 @@ lpfc_online(struct lpfc_hba * phba)
 		return 1;
 	}
 
-	spin_lock_irq(phba->host->host_lock);
-	phba->fc_flag &= ~FC_OFFLINE_MODE;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	vport->fc_flag &= ~FC_OFFLINE_MODE;
+	spin_unlock_irq(shost->host_lock);
 
 	lpfc_unblock_mgmt_io(phba);
 	return 0;
@@ -1256,9 +1252,9 @@ lpfc_block_mgmt_io(struct lpfc_hba * phba)
 {
 	unsigned long iflag;
 
-	spin_lock_irqsave(phba->host->host_lock, iflag);
-	phba->fc_flag |= FC_BLOCK_MGMT_IO;
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
+	spin_lock_irqsave(&phba->hbalock, iflag);
+	phba->sli.sli_flag |= LPFC_BLOCK_MGMT_IO;
+	spin_unlock_irqrestore(&phba->hbalock, iflag);
 }
 
 void
@@ -1266,17 +1262,18 @@ lpfc_unblock_mgmt_io(struct lpfc_hba * phba)
 {
 	unsigned long iflag;
 
-	spin_lock_irqsave(phba->host->host_lock, iflag);
-	phba->fc_flag &= ~FC_BLOCK_MGMT_IO;
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
+	spin_lock_irqsave(&phba->hbalock, iflag);
+	phba->sli.sli_flag &= ~LPFC_BLOCK_MGMT_IO;
+	spin_unlock_irqrestore(&phba->hbalock, iflag);
 }
 
 void
 lpfc_offline_prep(struct lpfc_hba * phba)
 {
+	struct lpfc_vport *vport = phba->pport;
 	struct lpfc_nodelist  *ndlp, *next_ndlp;
 
-	if (phba->fc_flag & FC_OFFLINE_MODE)
+	if (vport->fc_flag & FC_OFFLINE_MODE)
 		return;
 
 	lpfc_block_mgmt_io(phba);
@@ -1284,19 +1281,21 @@ lpfc_offline_prep(struct lpfc_hba * phba)
 	lpfc_linkdown(phba);
 
 	/* Issue an unreg_login to all nodes */
-	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_UNUSED_NODE)
-			lpfc_unreg_rpi(phba, ndlp);
+			lpfc_unreg_rpi(vport, ndlp);
 
 	lpfc_sli_flush_mbox_queue(phba);
 }
 
 void
-lpfc_offline(struct lpfc_hba * phba)
+lpfc_offline(struct lpfc_hba *phba)
 {
+	struct lpfc_vport *vport = phba->pport;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
 	unsigned long iflag;
 
-	if (phba->fc_flag & FC_OFFLINE_MODE)
+	if (vport->fc_flag & FC_OFFLINE_MODE)
 		return;
 
 	/* stop all timers associated with this hba */
@@ -1311,12 +1310,14 @@ lpfc_offline(struct lpfc_hba * phba)
 	/* Bring down the SLI Layer and cleanup.  The HBA is offline
 	   now.  */
 	lpfc_sli_hba_down(phba);
-	lpfc_cleanup(phba);
-	spin_lock_irqsave(phba->host->host_lock, iflag);
-	phba->work_hba_events = 0;
+	lpfc_cleanup(vport);
+	spin_lock_irqsave(shost->host_lock, iflag);
+	spin_lock(&phba->hbalock);
 	phba->work_ha = 0;
-	phba->fc_flag |= FC_OFFLINE_MODE;
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
+	vport->work_port_events = 0;
+	vport->fc_flag |= FC_OFFLINE_MODE;
+	spin_unlock(&phba->hbalock);
+	spin_unlock_irqrestore(shost->host_lock, iflag);
 }
 
 /******************************************************************************
@@ -1326,12 +1327,12 @@ lpfc_offline(struct lpfc_hba * phba)
 *
 ******************************************************************************/
 static int
-lpfc_scsi_free(struct lpfc_hba * phba)
+lpfc_scsi_free(struct lpfc_hba *phba)
 {
 	struct lpfc_scsi_buf *sb, *sb_next;
 	struct lpfc_iocbq *io, *io_next;
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	/* Release all the lpfc_scsi_bufs maintained by this host. */
 	list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) {
 		list_del(&sb->list);
@@ -1348,130 +1349,158 @@ lpfc_scsi_free(struct lpfc_hba * phba)
 		phba->total_iocbq_bufs--;
 	}
 
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	return 0;
 }
 
-void lpfc_remove_device(struct lpfc_hba *phba)
+struct lpfc_vport *
+lpfc_create_port(struct lpfc_hba *phba, int instance)
 {
-	unsigned long iflag;
-
-	lpfc_free_sysfs_attr(phba);
+	struct lpfc_vport *vport;
+	struct Scsi_Host  *shost;
+	int error = 0;
 
-	spin_lock_irqsave(phba->host->host_lock, iflag);
-	phba->fc_flag |= FC_UNLOADING;
+	shost = scsi_host_alloc(&lpfc_template, sizeof(struct lpfc_vport));
+	if (!shost)
+		goto out;
 
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
+	vport = (struct lpfc_vport *) shost->hostdata;
+	vport->phba = phba;
 
-	fc_remove_host(phba->host);
-	scsi_remove_host(phba->host);
-
-	kthread_stop(phba->worker_thread);
+	vport->load_flag |= FC_LOADING;
 
+	shost->unique_id = instance;
+	shost->max_id = LPFC_MAX_TARGET;
+	shost->max_lun = phba->cfg_max_luns;
+	shost->this_id = -1;
+	shost->max_cmd_len = 16;
 	/*
-	 * Bring down the SLI Layer. This step disable all interrupts,
-	 * clears the rings, discards all mailbox commands, and resets
-	 * the HBA.
+	 * Set initial can_queue value since 0 is no longer supported and
+	 * scsi_add_host will fail. This will be adjusted later based on the
+	 * max xri value determined in hba setup.
 	 */
-	lpfc_sli_hba_down(phba);
-	lpfc_sli_brdrestart(phba);
+	shost->can_queue = phba->cfg_hba_queue_depth - 10;
+	shost->transportt = lpfc_transport_template;
 
-	/* Release the irq reservation */
-	free_irq(phba->pcidev->irq, phba);
-	pci_disable_msi(phba->pcidev);
+	/* Initialize all internally managed lists. */
+	INIT_LIST_HEAD(&vport->fc_nodes);
+	spin_lock_init(&vport->work_port_lock);
 
-	lpfc_cleanup(phba);
-	lpfc_stop_timer(phba);
-	phba->work_hba_events = 0;
+	init_timer(&vport->fc_disctmo);
+	vport->fc_disctmo.function = lpfc_disc_timeout;
+	vport->fc_disctmo.data = (unsigned long) vport;
 
-	/*
-	 * Call scsi_free before mem_free since scsi bufs are released to their
-	 * corresponding pools here.
-	 */
-	lpfc_scsi_free(phba);
-	lpfc_mem_free(phba);
+	init_timer(&vport->fc_fdmitmo);
+	vport->fc_fdmitmo.function = lpfc_fdmi_tmo;
+	vport->fc_fdmitmo.data = (unsigned long) vport;
 
-	/* Free resources associated with SLI2 interface */
-	dma_free_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE,
-			  phba->slim2p, phba->slim2p_mapping);
+	init_timer(&vport->els_tmofunc);
+	vport->els_tmofunc.function = lpfc_els_timeout;
+	vport->els_tmofunc.data = (unsigned long) vport;
 
-	/* unmap adapter SLIM and Control Registers */
-	iounmap(phba->ctrl_regs_memmap_p);
-	iounmap(phba->slim_memmap_p);
+	error = scsi_add_host(shost, &phba->pcidev->dev);
+	if (error)
+		goto out_put_shost;
 
-	pci_release_regions(phba->pcidev);
-	pci_disable_device(phba->pcidev);
+	list_add_tail(&vport->listentry, &phba->port_list);
+	scsi_scan_host(shost);
+	return vport;
 
-	idr_remove(&lpfc_hba_index, phba->brd_no);
-	scsi_host_put(phba->host);
+out_put_shost:
+	scsi_host_put(shost);
+out:
+	return NULL;
+}
+
+void
+destroy_port(struct lpfc_vport *vport)
+{
+	lpfc_cleanup(vport);
+	list_del(&vport->listentry);
+	lpfc_free_sysfs_attr(vport);
+	fc_remove_host(lpfc_shost_from_vport(vport));
+	scsi_remove_host(lpfc_shost_from_vport(vport));
+	return;
 }
 
-void lpfc_scan_start(struct Scsi_Host *host)
+static void
+lpfc_remove_device(struct lpfc_vport *vport)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba  = vport->phba;
 
-	if (lpfc_alloc_sysfs_attr(phba))
-		goto error;
+	lpfc_free_sysfs_attr(vport);
 
-	phba->MBslimaddr = phba->slim_memmap_p;
-	phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET;
-	phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET;
-	phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
-	phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
+	spin_lock_irq(shost->host_lock);
+	vport->fc_flag |= FC_UNLOADING;
+	spin_unlock_irq(shost->host_lock);
+
+	fc_remove_host(shost);
+	scsi_remove_host(shost);
+
+	kthread_stop(phba->worker_thread);
+}
+
+void lpfc_scan_start(struct Scsi_Host *shost)
+{
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 
-	if (lpfc_sli_hba_setup(phba))
+	if (lpfc_alloc_sysfs_attr(vport))
 		goto error;
 
 	/*
 	 * hba setup may have changed the hba_queue_depth so we need to adjust
 	 * the value of can_queue.
 	 */
-	host->can_queue = phba->cfg_hba_queue_depth - 10;
+	shost->can_queue = phba->cfg_hba_queue_depth - 10;
 	return;
 
 error:
-	lpfc_remove_device(phba);
+	lpfc_remove_device(vport);
 }
 
 int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 
-	if (!phba->host)
-		return 1;
-	if (time >= 30 * HZ)
+	if (time >= 30 * HZ) {
+		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+				"%d:0461 Scanning longer than 30 "
+				"seconds.  Continuing initialization\n",
+				phba->brd_no);
 		goto finished;
+	}
+	if (time >= 15 * HZ && phba->link_state <= LPFC_LINK_DOWN) {
+		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+				"%d:0465 Link down longer than 15 "
+				"seconds.  Continuing initialization\n",
+				phba->brd_no);
+		goto finished;
+	}
 
-	if (phba->hba_state != LPFC_HBA_READY)
-		return 0;
-	if (phba->num_disc_nodes || phba->fc_prli_sent)
+	if (vport->port_state != LPFC_VPORT_READY)
 		return 0;
-	if ((phba->fc_map_cnt == 0) && (time < 2 * HZ))
+	if (vport->num_disc_nodes || vport->fc_prli_sent)
 		return 0;
-	if (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE)
+	if (vport->fc_map_cnt == 0 && time < 2 * HZ)
 		return 0;
-	if ((phba->hba_state > LPFC_LINK_DOWN) || (time < 15 * HZ))
+	if ((phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) != 0)
 		return 0;
 
 finished:
-	if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
-		spin_lock_irq(shost->host_lock);
-		lpfc_poll_start_timer(phba);
-		spin_unlock_irq(shost->host_lock);
-	}
-
 	/*
-	 * set fixed host attributes
-	 * Must done after lpfc_sli_hba_setup()
+	 * Set fixed host attributes.  Must done after lpfc_sli_hba_setup().
 	 */
 
-	fc_host_node_name(shost) = wwn_to_u64(phba->fc_nodename.u.wwn);
-	fc_host_port_name(shost) = wwn_to_u64(phba->fc_portname.u.wwn);
+	fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn);
+	fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn);
 	fc_host_supported_classes(shost) = FC_COS_CLASS3;
 
 	memset(fc_host_supported_fc4s(shost), 0,
-		sizeof(fc_host_supported_fc4s(shost)));
+	       sizeof(fc_host_supported_fc4s(shost)));
 	fc_host_supported_fc4s(shost)[2] = 1;
 	fc_host_supported_fc4s(shost)[7] = 1;
 
@@ -1488,17 +1517,17 @@ finished:
 		fc_host_supported_speeds(shost) |= FC_PORTSPEED_1GBIT;
 
 	fc_host_maxframe_size(shost) =
-		((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) |
-		 (uint32_t) phba->fc_sparam.cmn.bbRcvSizeLsb);
+		(((uint32_t) vport->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) |
+		(uint32_t) vport->fc_sparam.cmn.bbRcvSizeLsb;
 
 	/* This value is also unchanging */
 	memset(fc_host_active_fc4s(shost), 0,
-		sizeof(fc_host_active_fc4s(shost)));
+	       sizeof(fc_host_active_fc4s(shost)));
 	fc_host_active_fc4s(shost)[2] = 1;
 	fc_host_active_fc4s(shost)[7] = 1;
 
 	spin_lock_irq(shost->host_lock);
-	phba->fc_flag &= ~FC_LOADING;
+	vport->fc_flag &= ~FC_LOADING;
 	spin_unlock_irq(shost->host_lock);
 
 	return 1;
@@ -1507,10 +1536,11 @@ finished:
 static int __devinit
 lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
 {
-	struct Scsi_Host *host;
-	struct lpfc_hba  *phba;
-	struct lpfc_sli  *psli;
+	struct lpfc_vport *vport = NULL;
+	struct lpfc_hba   *phba;
+	struct lpfc_sli   *psli;
 	struct lpfc_iocbq *iocbq_entry = NULL, *iocbq_next = NULL;
+	struct Scsi_Host  *shost = NULL;
 	unsigned long bar0map_len, bar2map_len;
 	int error = -ENODEV, retval;
 	int i;
@@ -1521,61 +1551,41 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
 	if (pci_request_regions(pdev, LPFC_DRIVER_NAME))
 		goto out_disable_device;
 
-	host = scsi_host_alloc(&lpfc_template, sizeof (struct lpfc_hba));
-	if (!host)
+	phba = kzalloc(sizeof (struct lpfc_hba), GFP_KERNEL);
+	if (!phba)
 		goto out_release_regions;
 
-	phba = (struct lpfc_hba*)host->hostdata;
-	memset(phba, 0, sizeof (struct lpfc_hba));
-	phba->host = host;
+	spin_lock_init(&phba->hbalock);
 
-	phba->fc_flag |= FC_LOADING;
 	phba->pcidev = pdev;
 
 	/* Assign an unused board number */
 	if (!idr_pre_get(&lpfc_hba_index, GFP_KERNEL))
-		goto out_put_host;
+		goto out_free_phba;
 
 	error = idr_get_new(&lpfc_hba_index, NULL, &phba->brd_no);
 	if (error)
-		goto out_put_host;
+		goto out_free_phba;
+
+	INIT_LIST_HEAD(&phba->port_list);
 
-	host->unique_id = phba->brd_no;
+	/*
+	 * Get all the module params for configuring this host and then
+	 * establish the host.
+	 */
+	lpfc_get_cfgparam(phba);
 
 	/* Initialize timers used by driver */
 	init_timer(&phba->fc_estabtmo);
 	phba->fc_estabtmo.function = lpfc_establish_link_tmo;
-	phba->fc_estabtmo.data = (unsigned long)phba;
-	init_timer(&phba->fc_disctmo);
-	phba->fc_disctmo.function = lpfc_disc_timeout;
-	phba->fc_disctmo.data = (unsigned long)phba;
-
-	init_timer(&phba->fc_fdmitmo);
-	phba->fc_fdmitmo.function = lpfc_fdmi_tmo;
-	phba->fc_fdmitmo.data = (unsigned long)phba;
-	init_timer(&phba->els_tmofunc);
-	phba->els_tmofunc.function = lpfc_els_timeout;
-	phba->els_tmofunc.data = (unsigned long)phba;
+	phba->fc_estabtmo.data = (unsigned long) phba;
 	psli = &phba->sli;
 	init_timer(&psli->mbox_tmo);
 	psli->mbox_tmo.function = lpfc_mbox_timeout;
-	psli->mbox_tmo.data = (unsigned long)phba;
-
+	psli->mbox_tmo.data = (unsigned long) phba;
 	init_timer(&phba->fcp_poll_timer);
 	phba->fcp_poll_timer.function = lpfc_poll_timeout;
-	phba->fcp_poll_timer.data = (unsigned long)phba;
-
-	/*
-	 * Get all the module params for configuring this host and then
-	 * establish the host parameters.
-	 */
-	lpfc_get_cfgparam(phba);
-
-	host->max_id = LPFC_MAX_TARGET;
-	host->max_lun = phba->cfg_max_luns;
-	host->this_id = -1;
-
-	INIT_LIST_HEAD(&phba->fc_nodes);
+	phba->fcp_poll_timer.data = (unsigned long) phba;
 
 	pci_set_master(pdev);
 	retval = pci_set_mwi(pdev);
@@ -1653,10 +1663,11 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
 			error = -ENOMEM;
 			goto out_free_iocbq;
 		}
-		spin_lock_irq(phba->host->host_lock);
+
+		spin_lock_irq(&phba->hbalock);
 		list_add(&iocbq_entry->list, &phba->lpfc_iocb_list);
 		phba->total_iocbq_bufs++;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(&phba->hbalock);
 	}
 
 	/* Initialize HBA structure */
@@ -1677,22 +1688,19 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
 		goto out_free_iocbq;
 	}
 
-	/*
-	 * Set initial can_queue value since 0 is no longer supported and
-	 * scsi_add_host will fail. This will be adjusted later based on the
-	 * max xri value determined in hba setup.
-	 */
-	host->can_queue = phba->cfg_hba_queue_depth - 10;
-
-	/* Tell the midlayer we support 16 byte commands */
-	host->max_cmd_len = 16;
-
 	/* Initialize the list of scsi buffers used by driver for scsi IO. */
 	spin_lock_init(&phba->scsi_buf_list_lock);
 	INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list);
 
-	host->transportt = lpfc_transport_template;
-	pci_set_drvdata(pdev, host);
+	vport = lpfc_create_port(phba, phba->brd_no);
+	if (!vport)
+		goto out_kthread_stop;
+
+	shost = lpfc_shost_from_vport(vport);
+	vport->port_type = LPFC_PHYSICAL_PORT;
+	phba->pport = vport;
+
+	pci_set_drvdata(pdev, lpfc_shost_from_vport(vport));
 
 	if (phba->cfg_use_msi) {
 		error = pci_enable_msi(phba->pcidev);
@@ -1703,36 +1711,46 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
 	}
 
 	error =	request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED,
-							LPFC_DRIVER_NAME, phba);
+			    LPFC_DRIVER_NAME, phba);
 	if (error) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 			"%d:0451 Enable interrupt handler failed\n",
 			phba->brd_no);
-		goto out_kthread_stop;
+		goto out_destroy_port;
 	}
 
-	error = scsi_add_host(host, &pdev->dev);
+	phba->MBslimaddr = phba->slim_memmap_p;
+	phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET;
+	phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET;
+	phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
+	phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
+
+	error = lpfc_sli_hba_setup(phba);
 	if (error)
 		goto out_free_irq;
 
-	scsi_scan_host(host);
+	if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+		spin_lock_irq(shost->host_lock);
+		lpfc_poll_start_timer(phba);
+		spin_unlock_irq(shost->host_lock);
+	}
 
 	return 0;
 
 out_free_irq:
 	lpfc_stop_timer(phba);
-	phba->work_hba_events = 0;
+	phba->pport->work_port_events = 0;
 	free_irq(phba->pcidev->irq, phba);
 	pci_disable_msi(phba->pcidev);
+out_destroy_port:
+	destroy_port(vport);
 out_kthread_stop:
 	kthread_stop(phba->worker_thread);
 out_free_iocbq:
 	list_for_each_entry_safe(iocbq_entry, iocbq_next,
 						&phba->lpfc_iocb_list, list) {
-		spin_lock_irq(phba->host->host_lock);
 		kfree(iocbq_entry);
 		phba->total_iocbq_bufs--;
-		spin_unlock_irq(phba->host->host_lock);
 	}
 	lpfc_mem_free(phba);
 out_free_slim:
@@ -1744,9 +1762,8 @@ out_iounmap_slim:
 	iounmap(phba->slim_memmap_p);
 out_idr_remove:
 	idr_remove(&lpfc_hba_index, phba->brd_no);
-out_put_host:
-	phba->host = NULL;
-	scsi_host_put(host);
+out_free_phba:
+	kfree(phba);
 out_release_regions:
 	pci_release_regions(pdev);
 out_disable_device:
@@ -1759,12 +1776,55 @@ out:
 static void __devexit
 lpfc_pci_remove_one(struct pci_dev *pdev)
 {
-	struct Scsi_Host   *host = pci_get_drvdata(pdev);
-	struct lpfc_hba    *phba = (struct lpfc_hba *)host->hostdata;
+	struct Scsi_Host  *shost = pci_get_drvdata(pdev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+
+	vport->load_flag |= FC_UNLOADING;
+	lpfc_remove_device(vport);
+
+	/*
+	 * Bring down the SLI Layer. This step disable all interrupts,
+	 * clears the rings, discards all mailbox commands, and resets
+	 * the HBA.
+	 */
+	lpfc_sli_hba_down(phba);
+	lpfc_sli_brdrestart(phba);
+
+	lpfc_stop_timer(phba);
+
+	kthread_stop(phba->worker_thread);
+
+	/* Release the irq reservation */
+	free_irq(phba->pcidev->irq, phba);
+	pci_disable_msi(phba->pcidev);
 
-	lpfc_remove_device(phba);
+	vport->work_port_events = 0;
+	destroy_port(vport);
 
 	pci_set_drvdata(pdev, NULL);
+
+	/*
+	 * Call scsi_free before mem_free since scsi bufs are released to their
+	 * corresponding pools here.
+	 */
+	lpfc_scsi_free(phba);
+	lpfc_mem_free(phba);
+
+	/* Free resources associated with SLI2 interface */
+	dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE,
+			  phba->slim2p, phba->slim2p_mapping);
+
+	/* unmap adapter SLIM and Control Registers */
+	iounmap(phba->ctrl_regs_memmap_p);
+	iounmap(phba->slim_memmap_p);
+
+	idr_remove(&lpfc_hba_index, phba->brd_no);
+
+	kfree(phba);
+
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
 }
 
 /**
@@ -1822,10 +1882,12 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
 	pci_set_master(pdev);
 
 	/* Re-establishing Link */
-	spin_lock_irq(phba->host->host_lock);
-	phba->fc_flag |= FC_ESTABLISH_LINK;
+	spin_lock_irq(&phba->hbalock);
+	phba->pport->fc_flag |= FC_ESTABLISH_LINK;
+	spin_unlock_irq(&phba->hbalock);
+	spin_lock_irq(host->host_lock);
 	psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(host->host_lock);
 
 
 	/* Take device offline; this will perform cleanup */
@@ -1935,7 +1997,7 @@ static struct pci_driver lpfc_driver = {
 	.id_table	= lpfc_id_table,
 	.probe		= lpfc_pci_probe_one,
 	.remove		= __devexit_p(lpfc_pci_remove_one),
-	.err_handler = &lpfc_err_handler,
+	.err_handler    = &lpfc_err_handler,
 };
 
 static int __init
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 8041c3f06f7b466483c4ec61d256adc49c2b6d6c..86757ec53057017fe1ed8bb221ed5e54272fdef0 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -106,7 +106,7 @@ lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp)
 	 */
 	pmb->context1 = (uint8_t *) mp;
 	mb->mbxOwner = OWN_HOST;
-	return (0);
+	return 0;
 }
 
 /**********************************************/
@@ -134,6 +134,7 @@ lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 void
 lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 {
+	struct lpfc_vport  *vport = phba->pport;
 	MAILBOX_t *mb = &pmb->mb;
 	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
@@ -147,7 +148,7 @@ lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 		mb->un.varCfgLnk.cr_count = phba->cfg_cr_count;
 	}
 
-	mb->un.varCfgLnk.myId = phba->fc_myDID;
+	mb->un.varCfgLnk.myId = vport->fc_myDID;
 	mb->un.varCfgLnk.edtov = phba->fc_edtov;
 	mb->un.varCfgLnk.arbtov = phba->fc_arbtov;
 	mb->un.varCfgLnk.ratov = phba->fc_ratov;
@@ -208,7 +209,7 @@ lpfc_init_link(struct lpfc_hba * phba,
 	 */
 	vpd = &phba->vpd;
 	if (vpd->rev.feaLevelHigh >= 0x02){
-		switch(linkspeed){
+		switch (linkspeed){
 			case LINK_SPEED_1G:
 			case LINK_SPEED_2G:
 			case LINK_SPEED_4G:
@@ -263,7 +264,7 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 			        LOG_MBOX,
 			        "%d:0301 READ_SPARAM: no buffers\n",
 			        phba->brd_no);
-		return (1);
+		return 1;
 	}
 	INIT_LIST_HEAD(&mp->list);
 	mb->mbxCommand = MBX_READ_SPARM64;
@@ -274,7 +275,7 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 	/* save address for completion */
 	pmb->context1 = mp;
 
-	return (0);
+	return 0;
 }
 
 /********************************************/
@@ -282,7 +283,7 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 /*                  mailbox command         */
 /********************************************/
 void
-lpfc_unreg_did(struct lpfc_hba * phba, uint32_t did, LPFC_MBOXQ_t * pmb)
+lpfc_unreg_did(struct lpfc_hba *phba, uint32_t did, LPFC_MBOXQ_t *pmb)
 {
 	MAILBOX_t *mb;
 
@@ -335,16 +336,13 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 /*                  mailbox command         */
 /********************************************/
 int
-lpfc_reg_login(struct lpfc_hba * phba,
-	       uint32_t did, uint8_t * param, LPFC_MBOXQ_t * pmb, uint32_t flag)
+lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param,
+	       LPFC_MBOXQ_t *pmb, uint32_t flag)
 {
+	MAILBOX_t *mb = &pmb->mb;
 	uint8_t *sparam;
 	struct lpfc_dmabuf *mp;
-	MAILBOX_t *mb;
-	struct lpfc_sli *psli;
 
-	psli = &phba->sli;
-	mb = &pmb->mb;
 	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 	mb->un.varRegLogin.rpi = 0;
@@ -365,7 +363,7 @@ lpfc_reg_login(struct lpfc_hba * phba,
 			       "%d:0302 REG_LOGIN: no buffers Data x%x x%x\n",
 			       phba->brd_no,
 			       (uint32_t) did, (uint32_t) flag);
-		return (1);
+		return 1;
 	}
 	INIT_LIST_HEAD(&mp->list);
 	sparam = mp->virt;
@@ -381,7 +379,7 @@ lpfc_reg_login(struct lpfc_hba * phba,
 	mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys);
 	mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys);
 
-	return (0);
+	return 0;
 }
 
 /**********************************************/
@@ -389,7 +387,7 @@ lpfc_reg_login(struct lpfc_hba * phba,
 /*                    mailbox command         */
 /**********************************************/
 void
-lpfc_unreg_login(struct lpfc_hba * phba, uint32_t rpi, LPFC_MBOXQ_t * pmb)
+lpfc_unreg_login(struct lpfc_hba *phba, uint32_t rpi, LPFC_MBOXQ_t * pmb)
 {
 	MAILBOX_t *mb;
 
@@ -412,14 +410,14 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
 	PCB_t *pcbp = &phba->slim2p->pcb;
 	dma_addr_t pdma_addr;
 	uint32_t offset;
-	uint32_t iocbCnt;
+	uint32_t iocbCnt = 0;
 	int i;
 
 	pcbp->maxRing = (psli->num_rings - 1);
 
-	iocbCnt = 0;
 	for (i = 0; i < psli->num_rings; i++) {
 		pring = &psli->ring[i];
+
 		/* A ring MUST have both cmd and rsp entries defined to be
 		   valid */
 		if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) {
@@ -462,9 +460,7 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
 void
 lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 {
-	MAILBOX_t *mb;
-
-	mb = &pmb->mb;
+	MAILBOX_t *mb = &pmb->mb;
 	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 	mb->un.varRdRev.cv = 1;
 	mb->mbxCommand = MBX_READ_REV;
@@ -644,8 +640,7 @@ lpfc_mbox_get(struct lpfc_hba * phba)
 	LPFC_MBOXQ_t *mbq = NULL;
 	struct lpfc_sli *psli = &phba->sli;
 
-	list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t,
-			 list);
+	list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list);
 	if (mbq) {
 		psli->mboxq_cnt--;
 	}
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index ec3bbbde6f7a397442eec29fbb477ca35a97f556..3aa1dff154466ff79817e18bcd29212ee3d20c3e 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2006 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -38,6 +38,8 @@
 #define LPFC_MBUF_POOL_SIZE     64      /* max elements in MBUF safety pool */
 #define LPFC_MEM_POOL_SIZE      64      /* max elem in non-DMA safety pool */
 
+
+
 int
 lpfc_mem_alloc(struct lpfc_hba * phba)
 {
@@ -84,6 +86,7 @@ lpfc_mem_alloc(struct lpfc_hba * phba)
 
  fail_free_mbox_pool:
 	mempool_destroy(phba->mbox_mem_pool);
+	phba->mbox_mem_pool = NULL;
  fail_free_mbuf_pool:
 	while (i--)
 		pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt,
@@ -91,8 +94,10 @@ lpfc_mem_alloc(struct lpfc_hba * phba)
 	kfree(pool->elements);
  fail_free_lpfc_mbuf_pool:
 	pci_pool_destroy(phba->lpfc_mbuf_pool);
+	phba->lpfc_mbuf_pool = NULL;
  fail_free_dma_buf_pool:
 	pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
+	phba->lpfc_scsi_dma_buf_pool = NULL;
  fail:
 	return -ENOMEM;
 }
@@ -106,6 +111,7 @@ lpfc_mem_free(struct lpfc_hba * phba)
 	struct lpfc_dmabuf   *mp;
 	int i;
 
+	spin_lock_irq(&phba->hbalock);
 	list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) {
 		mp = (struct lpfc_dmabuf *) (mbox->context1);
 		if (mp) {
@@ -117,6 +123,7 @@ lpfc_mem_free(struct lpfc_hba * phba)
 	}
 
 	psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
+	spin_unlock_irq(&phba->hbalock);
 	if (psli->mbox_active) {
 		mbox = psli->mbox_active;
 		mp = (struct lpfc_dmabuf *) (mbox->context1);
@@ -132,12 +139,18 @@ lpfc_mem_free(struct lpfc_hba * phba)
 		pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt,
 						 pool->elements[i].phys);
 	kfree(pool->elements);
+
 	mempool_destroy(phba->nlp_mem_pool);
 	mempool_destroy(phba->mbox_mem_pool);
 
 	pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
 	pci_pool_destroy(phba->lpfc_mbuf_pool);
 
+	phba->nlp_mem_pool = NULL;
+	phba->mbox_mem_pool = NULL;
+	phba->lpfc_scsi_dma_buf_pool = NULL;
+	phba->lpfc_mbuf_pool = NULL;
+
 	/* Free the iocb lookup array */
 	kfree(psli->iocbq_lookup);
 	psli->iocbq_lookup = NULL;
@@ -148,20 +161,23 @@ void *
 lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
 {
 	struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
+	unsigned long iflags;
 	void *ret;
 
 	ret = pci_pool_alloc(phba->lpfc_mbuf_pool, GFP_KERNEL, handle);
 
+	spin_lock_irqsave(&phba->hbalock, iflags);
 	if (!ret && ( mem_flags & MEM_PRI) && pool->current_count) {
 		pool->current_count--;
 		ret = pool->elements[pool->current_count].virt;
 		*handle = pool->elements[pool->current_count].phys;
 	}
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
 	return ret;
 }
 
 void
-lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
+__lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
 {
 	struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
 
@@ -174,3 +190,14 @@ lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
 	}
 	return;
 }
+
+void
+lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
+{
+	unsigned long iflags;
+
+	spin_lock_irqsave(&phba->hbalock, iflags);
+	__lpfc_mbuf_free(phba, virt, dma);
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
+	return;
+}
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index b309841e3846a571aaadd44fe60c950587315203..e6452b88d95804c5890506e16c87bace306cde8b 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -39,16 +39,16 @@
 
 /* Called to verify a rcv'ed ADISC was intended for us. */
 static int
-lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
-		 struct lpfc_name * nn, struct lpfc_name * pn)
+lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+		 struct lpfc_name *nn, struct lpfc_name *pn)
 {
 	/* Compare the ADISC rsp WWNN / WWPN matches our internal node
 	 * table entry for that node.
 	 */
-	if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)) != 0)
+	if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)))
 		return 0;
 
-	if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)) != 0)
+	if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)))
 		return 0;
 
 	/* we match, return success */
@@ -56,11 +56,10 @@ lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
 }
 
 int
-lpfc_check_sparm(struct lpfc_hba * phba,
-		 struct lpfc_nodelist * ndlp, struct serv_parm * sp,
-		 uint32_t class)
+lpfc_check_sparm(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+		 struct serv_parm * sp, uint32_t class)
 {
-	volatile struct serv_parm *hsp = &phba->fc_sparam;
+	volatile struct serv_parm *hsp = &vport->fc_sparam;
 	uint16_t hsp_value, ssp_value = 0;
 
 	/*
@@ -128,8 +127,7 @@ lpfc_check_sparm(struct lpfc_hba * phba,
 }
 
 static void *
-lpfc_check_elscmpl_iocb(struct lpfc_hba * phba,
-		      struct lpfc_iocbq *cmdiocb,
+lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 		      struct lpfc_iocbq *rspiocb)
 {
 	struct lpfc_dmabuf *pcmd, *prsp;
@@ -168,11 +166,11 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba,
  * routine effectively results in a "software abort".
  */
 int
-lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
+lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
 {
 	LIST_HEAD(completions);
-	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];
 	struct lpfc_iocbq *iocb, *next_iocb;
 	IOCB_t *cmd;
 
@@ -183,11 +181,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
 			phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag,
 			ndlp->nlp_state, ndlp->nlp_rpi);
 
-	psli = &phba->sli;
-	pring = &psli->ring[LPFC_ELS_RING];
-
 	/* First check the txq */
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {
 		/* Check to see if iocb matches the nport we are looking
 		   for */
@@ -206,32 +201,34 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
 		if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp))
 			lpfc_sli_issue_abort_iotag(phba, pring, iocb);
 	}
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	while (!list_empty(&completions)) {
 		iocb = list_get_first(&completions, struct lpfc_iocbq, list);
 		cmd = &iocb->iocb;
 		list_del(&iocb->list);
 
-		if (iocb->iocb_cmpl) {
+		if (!iocb->iocb_cmpl)
+			lpfc_sli_release_iocbq(phba, iocb);
+		else {
 			cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
 			cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
 			(iocb->iocb_cmpl) (phba, iocb, iocb);
-		} else
-			lpfc_sli_release_iocbq(phba, iocb);
+		}
 	}
 
 	/* If we are delaying issuing an ELS command, cancel it */
 	if (ndlp->nlp_flag & NLP_DELAY_TMO)
-		lpfc_cancel_retry_delay_tmo(phba, ndlp);
+		lpfc_cancel_retry_delay_tmo(phba->pport, ndlp);
 	return 0;
 }
 
 static int
-lpfc_rcv_plogi(struct lpfc_hba * phba,
-		      struct lpfc_nodelist * ndlp,
+lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 		      struct lpfc_iocbq *cmdiocb)
 {
+	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;
@@ -241,14 +238,14 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
 	int rc;
 
 	memset(&stat, 0, sizeof (struct ls_rjt));
-	if (phba->hba_state <= LPFC_FLOGI) {
+	if (vport->port_state <= LPFC_FLOGI) {
 		/* Before responding to PLOGI, check for pt2pt mode.
 		 * If we are pt2pt, with an outstanding FLOGI, abort
 		 * the FLOGI and resend it first.
 		 */
-		if (phba->fc_flag & FC_PT2PT) {
+		if (vport->fc_flag & FC_PT2PT) {
 			lpfc_els_abort_flogi(phba);
-		        if (!(phba->fc_flag & FC_PT2PT_PLOGI)) {
+		        if (!(vport->fc_flag & FC_PT2PT_PLOGI)) {
 				/* If the other side is supposed to initiate
 				 * the PLOGI anyway, just ACC it now and
 				 * move on with discovery.
@@ -257,14 +254,14 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
 				phba->fc_ratov = FF_DEF_RATOV;
 				/* Start discovery - this should just do
 				   CLEAR_LA */
-				lpfc_disc_start(phba);
+				lpfc_disc_start(vport);
 			} else {
-				lpfc_initial_flogi(phba);
+				lpfc_initial_flogi(vport);
 			}
 		} else {
 			stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;
 			stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
-			lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb,
+			lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
 					    ndlp);
 			return 0;
 		}
@@ -272,11 +269,11 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
 	pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
 	lp = (uint32_t *) pcmd->virt;
 	sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
-	if ((lpfc_check_sparm(phba, ndlp, sp, CLASS3) == 0)) {
+	if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3) == 0)) {
 		/* Reject this request because invalid parameters */
 		stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
 		stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
-		lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
+		lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp);
 		return 0;
 	}
 	icmd = &cmdiocb->iocb;
@@ -290,12 +287,12 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
 			ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag,
 			ndlp->nlp_rpi);
 
-	if ((phba->cfg_fcp_class == 2) &&
-	    (sp->cls2.classValid)) {
+	if (phba->cfg_fcp_class == 2 && sp->cls2.classValid) {
 		ndlp->nlp_fcp_info |= CLASS2;
 	} else {
 		ndlp->nlp_fcp_info |= CLASS3;
 	}
+
 	ndlp->nlp_class_sup = 0;
 	if (sp->cls1.classValid)
 		ndlp->nlp_class_sup |= FC_COS_CLASS1;
@@ -317,14 +314,14 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
 	case  NLP_STE_PRLI_ISSUE:
 	case  NLP_STE_UNMAPPED_NODE:
 	case  NLP_STE_MAPPED_NODE:
-		lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0);
+		lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0);
 		return 1;
 	}
 
-	if ((phba->fc_flag & FC_PT2PT)
-	    && !(phba->fc_flag & FC_PT2PT_PLOGI)) {
+	if ((vport->fc_flag & FC_PT2PT)
+	    && !(vport->fc_flag & FC_PT2PT_PLOGI)) {
 		/* rcv'ed PLOGI decides what our NPortId will be */
-		phba->fc_myDID = icmd->un.rcvels.parmRo;
+		vport->fc_myDID = icmd->un.rcvels.parmRo;
 		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 		if (mbox == NULL)
 			goto out;
@@ -337,15 +334,16 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
 			goto out;
 		}
 
-		lpfc_can_disctmo(phba);
+		lpfc_can_disctmo(vport);
 	}
 	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-	if (mbox == NULL)
+	if (!mbox)
 		goto out;
 
-	if (lpfc_reg_login(phba, icmd->un.rcvels.remoteID,
-			   (uint8_t *) sp, mbox, 0)) {
-		mempool_free( mbox, phba->mbox_mem_pool);
+	rc = lpfc_reg_login(phba, icmd->un.rcvels.remoteID, (uint8_t *) sp,
+			    mbox, 0);
+	if (rc) {
+		mempool_free(mbox, phba->mbox_mem_pool);
 		goto out;
 	}
 
@@ -357,7 +355,10 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
 	 * mbox->context2 = lpfc_nlp_get(ndlp) deferred until mailbox
 	 * command issued in lpfc_cmpl_els_acc().
 	 */
+	mbox->vport = vport;
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI);
+	spin_unlock_irq(shost->host_lock);
 
 	/*
 	 * If there is an outstanding PLOGI issued, abort it before
@@ -373,24 +374,24 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
 		lpfc_els_abort(phba, ndlp);
 	}
 
-	lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0);
+	lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0);
 	return 1;
 
 out:
 	stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
 	stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE;
-	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_rcv_padisc(struct lpfc_hba * phba,
-		struct lpfc_nodelist * ndlp,
+lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 		struct lpfc_iocbq *cmdiocb)
 {
+	struct Scsi_Host   *shost = lpfc_shost_from_vport(vport);
 	struct lpfc_dmabuf *pcmd;
-	struct serv_parm *sp;
-	struct lpfc_name *pnn, *ppn;
+	struct serv_parm   *sp;
+	struct lpfc_name   *pnn, *ppn;
 	struct ls_rjt stat;
 	ADISC *ap;
 	IOCB_t *icmd;
@@ -412,12 +413,11 @@ lpfc_rcv_padisc(struct lpfc_hba * phba,
 	}
 
 	icmd = &cmdiocb->iocb;
-	if ((icmd->ulpStatus == 0) &&
-	    (lpfc_check_adisc(phba, ndlp, pnn, ppn))) {
+	if (icmd->ulpStatus == 0 && lpfc_check_adisc(vport, ndlp, pnn, ppn)) {
 		if (cmd == ELS_CMD_ADISC) {
-			lpfc_els_rsp_adisc_acc(phba, cmdiocb, ndlp);
+			lpfc_els_rsp_adisc_acc(vport, cmdiocb, ndlp);
 		} else {
-			lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp,
+			lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp,
 				NULL, 0);
 		}
 		return 1;
@@ -427,55 +427,57 @@ lpfc_rcv_padisc(struct lpfc_hba * phba,
 	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);
 
 	/* 1 sec timeout */
 	mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag |= NLP_DELAY_TMO;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 	ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
 	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);
 	return 0;
 }
 
 static int
-lpfc_rcv_logo(struct lpfc_hba * phba,
-		      struct lpfc_nodelist * ndlp,
-		      struct lpfc_iocbq *cmdiocb,
-		      uint32_t els_cmd)
+lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+	      struct lpfc_iocbq *cmdiocb, uint32_t els_cmd)
 {
-	/* Put ndlp on NPR list with 1 sec timeout for plogi, ACC logo */
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
+	/* Put ndlp in NPR state with 1 sec timeout for plogi, ACC logo */
 	/* Only call LOGO ACC for first LOGO, this avoids sending unnecessary
 	 * PLOGIs during LOGO storms from a device.
 	 */
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag |= NLP_LOGO_ACC;
+	spin_unlock_irq(shost->host_lock);
 	if (els_cmd == ELS_CMD_PRLO)
-		lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
+		lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
 	else
-		lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+		lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
 
 	if (!(ndlp->nlp_type & NLP_FABRIC) ||
 		(ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) {
 		/* Only try to re-login if this is NOT a Fabric Node */
 		mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
-		spin_lock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag |= NLP_DELAY_TMO;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 
 		ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
 		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);
 	} else {
 		ndlp->nlp_prev_state = ndlp->nlp_state;
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE);
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
 	}
 
-	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);
 	/* The driver has to wait until the ACC completes before it continues
 	 * processing the LOGO.  The action will resume in
 	 * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an
@@ -485,9 +487,8 @@ lpfc_rcv_logo(struct lpfc_hba * phba,
 }
 
 static void
-lpfc_rcv_prli(struct lpfc_hba * phba,
-		      struct lpfc_nodelist * ndlp,
-		      struct lpfc_iocbq *cmdiocb)
+lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+	      struct lpfc_iocbq *cmdiocb)
 {
 	struct lpfc_dmabuf *pcmd;
 	uint32_t *lp;
@@ -522,31 +523,33 @@ lpfc_rcv_prli(struct lpfc_hba * phba,
 }
 
 static uint32_t
-lpfc_disc_set_adisc(struct lpfc_hba * phba,
-		      struct lpfc_nodelist * ndlp)
+lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
+
 	/* Check config parameter use-adisc or FCP-2 */
-	if ((phba->cfg_use_adisc == 0) &&
-		!(phba->fc_flag & FC_RSCN_MODE)) {
-		if (!(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE))
+	if (phba->cfg_use_adisc == 0 &&
+	    (vport->fc_flag & FC_RSCN_MODE) == 0 &&
+	    (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) == 0)
 			return 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);
 	return 1;
 }
 
 static uint32_t
-lpfc_disc_illegal(struct lpfc_hba * phba,
-		   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+		  void *arg, uint32_t evt)
 {
-	lpfc_printf_log(phba,
+	lpfc_printf_log(vport->phba,
 			KERN_ERR,
 			LOG_DISCOVERY,
 			"%d:0253 Illegal State Transition: node x%x event x%x, "
 			"state x%x Data: x%x x%x\n",
-			phba->brd_no,
+			vport->phba->brd_no,
 			ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
 			ndlp->nlp_flag);
 	return ndlp->nlp_state;
@@ -555,86 +558,82 @@ lpfc_disc_illegal(struct lpfc_hba * phba,
 /* Start of Discovery State Machine routines */
 
 static uint32_t
-lpfc_rcv_plogi_unused_node(struct lpfc_hba * phba,
-			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_plogi_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			   void *arg, uint32_t evt)
 {
 	struct lpfc_iocbq *cmdiocb;
 
 	cmdiocb = (struct lpfc_iocbq *) arg;
 
-	if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) {
+	if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
 		ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE);
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
 		return ndlp->nlp_state;
 	}
-	lpfc_drop_node(phba, ndlp);
+	lpfc_drop_node(vport, ndlp);
 	return NLP_STE_FREED_NODE;
 }
 
 static uint32_t
-lpfc_rcv_els_unused_node(struct lpfc_hba * phba,
-			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_els_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			 void *arg, uint32_t evt)
 {
-	lpfc_issue_els_logo(phba, ndlp, 0);
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE);
+	lpfc_issue_els_logo(vport, ndlp, 0);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_logo_unused_node(struct lpfc_hba * phba,
-			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			  void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq     *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	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);
-	lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE);
+	spin_unlock_irq(shost->host_lock);
+	lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
 
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_cmpl_logo_unused_node(struct lpfc_hba * phba,
-			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_cmpl_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			   void *arg, uint32_t evt)
 {
-	lpfc_drop_node(phba, ndlp);
+	lpfc_drop_node(vport, ndlp);
 	return NLP_STE_FREED_NODE;
 }
 
 static uint32_t
-lpfc_device_rm_unused_node(struct lpfc_hba * phba,
-			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			   void *arg, uint32_t evt)
 {
-	lpfc_drop_node(phba, ndlp);
+	lpfc_drop_node(vport, ndlp);
 	return NLP_STE_FREED_NODE;
 }
 
 static uint32_t
-lpfc_rcv_plogi_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
+lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 			   void *arg, uint32_t evt)
 {
+	struct lpfc_hba   *phba = vport->phba;
 	struct lpfc_iocbq *cmdiocb = arg;
-	struct lpfc_dmabuf *pcmd;
-	struct serv_parm *sp;
-	uint32_t *lp;
+	struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
+	uint32_t *lp = (uint32_t *) pcmd->virt;
+	struct serv_parm *sp = (struct serv_parm *) (lp + 1);
 	struct ls_rjt stat;
 	int port_cmp;
 
-	pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
-	lp = (uint32_t *) pcmd->virt;
-	sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
-
 	memset(&stat, 0, sizeof (struct ls_rjt));
 
 	/* For a PLOGI, we only accept if our portname is less
 	 * than the remote portname.
 	 */
 	phba->fc_stat.elsLogiCol++;
-	port_cmp = memcmp(&phba->fc_portname, &sp->portName,
+	port_cmp = memcmp(&vport->fc_portname, &sp->portName,
 			  sizeof (struct lpfc_name));
 
 	if (port_cmp >= 0) {
@@ -642,64 +641,64 @@ lpfc_rcv_plogi_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
 		   ours */
 		stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
 		stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS;
-		lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
+		lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp);
 	} else {
-		lpfc_rcv_plogi(phba, ndlp, cmdiocb);
-	} /* if our portname was less */
+		lpfc_rcv_plogi(vport, ndlp, cmdiocb);
+	} /* If our portname was less */
 
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_logo_plogi_issue(struct lpfc_hba * phba,
-			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			  void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq     *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
 	/* software abort outstanding PLOGI */
-	lpfc_els_abort(phba, ndlp);
+	lpfc_els_abort(vport->phba, ndlp);
 
-	lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
+	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba,
-			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_els_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			 void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq     *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba   *phba = vport->phba;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
 	/* software abort outstanding PLOGI */
 	lpfc_els_abort(phba, ndlp);
 
 	if (evt == NLP_EVT_RCV_LOGO) {
-		lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+		lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
 	} else {
-		lpfc_issue_els_logo(phba, ndlp, 0);
+		lpfc_issue_els_logo(vport, ndlp, 0);
 	}
 
-	/* Put ndlp in npr list set plogi timer for 1 sec */
+	/* Put ndlp in npr state set plogi timer for 1 sec */
 	mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag |= NLP_DELAY_TMO;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 	ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
 	ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
 
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
+lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
+			    struct lpfc_nodelist *ndlp,
+			    void *arg,
 			    uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb, *rspiocb;
+	struct lpfc_hba    *phba = vport->phba;
+	struct lpfc_iocbq  *cmdiocb, *rspiocb;
 	struct lpfc_dmabuf *pcmd, *prsp, *mp;
 	uint32_t *lp;
 	IOCB_t *irsp;
@@ -721,13 +720,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
 
 	pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
 
-	prsp = list_get_first(&pcmd->list,
-			      struct lpfc_dmabuf,
-			      list);
-	lp = (uint32_t *) prsp->virt;
+	prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
 
+	lp = (uint32_t *) prsp->virt;
 	sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
-	if (!lpfc_check_sparm(phba, ndlp, sp, CLASS3))
+	if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3))
 		goto out;
 
 	/* PLOGI chkparm OK */
@@ -740,12 +737,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
 			ndlp->nlp_DID, ndlp->nlp_state,
 			ndlp->nlp_flag, ndlp->nlp_rpi);
 
-	if ((phba->cfg_fcp_class == 2) &&
-	    (sp->cls2.classValid)) {
+	if (phba->cfg_fcp_class == 2 && (sp->cls2.classValid))
 		ndlp->nlp_fcp_info |= CLASS2;
-	} else {
+	else
 		ndlp->nlp_fcp_info |= CLASS3;
-	}
+
 	ndlp->nlp_class_sup = 0;
 	if (sp->cls1.classValid)
 		ndlp->nlp_class_sup |= FC_COS_CLASS1;
@@ -756,14 +752,14 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
 	if (sp->cls4.classValid)
 		ndlp->nlp_class_sup |= FC_COS_CLASS4;
 	ndlp->nlp_maxframe =
-		((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) |
-		sp->cmn.bbRcvSizeLsb;
+		((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
 
-	if (!(mbox = mempool_alloc(phba->mbox_mem_pool,
-				   GFP_KERNEL)))
+	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mbox)
 		goto out;
 
-	lpfc_unreg_rpi(phba, ndlp);
+	lpfc_unreg_rpi(vport, ndlp);
+
 	if (lpfc_reg_login(phba, irsp->un.elsreq64.remoteID, (uint8_t *) sp,
 			   mbox, 0) == 0) {
 		switch (ndlp->nlp_DID) {
@@ -777,10 +773,12 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
 			mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
 		}
 		mbox->context2 = lpfc_nlp_get(ndlp);
+		mbox->vport = vport;
 		if (lpfc_sli_issue_mbox(phba, mbox,
 					(MBX_NOWAIT | MBX_STOP_IOCB))
 		    != MBX_NOT_FINISHED) {
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_REG_LOGIN_ISSUE);
+			lpfc_nlp_set_state(vport, ndlp,
+					   NLP_STE_REG_LOGIN_ISSUE);
 			return ndlp->nlp_state;
 		}
 		lpfc_nlp_put(ndlp);
@@ -796,49 +794,56 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
  out:
 	/* Free this node since the driver cannot login or has the wrong
 	   sparm */
-	lpfc_drop_node(phba, ndlp);
+	lpfc_drop_node(vport, ndlp);
 	return NLP_STE_FREED_NODE;
 }
 
 static uint32_t
-lpfc_device_rm_plogi_issue(struct lpfc_hba * phba,
-			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_device_rm_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			   void *arg, uint32_t evt)
 {
-	if(ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
+	if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag |= NLP_NODEV_REMOVE;
+		spin_unlock_irq(shost->host_lock);
 		return ndlp->nlp_state;
-	}
-	else {
+	} else {
 		/* software abort outstanding PLOGI */
-		lpfc_els_abort(phba, ndlp);
+		lpfc_els_abort(vport->phba, ndlp);
 
-		lpfc_drop_node(phba, ndlp);
+		lpfc_drop_node(vport, ndlp);
 		return NLP_STE_FREED_NODE;
 	}
 }
 
 static uint32_t
-lpfc_device_recov_plogi_issue(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_device_recov_plogi_issue(struct lpfc_vport *vport,
+			      struct lpfc_nodelist *ndlp,
+			      void *arg,
+			      uint32_t evt)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
+
 	/* software abort outstanding PLOGI */
 	lpfc_els_abort(phba, ndlp);
 
 	ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
 	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			   void *arg, uint32_t evt)
 {
+	struct lpfc_hba   *phba = vport->phba;
 	struct lpfc_iocbq *cmdiocb;
 
 	/* software abort outstanding ADISC */
@@ -846,34 +851,31 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba,
 
 	cmdiocb = (struct lpfc_iocbq *) arg;
 
-	if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) {
+	if (lpfc_rcv_plogi(vport, ndlp, cmdiocb))
 		return ndlp->nlp_state;
-	}
+
 	ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE);
-	lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0);
+	lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
 
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_prli_adisc_issue(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_rcv_prli_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			  void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
+	lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_rcv_logo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			  void *arg, uint32_t evt)
 {
+	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_iocbq *cmdiocb;
 
 	cmdiocb = (struct lpfc_iocbq *) arg;
@@ -881,42 +883,43 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba,
 	/* software abort outstanding ADISC */
 	lpfc_els_abort(phba, ndlp);
 
-	lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
+	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_padisc_adisc_issue(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_rcv_padisc_adisc_issue(struct lpfc_vport *vport,
+			    struct lpfc_nodelist *ndlp,
+			    void *arg, uint32_t evt)
 {
 	struct lpfc_iocbq *cmdiocb;
 
 	cmdiocb = (struct lpfc_iocbq *) arg;
 
-	lpfc_rcv_padisc(phba, ndlp, cmdiocb);
+	lpfc_rcv_padisc(vport, ndlp, cmdiocb);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_rcv_prlo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			  void *arg, uint32_t evt)
 {
 	struct lpfc_iocbq *cmdiocb;
 
 	cmdiocb = (struct lpfc_iocbq *) arg;
 
 	/* Treat like rcv logo */
-	lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO);
+	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport,
+			    struct lpfc_nodelist *ndlp,
+			    void *arg, uint32_t evt)
 {
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba   *phba = vport->phba;
 	struct lpfc_iocbq *cmdiocb, *rspiocb;
 	IOCB_t *irsp;
 	ADISC *ap;
@@ -928,101 +931,107 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba,
 	irsp = &rspiocb->iocb;
 
 	if ((irsp->ulpStatus) ||
-		(!lpfc_check_adisc(phba, ndlp, &ap->nodeName, &ap->portName))) {
+	     (!lpfc_check_adisc(vport, ndlp, &ap->nodeName, &ap->portName))) {
 		/* 1 sec timeout */
 		mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
-		spin_lock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag |= NLP_DELAY_TMO;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 		ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
 
-		memset(&ndlp->nlp_nodename, 0, sizeof (struct lpfc_name));
-		memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name));
+		memset(&ndlp->nlp_nodename, 0, sizeof(struct lpfc_name));
+		memset(&ndlp->nlp_portname, 0, sizeof(struct lpfc_name));
 
 		ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
-		lpfc_unreg_rpi(phba, ndlp);
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+		lpfc_unreg_rpi(vport, ndlp);
 		return ndlp->nlp_state;
 	}
 
 	if (ndlp->nlp_type & NLP_FCP_TARGET) {
 		ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_MAPPED_NODE);
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
 	} else {
 		ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
 	}
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_device_rm_adisc_issue(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_device_rm_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			   void *arg, uint32_t evt)
 {
-	if(ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
+	if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag |= NLP_NODEV_REMOVE;
+		spin_unlock_irq(shost->host_lock);
 		return ndlp->nlp_state;
-	}
-	else {
+	} else {
 		/* software abort outstanding ADISC */
-		lpfc_els_abort(phba, ndlp);
+		lpfc_els_abort(vport->phba, ndlp);
 
-		lpfc_drop_node(phba, ndlp);
+		lpfc_drop_node(vport, ndlp);
 		return NLP_STE_FREED_NODE;
 	}
 }
 
 static uint32_t
-lpfc_device_recov_adisc_issue(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_device_recov_adisc_issue(struct lpfc_vport *vport,
+			      struct lpfc_nodelist *ndlp,
+			      void *arg,
+			      uint32_t evt)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
+
 	/* software abort outstanding ADISC */
 	lpfc_els_abort(phba, ndlp);
 
 	ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
-	spin_lock_irq(phba->host->host_lock);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
 	ndlp->nlp_flag |= NLP_NPR_ADISC;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_plogi_reglogin_issue(struct lpfc_hba * phba,
-			      struct lpfc_nodelist * ndlp, void *arg,
+lpfc_rcv_plogi_reglogin_issue(struct lpfc_vport *vport,
+			      struct lpfc_nodelist *ndlp,
+			      void *arg,
 			      uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	lpfc_rcv_plogi(phba, ndlp, cmdiocb);
+	lpfc_rcv_plogi(vport, ndlp, cmdiocb);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_prli_reglogin_issue(struct lpfc_hba * phba,
-			     struct lpfc_nodelist * ndlp, void *arg,
+lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport,
+			     struct lpfc_nodelist *ndlp,
+			     void *arg,
 			     uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
+	lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba,
-			     struct lpfc_nodelist * ndlp, void *arg,
+lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
+			     struct lpfc_nodelist *ndlp,
+			     void *arg,
 			     uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
+	struct lpfc_hba   *phba = vport->phba;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 	LPFC_MBOXQ_t	  *mb;
 	LPFC_MBOXQ_t	  *nextmb;
 	struct lpfc_dmabuf *mp;
@@ -1038,7 +1047,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba,
 		}
 	}
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
 		if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) &&
 		   (ndlp == (struct lpfc_nodelist *) mb->context2)) {
@@ -1051,49 +1060,49 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba,
 			mempool_free(mb, phba->mbox_mem_pool);
 		}
 	}
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
-	lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
+	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_padisc_reglogin_issue(struct lpfc_hba * phba,
-			       struct lpfc_nodelist * ndlp, void *arg,
+lpfc_rcv_padisc_reglogin_issue(struct lpfc_vport *vport,
+			       struct lpfc_nodelist *ndlp,
+			       void *arg,
 			       uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	cmdiocb = (struct lpfc_iocbq *) arg;
-
-	lpfc_rcv_padisc(phba, ndlp, cmdiocb);
+	lpfc_rcv_padisc(vport, ndlp, cmdiocb);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba,
-			     struct lpfc_nodelist * ndlp, void *arg,
+lpfc_rcv_prlo_reglogin_issue(struct lpfc_vport *vport,
+			     struct lpfc_nodelist *ndlp,
+			     void *arg,
 			     uint32_t evt)
 {
 	struct lpfc_iocbq *cmdiocb;
 
 	cmdiocb = (struct lpfc_iocbq *) arg;
-	lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
+	lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
-				  struct lpfc_nodelist * ndlp,
-				  void *arg, uint32_t evt)
+lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
+				  struct lpfc_nodelist *ndlp,
+				  void *arg,
+				  uint32_t evt)
 {
-	LPFC_MBOXQ_t *pmb;
-	MAILBOX_t *mb;
-	uint32_t did;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
+	LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
+	MAILBOX_t *mb = &pmb->mb;
+	uint32_t did  = mb->un.varWords[1];
 
-	pmb = (LPFC_MBOXQ_t *) arg;
-	mb = &pmb->mb;
-	did = mb->un.varWords[1];
 	if (mb->mbxStatus) {
 		/* RegLogin failed */
 		lpfc_printf_log(phba,
@@ -1101,7 +1110,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
 				LOG_DISCOVERY,
 				"%d:0246 RegLogin failed Data: x%x x%x x%x\n",
 				phba->brd_no,
-				did, mb->mbxStatus, phba->hba_state);
+				did, mb->mbxStatus, vport->port_state);
 
 		/*
 		 * If RegLogin failed due to lack of HBA resources do not
@@ -1109,20 +1118,20 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
 		 */
 		if (mb->mbxStatus == MBXERR_RPI_FULL) {
 			ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE);
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
 			return ndlp->nlp_state;
 		}
 
-		/* Put ndlp in npr list set plogi timer for 1 sec */
+		/* Put ndlp in npr state set plogi timer for 1 sec */
 		mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
-		spin_lock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag |= NLP_DELAY_TMO;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 		ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
 
-		lpfc_issue_els_logo(phba, ndlp, 0);
+		lpfc_issue_els_logo(vport, ndlp, 0);
 		ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
 		return ndlp->nlp_state;
 	}
 
@@ -1131,91 +1140,92 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
 	/* Only if we are not a fabric nport do we issue PRLI */
 	if (!(ndlp->nlp_type & NLP_FABRIC)) {
 		ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_PRLI_ISSUE);
-		lpfc_issue_els_prli(phba, ndlp, 0);
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
+		lpfc_issue_els_prli(vport, ndlp, 0);
 	} else {
 		ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
 	}
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_device_rm_reglogin_issue(struct lpfc_hba * phba,
-			      struct lpfc_nodelist * ndlp, void *arg,
+lpfc_device_rm_reglogin_issue(struct lpfc_vport *vport,
+			      struct lpfc_nodelist *ndlp,
+			      void *arg,
 			      uint32_t evt)
 {
-	if(ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
+	if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag |= NLP_NODEV_REMOVE;
+		spin_unlock_irq(shost->host_lock);
 		return ndlp->nlp_state;
-	}
-	else {
-		lpfc_drop_node(phba, ndlp);
+	} else {
+		lpfc_drop_node(vport, ndlp);
 		return NLP_STE_FREED_NODE;
 	}
 }
 
 static uint32_t
-lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba,
-			       struct lpfc_nodelist * ndlp, void *arg,
-			       uint32_t evt)
+lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport,
+				 struct lpfc_nodelist *ndlp,
+				 void *arg,
+				 uint32_t evt)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
 	ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
-	spin_lock_irq(phba->host->host_lock);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_plogi_prli_issue(struct lpfc_hba * phba,
-			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_plogi_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			  void *arg, uint32_t evt)
 {
 	struct lpfc_iocbq *cmdiocb;
 
 	cmdiocb = (struct lpfc_iocbq *) arg;
 
-	lpfc_rcv_plogi(phba, ndlp, cmdiocb);
+	lpfc_rcv_plogi(vport, ndlp, cmdiocb);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_prli_prli_issue(struct lpfc_hba * phba,
-			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			 void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
+	lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba,
-			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_logo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			 void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
 	/* Software abort outstanding PRLI before sending acc */
-	lpfc_els_abort(phba, ndlp);
+	lpfc_els_abort(vport->phba, ndlp);
 
-	lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
+	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_padisc_prli_issue(struct lpfc_hba * phba,
-			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_padisc_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			   void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	lpfc_rcv_padisc(phba, ndlp, cmdiocb);
+	lpfc_rcv_padisc(vport, ndlp, cmdiocb);
 	return ndlp->nlp_state;
 }
 
@@ -1225,21 +1235,21 @@ lpfc_rcv_padisc_prli_issue(struct lpfc_hba * phba,
  * NEXT STATE = PRLI_ISSUE
  */
 static uint32_t
-lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba,
-			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_prlo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			 void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	cmdiocb = (struct lpfc_iocbq *) arg;
-	lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
+	lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba,
-			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			  void *arg, uint32_t evt)
 {
 	struct lpfc_iocbq *cmdiocb, *rspiocb;
+	struct lpfc_hba   *phba = vport->phba;
 	IOCB_t *irsp;
 	PRLI *npr;
 
@@ -1250,7 +1260,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba,
 	irsp = &rspiocb->iocb;
 	if (irsp->ulpStatus) {
 		ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
-		lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
 		return ndlp->nlp_state;
 	}
 
@@ -1268,7 +1278,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba,
 	}
 
 	ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_MAPPED_NODE);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
 	return ndlp->nlp_state;
 }
 
@@ -1286,22 +1296,25 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba,
   *    This routine is envoked when we a request to remove a nport we are in the
   *    process of PRLIing. We should software abort outstanding prli, unreg
   *    login, send a logout. We will change node state to UNUSED_NODE, put it
-  *    on plogi list so it can be freed when LOGO completes.
+  *    in plogi state so it can be freed when LOGO completes.
   *
   */
 static uint32_t
-lpfc_device_rm_prli_issue(struct lpfc_hba * phba,
-			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_device_rm_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			  void *arg, uint32_t evt)
 {
-	if(ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
+	if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag |= NLP_NODEV_REMOVE;
+		spin_unlock_irq(shost->host_lock);
 		return ndlp->nlp_state;
-	}
-	else {
+	} else {
 		/* software abort outstanding PLOGI */
-		lpfc_els_abort(phba, ndlp);
+		lpfc_els_abort(vport->phba, ndlp);
 
-		lpfc_drop_node(phba, ndlp);
+		lpfc_drop_node(vport, ndlp);
 		return NLP_STE_FREED_NODE;
 	}
 }
@@ -1324,261 +1337,247 @@ lpfc_device_rm_prli_issue(struct lpfc_hba * phba,
   *    outstanding PRLI command, then free the node entry.
   */
 static uint32_t
-lpfc_device_recov_prli_issue(struct lpfc_hba * phba,
-			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_device_recov_prli_issue(struct lpfc_vport *vport,
+			     struct lpfc_nodelist *ndlp,
+			     void *arg,
+			     uint32_t evt)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
+
 	/* software abort outstanding PRLI */
 	lpfc_els_abort(phba, ndlp);
 
 	ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
-	spin_lock_irq(phba->host->host_lock);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_plogi_unmap_node(struct lpfc_hba * phba,
-			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_plogi_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			  void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	cmdiocb = (struct lpfc_iocbq *) arg;
-
-	lpfc_rcv_plogi(phba, ndlp, cmdiocb);
+	lpfc_rcv_plogi(vport, ndlp, cmdiocb);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_prli_unmap_node(struct lpfc_hba * phba,
-			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_prli_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			 void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	cmdiocb = (struct lpfc_iocbq *) arg;
-
-	lpfc_rcv_prli(phba, ndlp, cmdiocb);
-	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
+	lpfc_rcv_prli(vport, ndlp, cmdiocb);
+	lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba,
-			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_logo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			 void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
+	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_padisc_unmap_node(struct lpfc_hba * phba,
-			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_padisc_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			   void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	lpfc_rcv_padisc(phba, ndlp, cmdiocb);
+	lpfc_rcv_padisc(vport, ndlp, cmdiocb);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba,
-			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_prlo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			 void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	cmdiocb = (struct lpfc_iocbq *) arg;
-
-	lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
+	lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_device_recov_unmap_node(struct lpfc_hba * phba,
-			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_device_recov_unmap_node(struct lpfc_vport *vport,
+			     struct lpfc_nodelist *ndlp,
+			     void *arg,
+			     uint32_t evt)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
 	ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE;
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
-	lpfc_disc_set_adisc(phba, ndlp);
+	spin_unlock_irq(shost->host_lock);
+	lpfc_disc_set_adisc(vport, ndlp);
 
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_plogi_mapped_node(struct lpfc_hba * phba,
-			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_plogi_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			   void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	cmdiocb = (struct lpfc_iocbq *) arg;
-
-	lpfc_rcv_plogi(phba, ndlp, cmdiocb);
+	lpfc_rcv_plogi(vport, ndlp, cmdiocb);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_prli_mapped_node(struct lpfc_hba * phba,
-			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_prli_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			  void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	cmdiocb = (struct lpfc_iocbq *) arg;
-
-	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
+	lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba,
-			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_logo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			  void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	cmdiocb = (struct lpfc_iocbq *) arg;
-
-	lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
+	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_padisc_mapped_node(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_rcv_padisc_mapped_node(struct lpfc_vport *vport,
+			    struct lpfc_nodelist *ndlp,
+			    void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	lpfc_rcv_padisc(phba, ndlp, cmdiocb);
+	lpfc_rcv_padisc(vport, ndlp, cmdiocb);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba,
-			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			  void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_hba  *phba = vport->phba;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
 	/* flush the target */
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
 			       ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 
 	/* Treat like rcv logo */
-	lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO);
+	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_device_recov_mapped_node(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_device_recov_mapped_node(struct lpfc_vport *vport,
+			      struct lpfc_nodelist *ndlp,
+			      void *arg,
+			      uint32_t evt)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
 	ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE;
-	lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE);
-	spin_lock_irq(phba->host->host_lock);
+	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
-	spin_unlock_irq(phba->host->host_lock);
-	lpfc_disc_set_adisc(phba, ndlp);
+	spin_unlock_irq(shost->host_lock);
+	lpfc_disc_set_adisc(vport, ndlp);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_rcv_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_iocbq *cmdiocb  = (struct lpfc_iocbq *) arg;
 
 	/* Ignore PLOGI if we have an outstanding LOGO */
 	if (ndlp->nlp_flag & NLP_LOGO_SND) {
 		return ndlp->nlp_state;
 	}
 
-	if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) {
-		spin_lock_irq(phba->host->host_lock);
+	if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
+		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);
 		return ndlp->nlp_state;
 	}
 
 	/* send PLOGI immediately, move to PLOGI issue state */
 	if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
 		ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
-		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);
 	}
 
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_prli_npr_node(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_rcv_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+		       void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq     *cmdiocb;
-	struct ls_rjt          stat;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
+	struct ls_rjt     stat;
 
 	memset(&stat, 0, sizeof (struct ls_rjt));
 	stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
 	stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
-	lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
+	lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp);
 
 	if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
 		if (ndlp->nlp_flag & NLP_NPR_ADISC) {
-			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);
 			ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
-			lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE);
-			lpfc_issue_els_adisc(phba, ndlp, 0);
+			spin_unlock_irq(shost->host_lock);
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
+			lpfc_issue_els_adisc(vport, ndlp, 0);
 		} else {
 			ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
-			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);
 		}
 	}
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_logo_npr_node(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_rcv_logo_npr_node(struct lpfc_vport *vport,  struct lpfc_nodelist *ndlp,
+		       void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq     *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
+	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_rcv_padisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			 void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq     *cmdiocb;
-
-	cmdiocb = (struct lpfc_iocbq *) arg;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	lpfc_rcv_padisc(phba, ndlp, cmdiocb);
+	lpfc_rcv_padisc(vport, ndlp, cmdiocb);
 
 	/*
 	 * Do not start discovery if discovery is about to start
@@ -1586,53 +1585,51 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba,
 	 * here will affect the counting of discovery threads.
 	 */
 	if (!(ndlp->nlp_flag & NLP_DELAY_TMO) &&
-		!(ndlp->nlp_flag & NLP_NPR_2B_DISC)){
+	    !(ndlp->nlp_flag & NLP_NPR_2B_DISC)){
 		if (ndlp->nlp_flag & NLP_NPR_ADISC) {
 			ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
-			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);
 		} else {
 			ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
-			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);
 		}
 	}
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_rcv_prlo_npr_node(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_rcv_prlo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+		       void *arg, uint32_t evt)
 {
-	struct lpfc_iocbq     *cmdiocb;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
 
-	cmdiocb = (struct lpfc_iocbq *) arg;
-
-	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);
 
-	lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+	lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
 
-	if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
+	if ((ndlp->nlp_flag & NLP_DELAY_TMO) == 0) {
 		mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
-		spin_lock_irq(phba->host->host_lock);
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag |= NLP_DELAY_TMO;
 		ndlp->nlp_flag &= ~NLP_NPR_ADISC;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 		ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
 	} else {
-		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);
 	}
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba,
-			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_cmpl_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			 void *arg, uint32_t evt)
 {
 	struct lpfc_iocbq *cmdiocb, *rspiocb;
 	IOCB_t *irsp;
@@ -1642,15 +1639,15 @@ lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba,
 
 	irsp = &rspiocb->iocb;
 	if (irsp->ulpStatus) {
-		lpfc_drop_node(phba, ndlp);
+		lpfc_drop_node(vport, ndlp);
 		return NLP_STE_FREED_NODE;
 	}
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba,
-			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_cmpl_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			void *arg, uint32_t evt)
 {
 	struct lpfc_iocbq *cmdiocb, *rspiocb;
 	IOCB_t *irsp;
@@ -1660,25 +1657,24 @@ lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba,
 
 	irsp = &rspiocb->iocb;
 	if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {
-		lpfc_drop_node(phba, ndlp);
+		lpfc_drop_node(vport, ndlp);
 		return NLP_STE_FREED_NODE;
 	}
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_cmpl_logo_npr_node(struct lpfc_hba * phba,
-		struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_cmpl_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			void *arg, uint32_t evt)
 {
-	lpfc_unreg_rpi(phba, ndlp);
+	lpfc_unreg_rpi(vport, ndlp);
 	/* This routine does nothing, just return the current state */
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_cmpl_adisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			 void *arg, uint32_t evt)
 {
 	struct lpfc_iocbq *cmdiocb, *rspiocb;
 	IOCB_t *irsp;
@@ -1688,28 +1684,25 @@ lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba,
 
 	irsp = &rspiocb->iocb;
 	if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {
-		lpfc_drop_node(phba, ndlp);
+		lpfc_drop_node(vport, ndlp);
 		return NLP_STE_FREED_NODE;
 	}
 	return ndlp->nlp_state;
 }
 
 static uint32_t
-lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport,
+			    struct lpfc_nodelist *ndlp,
+			    void *arg, uint32_t evt)
 {
-	LPFC_MBOXQ_t *pmb;
-	MAILBOX_t *mb;
-
-	pmb = (LPFC_MBOXQ_t *) arg;
-	mb = &pmb->mb;
+	LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
+	MAILBOX_t    *mb = &pmb->mb;
 
 	if (!mb->mbxStatus)
 		ndlp->nlp_rpi = mb->un.varWords[0];
 	else {
 		if (ndlp->nlp_flag & NLP_NODEV_REMOVE) {
-			lpfc_drop_node(phba, ndlp);
+			lpfc_drop_node(vport, ndlp);
 			return NLP_STE_FREED_NODE;
 		}
 	}
@@ -1717,28 +1710,32 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba,
 }
 
 static uint32_t
-lpfc_device_rm_npr_node(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_device_rm_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			void *arg, uint32_t evt)
 {
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
 	if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
+		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag |= NLP_NODEV_REMOVE;
+		spin_unlock_irq(shost->host_lock);
 		return ndlp->nlp_state;
 	}
-	lpfc_drop_node(phba, ndlp);
+	lpfc_drop_node(vport, ndlp);
 	return NLP_STE_FREED_NODE;
 }
 
 static uint32_t
-lpfc_device_recov_npr_node(struct lpfc_hba * phba,
-			    struct lpfc_nodelist * ndlp, void *arg,
-			    uint32_t evt)
+lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			   void *arg, uint32_t evt)
 {
-	spin_lock_irq(phba->host->host_lock);
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
+	spin_lock_irq(shost->host_lock);
 	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 	if (ndlp->nlp_flag & NLP_DELAY_TMO) {
-		lpfc_cancel_retry_delay_tmo(phba, ndlp);
+		lpfc_cancel_retry_delay_tmo(vport, ndlp);
 	}
 	return ndlp->nlp_state;
 }
@@ -1801,7 +1798,7 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba,
  */
 
 static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
-     (struct lpfc_hba *, struct lpfc_nodelist *, void *, uint32_t) = {
+     (struct lpfc_vport *, struct lpfc_nodelist *, void *, uint32_t) = {
 	/* Action routine                  Event       Current State  */
 	lpfc_rcv_plogi_unused_node,	/* RCV_PLOGI   UNUSED_NODE    */
 	lpfc_rcv_els_unused_node,	/* RCV_PRLI        */
@@ -1917,11 +1914,12 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
 };
 
 int
-lpfc_disc_state_machine(struct lpfc_hba * phba,
-			struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
+lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+			void *arg, uint32_t evt)
 {
+	struct lpfc_hba  *phba = vport->phba;
 	uint32_t cur_state, rc;
-	uint32_t(*func) (struct lpfc_hba *, struct lpfc_nodelist *, void *,
+	uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *,
 			 uint32_t);
 
 	lpfc_nlp_get(ndlp);
@@ -1937,7 +1935,7 @@ lpfc_disc_state_machine(struct lpfc_hba * phba,
 			evt, ndlp->nlp_DID, cur_state, ndlp->nlp_flag);
 
 	func = lpfc_disc_action[(cur_state * NLP_EVT_MAX_EVENT) + evt];
-	rc = (func) (phba, ndlp, arg, evt);
+	rc = (func) (vport, ndlp, arg, evt);
 
 	/* DSM out state <rc> on NPort <nlp_DID> */
 	lpfc_printf_log(phba,
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 9a12d05e99e4d938460948186e8d0df9f7f9df5d..6db7ad83cc3907ca97963fd3dd0f6e86f0381464 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -41,7 +41,6 @@
 #define LPFC_RESET_WAIT  2
 #define LPFC_ABORT_WAIT  2
 
-
 /*
  * This routine allocates a scsi buffer, which contains all the necessary
  * information needed to initiate a SCSI I/O.  The non-DMAable buffer region
@@ -51,8 +50,9 @@
  * and the BPL BDE is setup in the IOCB.
  */
 static struct lpfc_scsi_buf *
-lpfc_new_scsi_buf(struct lpfc_hba * phba)
+lpfc_new_scsi_buf(struct lpfc_vport *vport)
 {
+	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_scsi_buf *psb;
 	struct ulp_bde64 *bpl;
 	IOCB_t *iocb;
@@ -63,7 +63,6 @@ lpfc_new_scsi_buf(struct lpfc_hba * phba)
 	if (!psb)
 		return NULL;
 	memset(psb, 0, sizeof (struct lpfc_scsi_buf));
-	psb->scsi_hba = phba;
 
 	/*
 	 * Get memory from the pci pool to map the virt space to pci bus space
@@ -292,12 +291,13 @@ lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
 }
 
 static void
-lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_iocbq *rsp_iocb)
+lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
+		    struct lpfc_iocbq *rsp_iocb)
 {
 	struct scsi_cmnd *cmnd = lpfc_cmd->pCmd;
 	struct fcp_cmnd *fcpcmd = lpfc_cmd->fcp_cmnd;
 	struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp;
-	struct lpfc_hba *phba = lpfc_cmd->scsi_hba;
+	struct lpfc_hba *phba = vport->phba;
 	uint32_t fcpi_parm = rsp_iocb->iocb.un.fcpi.fcpi_parm;
 	uint32_t resp_info = fcprsp->rspStatus2;
 	uint32_t scsi_status = fcprsp->rspStatus3;
@@ -429,6 +429,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 {
 	struct lpfc_scsi_buf *lpfc_cmd =
 		(struct lpfc_scsi_buf *) pIocbIn->context1;
+	struct lpfc_vport      *vport = pIocbIn->vport;
 	struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
 	struct lpfc_nodelist *pnode = rdata->pnode;
 	struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
@@ -457,7 +458,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 		switch (lpfc_cmd->status) {
 		case IOSTAT_FCP_RSP_ERROR:
 			/* Call FCP RSP handler to determine result */
-			lpfc_handle_fcp_err(lpfc_cmd,pIocbOut);
+			lpfc_handle_fcp_err(vport, lpfc_cmd, pIocbOut);
 			break;
 		case IOSTAT_NPORT_BSY:
 		case IOSTAT_FABRIC_BSY:
@@ -534,7 +535,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 					tmp_sdev->queue_depth - 1);
 		}
 		/*
- 		 * The queue depth cannot be lowered any more.
+		 * The queue depth cannot be lowered any more.
 		 * Modify the returned error code to store
 		 * the final depth value set by
 		 * scsi_track_queue_full.
@@ -553,9 +554,10 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 }
 
 static void
-lpfc_scsi_prep_cmnd(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd,
-			struct lpfc_nodelist *pnode)
+lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
+		    struct lpfc_nodelist *pnode)
 {
+	struct lpfc_hba *phba = vport->phba;
 	struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd;
 	struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
 	IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
@@ -642,15 +644,15 @@ lpfc_scsi_prep_cmnd(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd,
 	piocbq->context1  = lpfc_cmd;
 	piocbq->iocb_cmpl = lpfc_scsi_cmd_iocb_cmpl;
 	piocbq->iocb.ulpTimeout = lpfc_cmd->timeout;
+	piocbq->vport = vport;
 }
 
 static int
-lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
+lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport,
 			     struct lpfc_scsi_buf *lpfc_cmd,
 			     unsigned int lun,
 			     uint8_t task_mgmt_cmd)
 {
-	struct lpfc_sli *psli;
 	struct lpfc_iocbq *piocbq;
 	IOCB_t *piocb;
 	struct fcp_cmnd *fcp_cmnd;
@@ -661,8 +663,9 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
 		return 0;
 	}
 
-	psli = &phba->sli;
 	piocbq = &(lpfc_cmd->cur_iocbq);
+	piocbq->vport = vport;
+
 	piocb = &piocbq->iocb;
 
 	fcp_cmnd = lpfc_cmd->fcp_cmnd;
@@ -688,7 +691,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
 		piocb->ulpTimeout = lpfc_cmd->timeout;
 	}
 
-	return (1);
+	return 1;
 }
 
 static void
@@ -704,10 +707,11 @@ lpfc_tskmgmt_def_cmpl(struct lpfc_hba *phba,
 }
 
 static int
-lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba,
+lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport,
 		    unsigned  tgt_id, unsigned int lun,
 		    struct lpfc_rport_data *rdata)
 {
+	struct lpfc_hba   *phba = vport->phba;
 	struct lpfc_iocbq *iocbq;
 	struct lpfc_iocbq *iocbqrsp;
 	int ret;
@@ -716,12 +720,11 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba,
 		return FAILED;
 
 	lpfc_cmd->rdata = rdata;
-	ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun,
+	ret = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, lun,
 					   FCP_TARGET_RESET);
 	if (!ret)
 		return FAILED;
 
-	lpfc_cmd->scsi_hba = phba;
 	iocbq = &lpfc_cmd->cur_iocbq;
 	iocbqrsp = lpfc_sli_get_iocbq(phba);
 
@@ -758,7 +761,8 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba,
 const char *
 lpfc_info(struct Scsi_Host *host)
 {
-	struct lpfc_hba    *phba = (struct lpfc_hba *) host->hostdata;
+	struct lpfc_vport *vport = (struct lpfc_vport *) host->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	int len;
 	static char  lpfcinfobuf[384];
 
@@ -800,26 +804,22 @@ void lpfc_poll_start_timer(struct lpfc_hba * phba)
 
 void lpfc_poll_timeout(unsigned long ptr)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba *)ptr;
-	unsigned long iflag;
-
-	spin_lock_irqsave(phba->host->host_lock, iflag);
+	struct lpfc_hba *phba = (struct lpfc_hba *) ptr;
 
 	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
 		lpfc_sli_poll_fcp_ring (phba);
 		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
 			lpfc_poll_rearm_timer(phba);
 	}
-
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
 }
 
 static int
 lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 {
-	struct lpfc_hba *phba =
-		(struct lpfc_hba *) cmnd->device->host->hostdata;
-	struct lpfc_sli *psli = &phba->sli;
+	struct Scsi_Host  *shost = cmnd->device->host;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+	struct lpfc_sli   *psli = &phba->sli;
 	struct lpfc_rport_data *rdata = cmnd->device->hostdata;
 	struct lpfc_nodelist *ndlp = rdata->pnode;
 	struct lpfc_scsi_buf *lpfc_cmd;
@@ -862,7 +862,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 	if (err)
 		goto out_host_busy_free_buf;
 
-	lpfc_scsi_prep_cmnd(phba, lpfc_cmd, ndlp);
+	lpfc_scsi_prep_cmnd(vport, lpfc_cmd, ndlp);
 
 	err = lpfc_sli_issue_iocb(phba, &phba->sli.ring[psli->fcp_ring],
 				&lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB);
@@ -907,8 +907,9 @@ lpfc_block_error_handler(struct scsi_cmnd *cmnd)
 static int
 lpfc_abort_handler(struct scsi_cmnd *cmnd)
 {
-	struct Scsi_Host *shost = cmnd->device->host;
-	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
+	struct Scsi_Host  *shost = cmnd->device->host;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring];
 	struct lpfc_iocbq *iocb;
 	struct lpfc_iocbq *abtsiocb;
@@ -918,8 +919,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
 	int ret = SUCCESS;
 
 	lpfc_block_error_handler(cmnd);
-	spin_lock_irq(shost->host_lock);
-
 	lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
 	BUG_ON(!lpfc_cmd);
 
@@ -956,12 +955,13 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
 
 	icmd->ulpLe = 1;
 	icmd->ulpClass = cmd->ulpClass;
-	if (phba->hba_state >= LPFC_LINK_UP)
+	if (lpfc_is_link_up(phba))
 		icmd->ulpCommand = CMD_ABORT_XRI_CN;
 	else
 		icmd->ulpCommand = CMD_CLOSE_XRI_CN;
 
 	abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
+	abtsiocb->vport = vport;
 	if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) == IOCB_ERROR) {
 		lpfc_sli_release_iocbq(phba, abtsiocb);
 		ret = FAILED;
@@ -977,9 +977,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
 		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
 			lpfc_sli_poll_fcp_ring (phba);
 
-		spin_unlock_irq(phba->host->host_lock);
-			schedule_timeout_uninterruptible(LPFC_ABORT_WAIT*HZ);
-		spin_lock_irq(phba->host->host_lock);
+		schedule_timeout_uninterruptible(LPFC_ABORT_WAIT * HZ);
 		if (++loop_count
 		    > (2 * phba->cfg_devloss_tmo)/LPFC_ABORT_WAIT)
 			break;
@@ -1002,16 +1000,15 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
 			phba->brd_no, ret, cmnd->device->id,
 			cmnd->device->lun, cmnd->serial_number);
 
-	spin_unlock_irq(shost->host_lock);
-
 	return ret;
 }
 
 static int
 lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
 {
-	struct Scsi_Host *shost = cmnd->device->host;
-	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
+	struct Scsi_Host  *shost = cmnd->device->host;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	struct lpfc_scsi_buf *lpfc_cmd;
 	struct lpfc_iocbq *iocbq, *iocbqrsp;
 	struct lpfc_rport_data *rdata = cmnd->device->hostdata;
@@ -1022,7 +1019,6 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
 	int cnt, loopcnt;
 
 	lpfc_block_error_handler(cmnd);
-	spin_lock_irq(shost->host_lock);
 	loopcnt = 0;
 	/*
 	 * If target is not in a MAPPED state, delay the reset until
@@ -1033,9 +1029,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
 			goto out;
 
 		if (pnode->nlp_state != NLP_STE_MAPPED_NODE) {
-			spin_unlock_irq(phba->host->host_lock);
 			schedule_timeout_uninterruptible(msecs_to_jiffies(500));
-			spin_lock_irq(phba->host->host_lock);
 			loopcnt++;
 			rdata = cmnd->device->hostdata;
 			if (!rdata ||
@@ -1054,15 +1048,14 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
 			break;
 	}
 
-	lpfc_cmd = lpfc_get_scsi_buf (phba);
+	lpfc_cmd = lpfc_get_scsi_buf(phba);
 	if (lpfc_cmd == NULL)
 		goto out;
 
 	lpfc_cmd->timeout = 60;
-	lpfc_cmd->scsi_hba = phba;
 	lpfc_cmd->rdata = rdata;
 
-	ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, cmnd->device->lun,
+	ret = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, cmnd->device->lun,
 					   FCP_TARGET_RESET);
 	if (!ret)
 		goto out_free_scsi_buf;
@@ -1110,10 +1103,8 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
 				    cmnd->device->id, cmnd->device->lun,
 				    0, LPFC_CTX_LUN);
 	loopcnt = 0;
-	while(cnt) {
-		spin_unlock_irq(phba->host->host_lock);
+	while (cnt) {
 		schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
-		spin_lock_irq(phba->host->host_lock);
 
 		if (++loopcnt
 		    > (2 * phba->cfg_devloss_tmo)/LPFC_RESET_WAIT)
@@ -1143,15 +1134,15 @@ out_free_scsi_buf:
 			ret, cmd_status, cmd_result);
 
 out:
-	spin_unlock_irq(shost->host_lock);
 	return ret;
 }
 
 static int
 lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
 {
-	struct Scsi_Host *shost = cmnd->device->host;
-	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
+	struct Scsi_Host  *shost = cmnd->device->host;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	struct lpfc_nodelist *ndlp = NULL;
 	int match;
 	int ret = FAILED, i, err_count = 0;
@@ -1159,7 +1150,6 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
 	struct lpfc_scsi_buf * lpfc_cmd;
 
 	lpfc_block_error_handler(cmnd);
-	spin_lock_irq(shost->host_lock);
 
 	lpfc_cmd = lpfc_get_scsi_buf(phba);
 	if (lpfc_cmd == NULL)
@@ -1167,7 +1157,6 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
 
 	/* The lpfc_cmd storage is reused.  Set all loop invariants. */
 	lpfc_cmd->timeout = 60;
-	lpfc_cmd->scsi_hba = phba;
 
 	/*
 	 * Since the driver manages a single bus device, reset all
@@ -1177,7 +1166,8 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
 	for (i = 0; i < LPFC_MAX_TARGET; i++) {
 		/* Search for mapped node by target ID */
 		match = 0;
-		list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
+		spin_lock_irq(shost->host_lock);
+		list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
 			if (ndlp->nlp_state == NLP_STE_MAPPED_NODE &&
 			    i == ndlp->nlp_sid &&
 			    ndlp->rport) {
@@ -1185,10 +1175,12 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
 				break;
 			}
 		}
+		spin_unlock_irq(shost->host_lock);
 		if (!match)
 			continue;
 
-		ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, i, cmnd->device->lun,
+		ret = lpfc_scsi_tgt_reset(lpfc_cmd, vport, i,
+					  cmnd->device->lun,
 					  ndlp->rport->dd_data);
 		if (ret != SUCCESS) {
 			lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
@@ -1218,10 +1210,8 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
 		lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
 				    0, 0, 0, LPFC_CTX_HOST);
 	loopcnt = 0;
-	while(cnt) {
-		spin_unlock_irq(phba->host->host_lock);
+	while (cnt) {
 		schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
-		spin_lock_irq(phba->host->host_lock);
 
 		if (++loopcnt
 		    > (2 * phba->cfg_devloss_tmo)/LPFC_RESET_WAIT)
@@ -1245,14 +1235,14 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
 			"%d:0714 SCSI layer issued Bus Reset Data: x%x\n",
 			phba->brd_no, ret);
 out:
-	spin_unlock_irq(shost->host_lock);
 	return ret;
 }
 
 static int
 lpfc_slave_alloc(struct scsi_device *sdev)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata;
+	struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
 	struct lpfc_scsi_buf *scsi_buf = NULL;
 	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
 	uint32_t total = 0, i;
@@ -1289,7 +1279,7 @@ lpfc_slave_alloc(struct scsi_device *sdev)
 	}
 
 	for (i = 0; i < num_to_alloc; i++) {
-		scsi_buf = lpfc_new_scsi_buf(phba);
+		scsi_buf = lpfc_new_scsi_buf(vport);
 		if (!scsi_buf) {
 			lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
 					"%d:0706 Failed to allocate command "
@@ -1308,8 +1298,9 @@ lpfc_slave_alloc(struct scsi_device *sdev)
 static int
 lpfc_slave_configure(struct scsi_device *sdev)
 {
-	struct lpfc_hba *phba = (struct lpfc_hba *) sdev->host->hostdata;
-	struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
+	struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+	struct fc_rport   *rport = starget_to_rport(sdev->sdev_target);
 
 	if (sdev->tagged_supported)
 		scsi_activate_tcq(sdev, phba->cfg_lun_queue_depth);
@@ -1357,6 +1348,6 @@ struct scsi_host_template lpfc_template = {
 	.sg_tablesize		= LPFC_SG_SEG_CNT,
 	.cmd_per_lun		= LPFC_CMD_PER_LUN,
 	.use_clustering		= ENABLE_CLUSTERING,
-	.shost_attrs		= lpfc_host_attrs,
+	.shost_attrs		= lpfc_hba_attrs,
 	.max_sectors		= 0xFFFF,
 };
diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h
index cdcd2535803f2f7648df3e8e99b6161806f4b551..31787bb6d53ef1cd9e120dead2747f02ebe12f2a 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.h
+++ b/drivers/scsi/lpfc/lpfc_scsi.h
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2006 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -110,7 +110,6 @@ struct fcp_cmnd {
 struct lpfc_scsi_buf {
 	struct list_head list;
 	struct scsi_cmnd *pCmd;
-	struct lpfc_hba *scsi_hba;
 	struct lpfc_rport_data *rdata;
 
 	uint32_t timeout;
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index a1e721459e2b21a1734bff082c33e4f3c7df2bc7..1edac15eed40b7e7c520c45e5b748dc56d1aa997 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -52,9 +52,9 @@
 				"Data: x%x x%x x%x\n", \
 				phba->brd_no, \
 				mb->mbxCommand,		\
-				phba->hba_state,	\
+				phba->pport->port_state,	\
 				psli->sli_flag,	\
-				flag);
+				flag)
 
 
 /* There are only four IOCB completion types. */
@@ -65,8 +65,8 @@ typedef enum _lpfc_iocb_type {
 	LPFC_ABORT_IOCB
 } lpfc_iocb_type;
 
-struct lpfc_iocbq *
-lpfc_sli_get_iocbq(struct lpfc_hba * phba)
+static struct lpfc_iocbq *
+__lpfc_sli_get_iocbq(struct lpfc_hba *phba)
 {
 	struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
 	struct lpfc_iocbq * iocbq = NULL;
@@ -75,10 +75,22 @@ lpfc_sli_get_iocbq(struct lpfc_hba * phba)
 	return iocbq;
 }
 
+struct lpfc_iocbq *
+lpfc_sli_get_iocbq(struct lpfc_hba *phba)
+{
+	struct lpfc_iocbq * iocbq = NULL;
+	unsigned long iflags;
+
+	spin_lock_irqsave(&phba->hbalock, iflags);
+	iocbq = __lpfc_sli_get_iocbq(phba);
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
+	return iocbq;
+}
+
 void
-lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq)
+__lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
 {
-	size_t start_clean = (size_t)(&((struct lpfc_iocbq *)NULL)->iocb);
+	size_t start_clean = offsetof(struct lpfc_iocbq, iocb);
 
 	/*
 	 * Clean all volatile data fields, preserve iotag and node struct.
@@ -87,6 +99,19 @@ lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq)
 	list_add_tail(&iocbq->list, &phba->lpfc_iocb_list);
 }
 
+void
+lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
+{
+	unsigned long iflags;
+
+	/*
+	 * Clean all volatile data fields, preserve iotag and node struct.
+	 */
+	spin_lock_irqsave(&phba->hbalock, iflags);
+	__lpfc_sli_release_iocbq(phba, iocbq);
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
+}
+
 /*
  * Translate the iocb command to an iocb command type used to decide the final
  * disposition of each completed IOCB.
@@ -166,14 +191,14 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd)
 }
 
 static int
-lpfc_sli_ring_map(struct lpfc_hba * phba, LPFC_MBOXQ_t *pmb)
+lpfc_sli_ring_map(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
 	struct lpfc_sli *psli = &phba->sli;
 	MAILBOX_t *pmbox = &pmb->mb;
 	int i, rc;
 
 	for (i = 0; i < psli->num_rings; i++) {
-		phba->hba_state = LPFC_INIT_MBX_CMDS;
+		phba->link_state = LPFC_INIT_MBX_CMDS;
 		lpfc_config_ring(phba, i, pmb);
 		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
 		if (rc != MBX_SUCCESS) {
@@ -187,7 +212,7 @@ lpfc_sli_ring_map(struct lpfc_hba * phba, LPFC_MBOXQ_t *pmb)
 					pmbox->mbxCommand,
 					pmbox->mbxStatus,
 					i);
-			phba->hba_state = LPFC_HBA_ERROR;
+			phba->link_state = LPFC_HBA_ERROR;
 			return -ENXIO;
 		}
 	}
@@ -195,20 +220,20 @@ lpfc_sli_ring_map(struct lpfc_hba * phba, LPFC_MBOXQ_t *pmb)
 }
 
 static int
-lpfc_sli_ringtxcmpl_put(struct lpfc_hba * phba,
-			struct lpfc_sli_ring * pring, struct lpfc_iocbq * piocb)
+lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+			struct lpfc_iocbq *piocb)
 {
 	list_add_tail(&piocb->list, &pring->txcmplq);
 	pring->txcmplq_cnt++;
 	if (unlikely(pring->ringno == LPFC_ELS_RING))
-		mod_timer(&phba->els_tmofunc,
-					jiffies + HZ * (phba->fc_ratov << 1));
+		mod_timer(&piocb->vport->els_tmofunc,
+			  jiffies + HZ * (phba->fc_ratov << 1));
 
-	return (0);
+	return 0;
 }
 
 static struct lpfc_iocbq *
-lpfc_sli_ringtx_get(struct lpfc_hba * phba, struct lpfc_sli_ring * pring)
+lpfc_sli_ringtx_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
 {
 	struct list_head *dlp;
 	struct lpfc_iocbq *cmd_iocb;
@@ -224,7 +249,7 @@ lpfc_sli_ringtx_get(struct lpfc_hba * phba, struct lpfc_sli_ring * pring)
 		 */
 		pring->txq_cnt--;
 	}
-	return (cmd_iocb);
+	return cmd_iocb;
 }
 
 static IOCB_t *
@@ -249,7 +274,7 @@ lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
 					phba->brd_no, pring->ringno,
 					pring->local_getidx, max_cmd_idx);
 
-			phba->hba_state = LPFC_HBA_ERROR;
+			phba->link_state = LPFC_HBA_ERROR;
 			/*
 			 * All error attention handlers are posted to
 			 * worker thread
@@ -272,33 +297,30 @@ lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
 }
 
 uint16_t
-lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq)
+lpfc_sli_next_iotag(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
 {
-	struct lpfc_iocbq ** new_arr;
-	struct lpfc_iocbq ** old_arr;
+	struct lpfc_iocbq **new_arr;
+	struct lpfc_iocbq **old_arr;
 	size_t new_len;
 	struct lpfc_sli *psli = &phba->sli;
 	uint16_t iotag;
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	iotag = psli->last_iotag;
 	if(++iotag < psli->iocbq_lookup_len) {
 		psli->last_iotag = iotag;
 		psli->iocbq_lookup[iotag] = iocbq;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(&phba->hbalock);
 		iocbq->iotag = iotag;
 		return iotag;
-	}
-	else if (psli->iocbq_lookup_len < (0xffff
+	} else if (psli->iocbq_lookup_len < (0xffff
 					   - LPFC_IOCBQ_LOOKUP_INCREMENT)) {
 		new_len = psli->iocbq_lookup_len + LPFC_IOCBQ_LOOKUP_INCREMENT;
-		spin_unlock_irq(phba->host->host_lock);
-		new_arr = kmalloc(new_len * sizeof (struct lpfc_iocbq *),
+		spin_unlock_irq(&phba->hbalock);
+		new_arr = kzalloc(new_len * sizeof (struct lpfc_iocbq *),
 				  GFP_KERNEL);
 		if (new_arr) {
-			memset((char *)new_arr, 0,
-			       new_len * sizeof (struct lpfc_iocbq *));
-			spin_lock_irq(phba->host->host_lock);
+			spin_lock_irq(&phba->hbalock);
 			old_arr = psli->iocbq_lookup;
 			if (new_len <= psli->iocbq_lookup_len) {
 				/* highly unprobable case */
@@ -307,11 +329,11 @@ lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq)
 				if(++iotag < psli->iocbq_lookup_len) {
 					psli->last_iotag = iotag;
 					psli->iocbq_lookup[iotag] = iocbq;
-					spin_unlock_irq(phba->host->host_lock);
+					spin_unlock_irq(&phba->hbalock);
 					iocbq->iotag = iotag;
 					return iotag;
 				}
-				spin_unlock_irq(phba->host->host_lock);
+				spin_unlock_irq(&phba->hbalock);
 				return 0;
 			}
 			if (psli->iocbq_lookup)
@@ -322,13 +344,13 @@ lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq)
 			psli->iocbq_lookup_len = new_len;
 			psli->last_iotag = iotag;
 			psli->iocbq_lookup[iotag] = iocbq;
-			spin_unlock_irq(phba->host->host_lock);
+			spin_unlock_irq(&phba->hbalock);
 			iocbq->iotag = iotag;
 			kfree(old_arr);
 			return iotag;
 		}
 	} else
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(&phba->hbalock);
 
 	lpfc_printf_log(phba, KERN_ERR,LOG_SLI,
 			"%d:0318 Failed to allocate IOTAG.last IOTAG is %d\n",
@@ -361,7 +383,7 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 	if (nextiocb->iocb_cmpl)
 		lpfc_sli_ringtxcmpl_put(phba, pring, nextiocb);
 	else
-		lpfc_sli_release_iocbq(phba, nextiocb);
+		__lpfc_sli_release_iocbq(phba, nextiocb);
 
 	/*
 	 * Let the HBA know what IOCB slot will be the next one the
@@ -373,8 +395,7 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 }
 
 static void
-lpfc_sli_update_full_ring(struct lpfc_hba * phba,
-			  struct lpfc_sli_ring *pring)
+lpfc_sli_update_full_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
 {
 	int ringno = pring->ringno;
 
@@ -393,8 +414,7 @@ lpfc_sli_update_full_ring(struct lpfc_hba * phba,
 }
 
 static void
-lpfc_sli_update_ring(struct lpfc_hba * phba,
-		     struct lpfc_sli_ring *pring)
+lpfc_sli_update_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
 {
 	int ringno = pring->ringno;
 
@@ -407,7 +427,7 @@ lpfc_sli_update_ring(struct lpfc_hba * phba,
 }
 
 static void
-lpfc_sli_resume_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring)
+lpfc_sli_resume_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
 {
 	IOCB_t *iocb;
 	struct lpfc_iocbq *nextiocb;
@@ -420,7 +440,7 @@ lpfc_sli_resume_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring)
 	 *  (d) IOCB processing is not blocked by the outstanding mbox command.
 	 */
 	if (pring->txq_cnt &&
-	    (phba->hba_state > LPFC_LINK_DOWN) &&
+	    lpfc_is_link_up(phba) &&
 	    (pring->ringno != phba->sli.fcp_ring ||
 	     phba->sli.sli_flag & LPFC_PROCESS_LA) &&
 	    !(pring->flag & LPFC_STOP_IOCB_MBX)) {
@@ -440,11 +460,13 @@ lpfc_sli_resume_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring)
 
 /* lpfc_sli_turn_on_ring is only called by lpfc_sli_handle_mb_event below */
 static void
-lpfc_sli_turn_on_ring(struct lpfc_hba * phba, int ringno)
+lpfc_sli_turn_on_ring(struct lpfc_hba *phba, int ringno)
 {
-	struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[ringno];
+	struct lpfc_pgp  *pgp = &phba->slim2p->mbx.us.s2.port[ringno];
+	unsigned long iflags;
 
 	/* If the ring is active, flag it */
+	spin_lock_irqsave(&phba->hbalock, iflags);
 	if (phba->sli.ring[ringno].cmdringaddr) {
 		if (phba->sli.ring[ringno].flag & LPFC_STOP_IOCB_MBX) {
 			phba->sli.ring[ringno].flag &= ~LPFC_STOP_IOCB_MBX;
@@ -453,11 +475,10 @@ lpfc_sli_turn_on_ring(struct lpfc_hba * phba, int ringno)
 			 */
 			phba->sli.ring[ringno].local_getidx
 				= le32_to_cpu(pgp->cmdGetInx);
-			spin_lock_irq(phba->host->host_lock);
 			lpfc_sli_resume_iocb(phba, &phba->sli.ring[ringno]);
-			spin_unlock_irq(phba->host->host_lock);
 		}
 	}
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
 }
 
 static int
@@ -517,10 +538,10 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
 		ret = MBX_SHUTDOWN;
 		break;
 	}
-	return (ret);
+	return ret;
 }
 static void
-lpfc_sli_wake_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
+lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
 {
 	wait_queue_head_t *pdone_q;
 
@@ -536,7 +557,7 @@ lpfc_sli_wake_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
 }
 
 void
-lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
 	struct lpfc_dmabuf *mp;
 	uint16_t rpi;
@@ -553,9 +574,9 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 	 * If a REG_LOGIN succeeded  after node is destroyed or node
 	 * is in re-discovery driver need to cleanup the RPI.
 	 */
-	if (!(phba->fc_flag & FC_UNLOADING) &&
-		(pmb->mb.mbxCommand == MBX_REG_LOGIN64) &&
-		(!pmb->mb.mbxStatus)) {
+	if (!(phba->pport->load_flag & FC_UNLOADING) &&
+	    pmb->mb.mbxCommand == MBX_REG_LOGIN64 &&
+	    !pmb->mb.mbxStatus) {
 
 		rpi = pmb->mb.un.varWords[0];
 		lpfc_unreg_login(phba, rpi, pmb);
@@ -565,24 +586,22 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 			return;
 	}
 
-	mempool_free( pmb, phba->mbox_mem_pool);
+	mempool_free(pmb, phba->mbox_mem_pool);
 	return;
 }
 
 int
-lpfc_sli_handle_mb_event(struct lpfc_hba * phba)
+lpfc_sli_handle_mb_event(struct lpfc_hba *phba)
 {
-	MAILBOX_t *mbox;
-	MAILBOX_t *pmbox;
+	MAILBOX_t *mbox, *pmbox;
 	LPFC_MBOXQ_t *pmb;
-	struct lpfc_sli *psli;
 	int i, rc;
 	uint32_t process_next;
+	unsigned long iflags;
 
-	psli = &phba->sli;
 	/* We should only get here if we are in SLI2 mode */
 	if (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE)) {
-		return (1);
+		return 1;
 	}
 
 	phba->sli.slistat.mbox_event++;
@@ -616,15 +635,18 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba)
 					pmbox->mbxCommand,
 					pmbox->mbxStatus);
 
-			spin_lock_irq(phba->host->host_lock);
+			spin_lock_irq(&phba->hbalock);
 			phba->sli.sli_flag |= LPFC_SLI_MBOX_ACTIVE;
-			spin_unlock_irq(phba->host->host_lock);
-			return (1);
+			spin_unlock_irq(&phba->hbalock);
+			return 1;
 		}
 
 	      mbout:
 		del_timer_sync(&phba->sli.mbox_tmo);
-		phba->work_hba_events &= ~WORKER_MBOX_TMO;
+
+		spin_lock_irqsave(&phba->pport->work_port_lock, iflags);
+		phba->pport->work_port_events &= ~WORKER_MBOX_TMO;
+		spin_unlock_irqrestore(&phba->pport->work_port_lock, iflags);
 
 		/*
 		 * It is a fatal error if unknown mbox command completion.
@@ -639,10 +661,10 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba)
 				"%d:0323 Unknown Mailbox command %x Cmpl\n",
 				phba->brd_no,
 				pmbox->mbxCommand);
-			phba->hba_state = LPFC_HBA_ERROR;
+			phba->link_state = LPFC_HBA_ERROR;
 			phba->work_hs = HS_FFER3;
 			lpfc_handle_eratt(phba);
-			return (0);
+			return 0;
 		}
 
 		phba->sli.mbox_active = NULL;
@@ -659,15 +681,15 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba)
 					pmbox->mbxCommand,
 					pmbox->mbxStatus,
 					pmbox->un.varWords[0],
-					phba->hba_state);
+					phba->pport->port_state);
 				pmbox->mbxStatus = 0;
 				pmbox->mbxOwner = OWN_HOST;
-				spin_lock_irq(phba->host->host_lock);
+				spin_lock_irq(&phba->hbalock);
 				phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
-				spin_unlock_irq(phba->host->host_lock);
+				spin_unlock_irq(&phba->hbalock);
 				rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
 				if (rc == MBX_SUCCESS)
-					return (0);
+					return 0;
 			}
 		}
 
@@ -699,12 +721,12 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba)
 
 	do {
 		process_next = 0;	/* by default don't loop */
-		spin_lock_irq(phba->host->host_lock);
+		spin_lock_irq(&phba->hbalock);
 		phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
 
 		/* Process next mailbox command if there is one */
 		if ((pmb = lpfc_mbox_get(phba))) {
-			spin_unlock_irq(phba->host->host_lock);
+			spin_unlock_irq(&phba->hbalock);
 			rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
 			if (rc == MBX_NOT_FINISHED) {
 				pmb->mb.mbxStatus = MBX_NOT_FINISHED;
@@ -713,7 +735,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba)
 				continue;	/* loop back */
 			}
 		} else {
-			spin_unlock_irq(phba->host->host_lock);
+			spin_unlock_irq(&phba->hbalock);
 			/* Turn on IOCB processing */
 			for (i = 0; i < phba->sli.num_rings; i++)
 				lpfc_sli_turn_on_ring(phba, i);
@@ -721,7 +743,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba)
 
 	} while (process_next);
 
-	return (0);
+	return 0;
 }
 static int
 lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
@@ -795,9 +817,9 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 }
 
 static struct lpfc_iocbq *
-lpfc_sli_iocbq_lookup(struct lpfc_hba * phba,
-		      struct lpfc_sli_ring * pring,
-		      struct lpfc_iocbq * prspiocb)
+lpfc_sli_iocbq_lookup(struct lpfc_hba *phba,
+		      struct lpfc_sli_ring *pring,
+		      struct lpfc_iocbq *prspiocb)
 {
 	struct lpfc_iocbq *cmd_iocb = NULL;
 	uint16_t iotag;
@@ -821,16 +843,18 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba * phba,
 }
 
 static int
-lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
+lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 			  struct lpfc_iocbq *saveq)
 {
-	struct lpfc_iocbq * cmdiocbp;
+	struct lpfc_iocbq *cmdiocbp;
 	int rc = 1;
 	unsigned long iflag;
 
 	/* Based on the iotag field, get the cmd IOCB from the txcmplq */
-	spin_lock_irqsave(phba->host->host_lock, iflag);
+	spin_lock_irqsave(&phba->hbalock, iflag);
 	cmdiocbp = lpfc_sli_iocbq_lookup(phba, pring, saveq);
+	spin_unlock_irqrestore(&phba->hbalock, iflag);
+
 	if (cmdiocbp) {
 		if (cmdiocbp->iocb_cmpl) {
 			/*
@@ -846,17 +870,8 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
 					saveq->iocb.un.ulpWord[4] =
 						IOERR_SLI_ABORTED;
 				}
-				spin_unlock_irqrestore(phba->host->host_lock,
-						       iflag);
-				(cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
-				spin_lock_irqsave(phba->host->host_lock, iflag);
-			}
-			else {
-				spin_unlock_irqrestore(phba->host->host_lock,
-						       iflag);
-				(cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
-				spin_lock_irqsave(phba->host->host_lock, iflag);
 			}
+			(cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
 		} else
 			lpfc_sli_release_iocbq(phba, cmdiocbp);
 	} else {
@@ -885,12 +900,11 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
 		}
 	}
 
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
 	return rc;
 }
 
-static void lpfc_sli_rsp_pointers_error(struct lpfc_hba * phba,
-					struct lpfc_sli_ring * pring)
+static void
+lpfc_sli_rsp_pointers_error(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
 {
 	struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
 	/*
@@ -904,7 +918,7 @@ static void lpfc_sli_rsp_pointers_error(struct lpfc_hba * phba,
 			le32_to_cpu(pgp->rspPutInx),
 			pring->numRiocb);
 
-	phba->hba_state = LPFC_HBA_ERROR;
+	phba->link_state = LPFC_HBA_ERROR;
 
 	/*
 	 * All error attention handlers are posted to
@@ -918,10 +932,10 @@ static void lpfc_sli_rsp_pointers_error(struct lpfc_hba * phba,
 	return;
 }
 
-void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba)
+void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba)
 {
-	struct lpfc_sli      * psli   = &phba->sli;
-	struct lpfc_sli_ring * pring = &psli->ring[LPFC_FCP_RING];
+	struct lpfc_sli      *psli  = &phba->sli;
+	struct lpfc_sli_ring *pring = &psli->ring[LPFC_FCP_RING];
 	IOCB_t *irsp = NULL;
 	IOCB_t *entry = NULL;
 	struct lpfc_iocbq *cmdiocbq = NULL;
@@ -933,6 +947,7 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba)
 	uint32_t rsp_cmpl = 0;
 	void __iomem *to_slim;
 	uint32_t ha_copy;
+	unsigned long iflags;
 
 	pring->stats.iocb_event++;
 
@@ -960,7 +975,7 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba)
 
 		lpfc_sli_pcimem_bcopy((uint32_t *) entry,
 				      (uint32_t *) &rspiocbq.iocb,
-				      sizeof (IOCB_t));
+				      sizeof(IOCB_t));
 		irsp = &rspiocbq.iocb;
 		type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK);
 		pring->stats.iocb_rsp++;
@@ -998,8 +1013,10 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba)
 				break;
 			}
 
+			spin_lock_irqsave(&phba->hbalock, iflags);
 			cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
 							 &rspiocbq);
+			spin_unlock_irqrestore(&phba->hbalock, iflags);
 			if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
 				(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
 						      &rspiocbq);
@@ -1045,13 +1062,16 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba)
 	ha_copy >>= (LPFC_FCP_RING * 4);
 
 	if ((rsp_cmpl > 0) && (ha_copy & HA_R0RE_REQ)) {
+		spin_lock_irqsave(&phba->hbalock, iflags);
 		pring->stats.iocb_rsp_full++;
 		status = ((CA_R0ATT | CA_R0RE_RSP) << (LPFC_FCP_RING * 4));
 		writel(status, phba->CAregaddr);
 		readl(phba->CAregaddr);
+		spin_unlock_irqrestore(&phba->hbalock, iflags);
 	}
 	if ((ha_copy & HA_R0CE_RSP) &&
 	    (pring->flag & LPFC_CALL_RING_AVAILABLE)) {
+		spin_lock_irqsave(&phba->hbalock, iflags);
 		pring->flag &= ~LPFC_CALL_RING_AVAILABLE;
 		pring->stats.iocb_cmd_empty++;
 
@@ -1062,6 +1082,7 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba)
 		if ((pring->lpfc_sli_cmd_available))
 			(pring->lpfc_sli_cmd_available) (phba, pring);
 
+		spin_unlock_irqrestore(&phba->hbalock, iflags);
 	}
 
 	return;
@@ -1072,10 +1093,10 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba)
  * to check it explicitly.
  */
 static int
-lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
-				struct lpfc_sli_ring * pring, uint32_t mask)
+lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
+				struct lpfc_sli_ring *pring, uint32_t mask)
 {
- 	struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
+	struct lpfc_pgp  *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
 	IOCB_t *irsp = NULL;
 	IOCB_t *entry = NULL;
 	struct lpfc_iocbq *cmdiocbq = NULL;
@@ -1086,9 +1107,9 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
 	lpfc_iocb_type type;
 	unsigned long iflag;
 	uint32_t rsp_cmpl = 0;
-	void __iomem  *to_slim;
+	void __iomem *to_slim;
 
-	spin_lock_irqsave(phba->host->host_lock, iflag);
+	spin_lock_irqsave(&phba->hbalock, iflag);
 	pring->stats.iocb_event++;
 
 	/*
@@ -1099,7 +1120,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
 	portRspPut = le32_to_cpu(pgp->rspPutInx);
 	if (unlikely(portRspPut >= portRspMax)) {
 		lpfc_sli_rsp_pointers_error(phba, pring);
-		spin_unlock_irqrestore(phba->host->host_lock, iflag);
+		spin_unlock_irqrestore(&phba->hbalock, iflag);
 		return 1;
 	}
 
@@ -1117,7 +1138,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
 
 		lpfc_sli_pcimem_bcopy((uint32_t *) entry,
 				      (uint32_t *) &rspiocbq.iocb,
-				      sizeof (IOCB_t));
+				      sizeof(IOCB_t));
 		INIT_LIST_HEAD(&(rspiocbq.list));
 		irsp = &rspiocbq.iocb;
 
@@ -1161,19 +1182,19 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
 					(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
 							      &rspiocbq);
 				} else {
-					spin_unlock_irqrestore(
-						phba->host->host_lock, iflag);
+					spin_unlock_irqrestore(&phba->hbalock,
+							       iflag);
 					(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
 							      &rspiocbq);
-					spin_lock_irqsave(phba->host->host_lock,
+					spin_lock_irqsave(&phba->hbalock,
 							  iflag);
 				}
 			}
 			break;
 		case LPFC_UNSOL_IOCB:
-			spin_unlock_irqrestore(phba->host->host_lock, iflag);
+			spin_unlock_irqrestore(&phba->hbalock, iflag);
 			lpfc_sli_process_unsol_iocb(phba, pring, &rspiocbq);
-			spin_lock_irqsave(phba->host->host_lock, iflag);
+			spin_lock_irqsave(&phba->hbalock, iflag);
 			break;
 		default:
 			if (irsp->ulpCommand == CMD_ADAPTER_MSG) {
@@ -1228,31 +1249,31 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
 
 	}
 
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
+	spin_unlock_irqrestore(&phba->hbalock, iflag);
 	return rc;
 }
 
 
 int
-lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
-			   struct lpfc_sli_ring * pring, uint32_t mask)
+lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba,
+				struct lpfc_sli_ring *pring, uint32_t mask)
 {
+	struct lpfc_pgp  *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
 	IOCB_t *entry;
 	IOCB_t *irsp = NULL;
 	struct lpfc_iocbq *rspiocbp = NULL;
 	struct lpfc_iocbq *next_iocb;
 	struct lpfc_iocbq *cmdiocbp;
 	struct lpfc_iocbq *saveq;
-	struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
 	uint8_t iocb_cmd_type;
 	lpfc_iocb_type type;
 	uint32_t status, free_saveq;
 	uint32_t portRspPut, portRspMax;
 	int rc = 1;
 	unsigned long iflag;
-	void __iomem  *to_slim;
+	void __iomem *to_slim;
 
-	spin_lock_irqsave(phba->host->host_lock, iflag);
+	spin_lock_irqsave(&phba->hbalock, iflag);
 	pring->stats.iocb_event++;
 
 	/*
@@ -1274,8 +1295,8 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
 				phba->brd_no,
 				pring->ringno, portRspPut, portRspMax);
 
-		phba->hba_state = LPFC_HBA_ERROR;
-		spin_unlock_irqrestore(phba->host->host_lock, iflag);
+		phba->link_state = LPFC_HBA_ERROR;
+		spin_unlock_irqrestore(&phba->hbalock, iflag);
 
 		phba->work_hs = HS_FFER3;
 		lpfc_handle_eratt(phba);
@@ -1299,14 +1320,14 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
 		 * received.
 		 */
 		entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
-		rspiocbp = lpfc_sli_get_iocbq(phba);
+		rspiocbp = __lpfc_sli_get_iocbq(phba);
 		if (rspiocbp == NULL) {
 			printk(KERN_ERR "%s: out of buffers! Failing "
 			       "completion.\n", __FUNCTION__);
 			break;
 		}
 
-		lpfc_sli_pcimem_bcopy(entry, &rspiocbp->iocb, sizeof (IOCB_t));
+		lpfc_sli_pcimem_bcopy(entry, &rspiocbp->iocb, sizeof(IOCB_t));
 		irsp = &rspiocbp->iocb;
 
 		if (++pring->rspidx >= portRspMax)
@@ -1366,17 +1387,17 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
 			iocb_cmd_type = irsp->ulpCommand & CMD_IOCB_MASK;
 			type = lpfc_sli_iocb_cmd_type(iocb_cmd_type);
 			if (type == LPFC_SOL_IOCB) {
-				spin_unlock_irqrestore(phba->host->host_lock,
+				spin_unlock_irqrestore(&phba->hbalock,
 						       iflag);
 				rc = lpfc_sli_process_sol_iocb(phba, pring,
-					saveq);
-				spin_lock_irqsave(phba->host->host_lock, iflag);
+							       saveq);
+				spin_lock_irqsave(&phba->hbalock, iflag);
 			} else if (type == LPFC_UNSOL_IOCB) {
-				spin_unlock_irqrestore(phba->host->host_lock,
+				spin_unlock_irqrestore(&phba->hbalock,
 						       iflag);
 				rc = lpfc_sli_process_unsol_iocb(phba, pring,
-					saveq);
-				spin_lock_irqsave(phba->host->host_lock, iflag);
+								 saveq);
+				spin_lock_irqsave(&phba->hbalock, iflag);
 			} else if (type == LPFC_ABORT_IOCB) {
 				if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) &&
 				    ((cmdiocbp =
@@ -1386,15 +1407,15 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
 					   routine */
 					if (cmdiocbp->iocb_cmpl) {
 						spin_unlock_irqrestore(
-						       phba->host->host_lock,
+						       &phba->hbalock,
 						       iflag);
 						(cmdiocbp->iocb_cmpl) (phba,
 							     cmdiocbp, saveq);
 						spin_lock_irqsave(
-							  phba->host->host_lock,
+							  &phba->hbalock,
 							  iflag);
 					} else
-						lpfc_sli_release_iocbq(phba,
+						__lpfc_sli_release_iocbq(phba,
 								      cmdiocbp);
 				}
 			} else if (type == LPFC_UNKNOWN_IOCB) {
@@ -1425,17 +1446,13 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
 			}
 
 			if (free_saveq) {
-				if (!list_empty(&saveq->list)) {
-					list_for_each_entry_safe(rspiocbp,
-								 next_iocb,
-								 &saveq->list,
-								 list) {
-						list_del(&rspiocbp->list);
-						lpfc_sli_release_iocbq(phba,
-								     rspiocbp);
-					}
+				list_for_each_entry_safe(rspiocbp, next_iocb,
+							 &saveq->list, list) {
+					list_del(&rspiocbp->list);
+					__lpfc_sli_release_iocbq(phba,
+								 rspiocbp);
 				}
-				lpfc_sli_release_iocbq(phba, saveq);
+				__lpfc_sli_release_iocbq(phba, saveq);
 			}
 		}
 
@@ -1470,24 +1487,21 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
 
 	}
 
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
+	spin_unlock_irqrestore(&phba->hbalock, iflag);
 	return rc;
 }
 
-int
+void
 lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
 {
 	LIST_HEAD(completions);
 	struct lpfc_iocbq *iocb, *next_iocb;
 	IOCB_t *cmd = NULL;
-	int errcnt;
-
-	errcnt = 0;
 
 	/* Error everything on txq and txcmplq
 	 * First do the txq.
 	 */
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	list_splice_init(&pring->txq, &completions);
 	pring->txq_cnt = 0;
 
@@ -1495,26 +1509,25 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
 	list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list)
 		lpfc_sli_issue_abort_iotag(phba, pring, iocb);
 
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	while (!list_empty(&completions)) {
 		iocb = list_get_first(&completions, struct lpfc_iocbq, list);
 		cmd = &iocb->iocb;
 		list_del(&iocb->list);
 
-		if (iocb->iocb_cmpl) {
+		if (!iocb->iocb_cmpl)
+			lpfc_sli_release_iocbq(phba, iocb);
+		else {
 			cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
 			cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
 			(iocb->iocb_cmpl) (phba, iocb, iocb);
-		} else
-			lpfc_sli_release_iocbq(phba, iocb);
+		}
 	}
-
-	return errcnt;
 }
 
 int
-lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask)
+lpfc_sli_brdready(struct lpfc_hba *phba, uint32_t mask)
 {
 	uint32_t status;
 	int i = 0;
@@ -1541,7 +1554,8 @@ lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask)
 			msleep(2500);
 
 		if (i == 15) {
-			phba->hba_state = LPFC_STATE_UNKNOWN; /* Do post */
+				/* Do post */
+			phba->pport->port_state = LPFC_STATE_UNKNOWN;
 			lpfc_sli_brdrestart(phba);
 		}
 		/* Read the HBA Host Status Register */
@@ -1550,7 +1564,7 @@ lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask)
 
 	/* Check to see if any errors occurred during init */
 	if ((status & HS_FFERM) || (i >= 20)) {
-		phba->hba_state = LPFC_HBA_ERROR;
+		phba->link_state = LPFC_HBA_ERROR;
 		retval = 1;
 	}
 
@@ -1559,7 +1573,7 @@ lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask)
 
 #define BARRIER_TEST_PATTERN (0xdeadbeef)
 
-void lpfc_reset_barrier(struct lpfc_hba * phba)
+void lpfc_reset_barrier(struct lpfc_hba *phba)
 {
 	uint32_t __iomem *resp_buf;
 	uint32_t __iomem *mbox_buf;
@@ -1584,12 +1598,12 @@ void lpfc_reset_barrier(struct lpfc_hba * phba)
 	hc_copy = readl(phba->HCregaddr);
 	writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr);
 	readl(phba->HCregaddr); /* flush */
-	phba->fc_flag |= FC_IGNORE_ERATT;
+	phba->link_flag |= LS_IGNORE_ERATT;
 
 	if (readl(phba->HAregaddr) & HA_ERATT) {
 		/* Clear Chip error bit */
 		writel(HA_ERATT, phba->HAregaddr);
-		phba->stopped = 1;
+		phba->pport->stopped = 1;
 	}
 
 	mbox = 0;
@@ -1606,7 +1620,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba)
 
 	if (readl(resp_buf + 1) != ~(BARRIER_TEST_PATTERN)) {
 		if (phba->sli.sli_flag & LPFC_SLI2_ACTIVE ||
-		    phba->stopped)
+		    phba->pport->stopped)
 			goto restore_hc;
 		else
 			goto clear_errat;
@@ -1623,17 +1637,17 @@ clear_errat:
 
 	if (readl(phba->HAregaddr) & HA_ERATT) {
 		writel(HA_ERATT, phba->HAregaddr);
-		phba->stopped = 1;
+		phba->pport->stopped = 1;
 	}
 
 restore_hc:
-	phba->fc_flag &= ~FC_IGNORE_ERATT;
+	phba->link_flag &= ~LS_IGNORE_ERATT;
 	writel(hc_copy, phba->HCregaddr);
 	readl(phba->HCregaddr); /* flush */
 }
 
 int
-lpfc_sli_brdkill(struct lpfc_hba * phba)
+lpfc_sli_brdkill(struct lpfc_hba *phba)
 {
 	struct lpfc_sli *psli;
 	LPFC_MBOXQ_t *pmb;
@@ -1650,7 +1664,7 @@ lpfc_sli_brdkill(struct lpfc_hba * phba)
 		LOG_SLI,
 		"%d:0329 Kill HBA Data: x%x x%x\n",
 		phba->brd_no,
-		phba->hba_state,
+		phba->pport->port_state,
 		psli->sli_flag);
 
 	if ((pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
@@ -1658,13 +1672,13 @@ lpfc_sli_brdkill(struct lpfc_hba * phba)
 		return 1;
 
 	/* Disable the error attention */
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	status = readl(phba->HCregaddr);
 	status &= ~HC_ERINT_ENA;
 	writel(status, phba->HCregaddr);
 	readl(phba->HCregaddr); /* flush */
-	phba->fc_flag |= FC_IGNORE_ERATT;
-	spin_unlock_irq(phba->host->host_lock);
+	phba->link_flag |= LS_IGNORE_ERATT;
+	spin_unlock_irq(&phba->hbalock);
 
 	lpfc_kill_board(phba, pmb);
 	pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
@@ -1673,9 +1687,9 @@ lpfc_sli_brdkill(struct lpfc_hba * phba)
 	if (retval != MBX_SUCCESS) {
 		if (retval != MBX_BUSY)
 			mempool_free(pmb, phba->mbox_mem_pool);
-		spin_lock_irq(phba->host->host_lock);
-		phba->fc_flag &= ~FC_IGNORE_ERATT;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_lock_irq(&phba->hbalock);
+		phba->link_flag &= ~LS_IGNORE_ERATT;
+		spin_unlock_irq(&phba->hbalock);
 		return 1;
 	}
 
@@ -1698,22 +1712,22 @@ lpfc_sli_brdkill(struct lpfc_hba * phba)
 	del_timer_sync(&psli->mbox_tmo);
 	if (ha_copy & HA_ERATT) {
 		writel(HA_ERATT, phba->HAregaddr);
-		phba->stopped = 1;
+		phba->pport->stopped = 1;
 	}
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
-	phba->fc_flag &= ~FC_IGNORE_ERATT;
-	spin_unlock_irq(phba->host->host_lock);
+	phba->link_flag &= ~LS_IGNORE_ERATT;
+	spin_unlock_irq(&phba->hbalock);
 
 	psli->mbox_active = NULL;
 	lpfc_hba_down_post(phba);
-	phba->hba_state = LPFC_HBA_ERROR;
+	phba->link_state = LPFC_HBA_ERROR;
 
-	return (ha_copy & HA_ERATT ? 0 : 1);
+	return ha_copy & HA_ERATT ? 0 : 1;
 }
 
 int
-lpfc_sli_brdreset(struct lpfc_hba * phba)
+lpfc_sli_brdreset(struct lpfc_hba *phba)
 {
 	struct lpfc_sli *psli;
 	struct lpfc_sli_ring *pring;
@@ -1725,12 +1739,12 @@ lpfc_sli_brdreset(struct lpfc_hba * phba)
 	/* Reset HBA */
 	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
 			"%d:0325 Reset HBA Data: x%x x%x\n", phba->brd_no,
-			phba->hba_state, psli->sli_flag);
+			phba->pport->port_state, psli->sli_flag);
 
 	/* perform board reset */
 	phba->fc_eventTag = 0;
-	phba->fc_myDID = 0;
-	phba->fc_prevDID = 0;
+	phba->pport->fc_myDID = 0;
+	phba->pport->fc_prevDID = 0;
 
 	/* Turn off parity checking and serr during the physical reset */
 	pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value);
@@ -1760,12 +1774,12 @@ lpfc_sli_brdreset(struct lpfc_hba * phba)
 		pring->missbufcnt = 0;
 	}
 
-	phba->hba_state = LPFC_WARM_START;
+	phba->link_state = LPFC_WARM_START;
 	return 0;
 }
 
 int
-lpfc_sli_brdrestart(struct lpfc_hba * phba)
+lpfc_sli_brdrestart(struct lpfc_hba *phba)
 {
 	MAILBOX_t *mb;
 	struct lpfc_sli *psli;
@@ -1773,14 +1787,14 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba)
 	volatile uint32_t word0;
 	void __iomem *to_slim;
 
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 
 	psli = &phba->sli;
 
 	/* Restart HBA */
 	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
 			"%d:0337 Restart HBA Data: x%x x%x\n", phba->brd_no,
-			phba->hba_state, psli->sli_flag);
+			phba->pport->port_state, psli->sli_flag);
 
 	word0 = 0;
 	mb = (MAILBOX_t *) &word0;
@@ -1794,7 +1808,7 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba)
 	readl(to_slim); /* flush */
 
 	/* Only skip post after fc_ffinit is completed */
-	if (phba->hba_state) {
+	if (phba->pport->port_state) {
 		skip_post = 1;
 		word0 = 1;	/* This is really setting up word1 */
 	} else {
@@ -1806,10 +1820,10 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba)
 	readl(to_slim); /* flush */
 
 	lpfc_sli_brdreset(phba);
-	phba->stopped = 0;
-	phba->hba_state = LPFC_INIT_START;
+	phba->pport->stopped = 0;
+	phba->link_state = LPFC_INIT_START;
 
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	memset(&psli->lnk_stat_offsets, 0, sizeof(psli->lnk_stat_offsets));
 	psli->stats_start = get_seconds();
@@ -1850,7 +1864,7 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
 					"timeout, status reg x%x\n",
 					phba->brd_no,
 					status);
-			phba->hba_state = LPFC_HBA_ERROR;
+			phba->link_state = LPFC_HBA_ERROR;
 			return -ETIMEDOUT;
 		}
 
@@ -1866,7 +1880,7 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
 					"chipset, status reg x%x\n",
 					phba->brd_no,
 					status);
-			phba->hba_state = LPFC_HBA_ERROR;
+			phba->link_state = LPFC_HBA_ERROR;
 			return -EIO;
 		}
 
@@ -1879,7 +1893,8 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
 		}
 
 		if (i == 15) {
-			phba->hba_state = LPFC_STATE_UNKNOWN; /* Do post */
+				/* Do post */
+			phba->pport->port_state = LPFC_STATE_UNKNOWN;
 			lpfc_sli_brdrestart(phba);
 		}
 		/* Read the HBA Host Status Register */
@@ -1897,7 +1912,7 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
 				"status reg x%x\n",
 				phba->brd_no,
 				status);
-		phba->hba_state = LPFC_HBA_ERROR;
+		phba->link_state = LPFC_HBA_ERROR;
 		return -EIO;
 	}
 
@@ -1912,31 +1927,31 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
 }
 
 int
-lpfc_sli_hba_setup(struct lpfc_hba * phba)
+lpfc_sli_hba_setup(struct lpfc_hba *phba)
 {
 	LPFC_MBOXQ_t *pmb;
 	uint32_t resetcount = 0, rc = 0, done = 0;
 
 	pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!pmb) {
-		phba->hba_state = LPFC_HBA_ERROR;
+		phba->link_state = LPFC_HBA_ERROR;
 		return -ENOMEM;
 	}
 
 	while (resetcount < 2 && !done) {
-		spin_lock_irq(phba->host->host_lock);
+		spin_lock_irq(&phba->hbalock);
 		phba->sli.sli_flag |= LPFC_SLI_MBOX_ACTIVE;
-		spin_unlock_irq(phba->host->host_lock);
-		phba->hba_state = LPFC_STATE_UNKNOWN;
+		spin_unlock_irq(&phba->hbalock);
+		phba->pport->port_state = LPFC_STATE_UNKNOWN;
 		lpfc_sli_brdrestart(phba);
 		msleep(2500);
 		rc = lpfc_sli_chipset_init(phba);
 		if (rc)
 			break;
 
-		spin_lock_irq(phba->host->host_lock);
+		spin_lock_irq(&phba->hbalock);
 		phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(&phba->hbalock);
 		resetcount++;
 
 	/* Call pre CONFIG_PORT mailbox command initialization.  A value of 0
@@ -1946,13 +1961,13 @@ lpfc_sli_hba_setup(struct lpfc_hba * phba)
 	 */
 		rc = lpfc_config_port_prep(phba);
 		if (rc == -ERESTART) {
-			phba->hba_state = 0;
+			phba->pport->port_state = 0;
 			continue;
 		} else if (rc) {
 			break;
 		}
 
-		phba->hba_state = LPFC_INIT_MBX_CMDS;
+		phba->link_state = LPFC_INIT_MBX_CMDS;
 		lpfc_config_port(phba, pmb);
 		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
 		if (rc == MBX_SUCCESS)
@@ -1963,7 +1978,10 @@ lpfc_sli_hba_setup(struct lpfc_hba * phba)
 				"CONFIG_PORT, mbxStatus x%x Data: x%x\n",
 				phba->brd_no, pmb->mb.mbxCommand,
 				pmb->mb.mbxStatus, 0);
+			spin_lock_irq(&phba->hbalock);
 			phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE;
+			spin_unlock_irq(&phba->hbalock);
+			rc = -ENXIO;
 		}
 	}
 	if (!done)
@@ -1982,7 +2000,7 @@ lpfc_sli_hba_setup(struct lpfc_hba * phba)
 
 	goto lpfc_sli_hba_setup_exit;
 lpfc_sli_hba_setup_error:
-	phba->hba_state = LPFC_HBA_ERROR;
+	phba->link_state = LPFC_HBA_ERROR;
 lpfc_sli_hba_setup_exit:
 	mempool_free(pmb, phba->mbox_mem_pool);
 	return rc;
@@ -2004,36 +2022,34 @@ lpfc_sli_hba_setup_exit:
 void
 lpfc_mbox_timeout(unsigned long ptr)
 {
-	struct lpfc_hba *phba;
+	struct lpfc_hba  *phba = (struct lpfc_hba *) phba;
 	unsigned long iflag;
+	uint32_t tmo_posted;
 
-	phba = (struct lpfc_hba *)ptr;
-	spin_lock_irqsave(phba->host->host_lock, iflag);
-	if (!(phba->work_hba_events & WORKER_MBOX_TMO)) {
-		phba->work_hba_events |= WORKER_MBOX_TMO;
+	spin_lock_irqsave(&phba->pport->work_port_lock, iflag);
+	tmo_posted = (phba->pport->work_port_events & WORKER_MBOX_TMO) == 0;
+	if (!tmo_posted)
+		phba->pport->work_port_events |= WORKER_MBOX_TMO;
+	spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag);
+
+	if (!tmo_posted) {
 		if (phba->work_wait)
 			wake_up(phba->work_wait);
 	}
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
 }
 
 void
 lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
 {
-	LPFC_MBOXQ_t *pmbox;
-	MAILBOX_t *mb;
+	LPFC_MBOXQ_t *pmbox = phba->sli.mbox_active;
+	MAILBOX_t *mb = &pmbox->mb;
 	struct lpfc_sli *psli = &phba->sli;
 	struct lpfc_sli_ring *pring;
 
-	spin_lock_irq(phba->host->host_lock);
-	if (!(phba->work_hba_events & WORKER_MBOX_TMO)) {
-		spin_unlock_irq(phba->host->host_lock);
+	if (!(phba->pport->work_port_events & WORKER_MBOX_TMO)) {
 		return;
 	}
 
-	pmbox = phba->sli.mbox_active;
-	mb = &pmbox->mb;
-
 	/* Mbox cmd <mbxCommand> timeout */
 	lpfc_printf_log(phba,
 		KERN_ERR,
@@ -2041,7 +2057,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
 		"%d:0310 Mailbox command x%x timeout Data: x%x x%x x%p\n",
 		phba->brd_no,
 		mb->mbxCommand,
-		phba->hba_state,
+		phba->pport->port_state,
 		phba->sli.sli_flag,
 		phba->sli.mbox_active);
 
@@ -2049,11 +2065,14 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
 	 * would get IOCB_ERROR from lpfc_sli_issue_iocb, allowing
 	 * it to fail all oustanding SCSI IO.
 	 */
-	phba->hba_state = LPFC_STATE_UNKNOWN;
-	phba->work_hba_events &= ~WORKER_MBOX_TMO;
-	phba->fc_flag |= FC_ESTABLISH_LINK;
+	spin_lock_irq(&phba->pport->work_port_lock);
+	phba->pport->work_port_events &= ~WORKER_MBOX_TMO;
+	spin_unlock_irq(&phba->pport->work_port_lock);
+	spin_lock_irq(&phba->hbalock);
+	phba->link_state = LPFC_LINK_UNKNOWN;
+	phba->pport->fc_flag |= FC_ESTABLISH_LINK;
 	psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	pring = &psli->ring[psli->fcp_ring];
 	lpfc_sli_abort_iocb_ring(phba, pring);
@@ -2075,10 +2094,10 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
 }
 
 int
-lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
+lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
 {
 	MAILBOX_t *mb;
-	struct lpfc_sli *psli;
+	struct lpfc_sli *psli = &phba->sli;
 	uint32_t status, evtctr;
 	uint32_t ha_copy;
 	int i;
@@ -2090,27 +2109,25 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
 	if (unlikely(pci_channel_offline(phba->pcidev)))
 		return MBX_NOT_FINISHED;
 
+	spin_lock_irqsave(&phba->hbalock, drvr_flag);
 	psli = &phba->sli;
 
-	spin_lock_irqsave(phba->host->host_lock, drvr_flag);
-
-
 	mb = &pmbox->mb;
 	status = MBX_SUCCESS;
 
-	if (phba->hba_state == LPFC_HBA_ERROR) {
-		spin_unlock_irqrestore(phba->host->host_lock, drvr_flag);
+	if (phba->link_state == LPFC_HBA_ERROR) {
+		spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 
 		/* Mbox command <mbxCommand> cannot issue */
 		LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag)
-		return (MBX_NOT_FINISHED);
+		return MBX_NOT_FINISHED;
 	}
 
 	if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT &&
 	    !(readl(phba->HCregaddr) & HC_MBINT_ENA)) {
-		spin_unlock_irqrestore(phba->host->host_lock, drvr_flag);
+		spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 		LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag)
-		return (MBX_NOT_FINISHED);
+		return MBX_NOT_FINISHED;
 	}
 
 	if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) {
@@ -2120,20 +2137,18 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
 		 */
 
 		if (flag & MBX_POLL) {
-			spin_unlock_irqrestore(phba->host->host_lock,
-					       drvr_flag);
+			spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 
 			/* Mbox command <mbxCommand> cannot issue */
-			LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag)
-			return (MBX_NOT_FINISHED);
+			LOG_MBOX_CANNOT_ISSUE_DATA(phba, mb, psli, flag);
+			return MBX_NOT_FINISHED;
 		}
 
 		if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) {
-			spin_unlock_irqrestore(phba->host->host_lock,
-					       drvr_flag);
+			spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 			/* Mbox command <mbxCommand> cannot issue */
-			LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag)
-			return (MBX_NOT_FINISHED);
+			LOG_MBOX_CANNOT_ISSUE_DATA(phba, mb, psli, flag);
+			return MBX_NOT_FINISHED;
 		}
 
 		/* Handle STOP IOCB processing flag. This is only meaningful
@@ -2163,15 +2178,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
 			"%d:0308 Mbox cmd issue - BUSY Data: x%x x%x x%x x%x\n",
 			phba->brd_no,
 			mb->mbxCommand,
-			phba->hba_state,
+			phba->pport->port_state,
 			psli->sli_flag,
 			flag);
 
 		psli->slistat.mbox_busy++;
-		spin_unlock_irqrestore(phba->host->host_lock,
-				       drvr_flag);
+		spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 
-		return (MBX_BUSY);
+		return MBX_BUSY;
 	}
 
 	/* Handle STOP IOCB processing flag. This is only meaningful
@@ -2198,11 +2212,10 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
 		if (!(psli->sli_flag & LPFC_SLI2_ACTIVE) &&
 		    (mb->mbxCommand != MBX_KILL_BOARD)) {
 			psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
-			spin_unlock_irqrestore(phba->host->host_lock,
-					       drvr_flag);
+			spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 			/* Mbox command <mbxCommand> cannot issue */
 			LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag);
-			return (MBX_NOT_FINISHED);
+			return MBX_NOT_FINISHED;
 		}
 		/* timeout active mbox command */
 		mod_timer(&psli->mbox_tmo, (jiffies +
@@ -2216,9 +2229,9 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
 		"%d:0309 Mailbox cmd x%x issue Data: x%x x%x x%x\n",
 		phba->brd_no,
 		mb->mbxCommand,
-		phba->hba_state,
+		phba->pport->port_state,
 		psli->sli_flag,
-		flag);
+			flag);
 
 	psli->slistat.mbox_cmd++;
 	evtctr = psli->slistat.mbox_event;
@@ -2285,12 +2298,12 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
 		/* Wait for command to complete */
 		while (((word0 & OWN_CHIP) == OWN_CHIP) ||
 		       (!(ha_copy & HA_MBATT) &&
-			(phba->hba_state > LPFC_WARM_START))) {
+			(phba->link_state > LPFC_WARM_START))) {
 			if (i-- <= 0) {
 				psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
-				spin_unlock_irqrestore(phba->host->host_lock,
+				spin_unlock_irqrestore(&phba->hbalock,
 						       drvr_flag);
-				return (MBX_NOT_FINISHED);
+				return MBX_NOT_FINISHED;
 			}
 
 			/* Check if we took a mbox interrupt while we were
@@ -2299,12 +2312,12 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
 			    && (evtctr != psli->slistat.mbox_event))
 				break;
 
-			spin_unlock_irqrestore(phba->host->host_lock,
+			spin_unlock_irqrestore(&phba->hbalock,
 					       drvr_flag);
 
 			msleep(1);
 
-			spin_lock_irqsave(phba->host->host_lock, drvr_flag);
+			spin_lock_irqsave(&phba->hbalock, drvr_flag);
 
 			if (psli->sli_flag & LPFC_SLI2_ACTIVE) {
 				/* First copy command data */
@@ -2342,7 +2355,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
 							MAILBOX_CMD_SIZE);
 			if ((mb->mbxCommand == MBX_DUMP_MEMORY) &&
 				pmbox->context2) {
-				lpfc_memcpy_from_slim((void *)pmbox->context2,
+				lpfc_memcpy_from_slim((void *) pmbox->context2,
 				      phba->MBslimaddr + DMP_RSP_OFFSET,
 						      mb->un.varDmp.word_cnt);
 			}
@@ -2355,23 +2368,27 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
 		status = mb->mbxStatus;
 	}
 
-	spin_unlock_irqrestore(phba->host->host_lock, drvr_flag);
-	return (status);
+	spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
+	return status;
 }
 
 static int
-lpfc_sli_ringtx_put(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
-		    struct lpfc_iocbq * piocb)
+lpfc_sli_ringtx_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+		    struct lpfc_iocbq *piocb)
 {
+	unsigned long iflags;
+
 	/* Insert the caller's iocb in the txq tail for later processing. */
+	spin_lock_irqsave(&phba->hbalock, iflags);
 	list_add_tail(&piocb->list, &pring->txq);
 	pring->txq_cnt++;
-	return (0);
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
+	return 0;
 }
 
 static struct lpfc_iocbq *
 lpfc_sli_next_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
-		   struct lpfc_iocbq ** piocb)
+		   struct lpfc_iocbq **piocb)
 {
 	struct lpfc_iocbq * nextiocb;
 
@@ -2389,6 +2406,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 		    struct lpfc_iocbq *piocb, uint32_t flag)
 {
 	struct lpfc_iocbq *nextiocb;
+	unsigned long iflags;
 	IOCB_t *iocb;
 
 	/* If the PCI channel is in offline state, do not post iocbs. */
@@ -2398,7 +2416,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 	/*
 	 * We should never get an IOCB if we are in a < LINK_DOWN state
 	 */
-	if (unlikely(phba->hba_state < LPFC_LINK_DOWN))
+	if (unlikely(phba->link_state < LPFC_LINK_DOWN))
 		return IOCB_ERROR;
 
 	/*
@@ -2408,7 +2426,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 	if (unlikely(pring->flag & LPFC_STOP_IOCB_MBX))
 		goto iocb_busy;
 
-	if (unlikely(phba->hba_state == LPFC_LINK_DOWN)) {
+	if (unlikely(phba->link_state == LPFC_LINK_DOWN)) {
 		/*
 		 * Only CREATE_XRI, CLOSE_XRI, and QUE_RING_BUF
 		 * can be issued if the link is not up.
@@ -2439,6 +2457,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 		   !(phba->sli.sli_flag & LPFC_PROCESS_LA)))
 		goto iocb_busy;
 
+	spin_lock_irqsave(&phba->hbalock, iflags);
 	while ((iocb = lpfc_sli_next_iocb_slot(phba, pring)) &&
 	       (nextiocb = lpfc_sli_next_iocb(phba, pring, &piocb)))
 		lpfc_sli_submit_iocb(phba, pring, iocb, nextiocb);
@@ -2447,6 +2466,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 		lpfc_sli_update_ring(phba, pring);
 	else
 		lpfc_sli_update_full_ring(phba, pring);
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
 
 	if (!piocb)
 		return IOCB_SUCCESS;
@@ -2454,7 +2474,9 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 	goto out_busy;
 
  iocb_busy:
+	spin_lock_irqsave(&phba->hbalock, iflags);
 	pring->stats.iocb_cmd_delay++;
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
 
  out_busy:
 
@@ -2539,6 +2561,7 @@ lpfc_sli_setup(struct lpfc_hba *phba)
 			/* numCiocb and numRiocb are used in config_port */
 			pring->numCiocb = SLI2_IOCB_CMD_R1_ENTRIES;
 			pring->numRiocb = SLI2_IOCB_RSP_R1_ENTRIES;
+			pring->iotag_max = phba->cfg_hba_queue_depth;
 			pring->num_mask = 0;
 			break;
 		case LPFC_ELS_RING:	/* ring 2 - ELS / CT */
@@ -2591,14 +2614,14 @@ lpfc_sli_setup(struct lpfc_hba *phba)
 }
 
 int
-lpfc_sli_queue_setup(struct lpfc_hba * phba)
+lpfc_sli_queue_setup(struct lpfc_hba *phba)
 {
 	struct lpfc_sli *psli;
 	struct lpfc_sli_ring *pring;
 	int i;
 
 	psli = &phba->sli;
-	spin_lock_irq(phba->host->host_lock);
+	spin_lock_irq(&phba->hbalock);
 	INIT_LIST_HEAD(&psli->mboxq);
 	/* Initialize list headers for txq and txcmplq as double linked lists */
 	for (i = 0; i < psli->num_rings; i++) {
@@ -2612,15 +2635,15 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba)
 		INIT_LIST_HEAD(&pring->iocb_continueq);
 		INIT_LIST_HEAD(&pring->postbufq);
 	}
-	spin_unlock_irq(phba->host->host_lock);
-	return (1);
+	spin_unlock_irq(&phba->hbalock);
+	return 1;
 }
 
 int
-lpfc_sli_hba_down(struct lpfc_hba * phba)
+lpfc_sli_hba_down(struct lpfc_hba *phba)
 {
 	LIST_HEAD(completions);
-	struct lpfc_sli *psli;
+	struct lpfc_sli *psli = &phba->sli;
 	struct lpfc_sli_ring *pring;
 	LPFC_MBOXQ_t *pmb;
 	struct lpfc_iocbq *iocb;
@@ -2628,10 +2651,9 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
 	int i;
 	unsigned long flags = 0;
 
-	psli = &phba->sli;
 	lpfc_hba_down_prep(phba);
 
-	spin_lock_irqsave(phba->host->host_lock, flags);
+	spin_lock_irqsave(&phba->hbalock, flags);
 	for (i = 0; i < psli->num_rings; i++) {
 		pring = &psli->ring[i];
 		pring->flag |= LPFC_DEFERRED_RING_EVENT;
@@ -2644,51 +2666,48 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
 		pring->txq_cnt = 0;
 
 	}
-	spin_unlock_irqrestore(phba->host->host_lock, flags);
+	spin_unlock_irqrestore(&phba->hbalock, flags);
 
 	while (!list_empty(&completions)) {
 		iocb = list_get_first(&completions, struct lpfc_iocbq, list);
 		cmd = &iocb->iocb;
 		list_del(&iocb->list);
 
-		if (iocb->iocb_cmpl) {
+		if (!iocb->iocb_cmpl)
+			lpfc_sli_release_iocbq(phba, iocb);
+		else {
 			cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
 			cmd->un.ulpWord[4] = IOERR_SLI_DOWN;
 			(iocb->iocb_cmpl) (phba, iocb, iocb);
-		} else
-			lpfc_sli_release_iocbq(phba, iocb);
+		}
 	}
 
 	/* Return any active mbox cmds */
 	del_timer_sync(&psli->mbox_tmo);
-	spin_lock_irqsave(phba->host->host_lock, flags);
-	phba->work_hba_events &= ~WORKER_MBOX_TMO;
-	if (psli->mbox_active) {
-		pmb = psli->mbox_active;
+
+	spin_lock_irqsave(&phba->pport->work_port_lock, flags);
+	phba->pport->work_port_events &= ~WORKER_MBOX_TMO;
+	spin_unlock_irqrestore(&phba->pport->work_port_lock, flags);
+
+	pmb = psli->mbox_active;
+	if (pmb) {
+		psli->mbox_active = NULL;
 		pmb->mb.mbxStatus = MBX_NOT_FINISHED;
+		psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
 		if (pmb->mbox_cmpl) {
-			spin_unlock_irqrestore(phba->host->host_lock, flags);
 			pmb->mbox_cmpl(phba,pmb);
-			spin_lock_irqsave(phba->host->host_lock, flags);
 		}
 	}
-	psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
-	psli->mbox_active = NULL;
 
 	/* Return any pending mbox cmds */
 	while ((pmb = lpfc_mbox_get(phba)) != NULL) {
 		pmb->mb.mbxStatus = MBX_NOT_FINISHED;
 		if (pmb->mbox_cmpl) {
-			spin_unlock_irqrestore(phba->host->host_lock, flags);
 			pmb->mbox_cmpl(phba,pmb);
-			spin_lock_irqsave(phba->host->host_lock, flags);
 		}
 	}
-
 	INIT_LIST_HEAD(&psli->mboxq);
 
-	spin_unlock_irqrestore(phba->host->host_lock, flags);
-
 	return 1;
 }
 
@@ -2710,14 +2729,15 @@ lpfc_sli_pcimem_bcopy(void *srcp, void *destp, uint32_t cnt)
 }
 
 int
-lpfc_sli_ringpostbuf_put(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
-			 struct lpfc_dmabuf * mp)
+lpfc_sli_ringpostbuf_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+			 struct lpfc_dmabuf *mp)
 {
 	/* Stick struct lpfc_dmabuf at end of postbufq so driver can look it up
 	   later */
+	spin_lock_irq(&phba->hbalock);
 	list_add_tail(&mp->list, &pring->postbufq);
-
 	pring->postbufq_cnt++;
+	spin_unlock_irq(&phba->hbalock);
 	return 0;
 }
 
@@ -2730,40 +2750,41 @@ lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 	struct list_head *slp = &pring->postbufq;
 
 	/* Search postbufq, from the begining, looking for a match on phys */
+	spin_lock_irq(&phba->hbalock);
 	list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) {
 		if (mp->phys == phys) {
 			list_del_init(&mp->list);
 			pring->postbufq_cnt--;
+			spin_unlock_irq(&phba->hbalock);
 			return mp;
 		}
 	}
 
+	spin_unlock_irq(&phba->hbalock);
 	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 			"%d:0410 Cannot find virtual addr for mapped buf on "
 			"ring %d Data x%llx x%p x%p x%x\n",
-			phba->brd_no, pring->ringno, (unsigned long long)phys,
+			phba->brd_no, pring->ringno, (unsigned long long) phys,
 			slp->next, slp->prev, pring->postbufq_cnt);
 	return NULL;
 }
 
 static void
-lpfc_sli_abort_els_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-			struct lpfc_iocbq * rspiocb)
+lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+			struct lpfc_iocbq *rspiocb)
 {
-	IOCB_t *irsp;
+	IOCB_t *irsp = &rspiocb->iocb;
 	uint16_t abort_iotag, abort_context;
 	struct lpfc_iocbq *abort_iocb, *rsp_ab_iocb;
 	struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
 
 	abort_iocb = NULL;
-	irsp = &rspiocb->iocb;
-
-	spin_lock_irq(phba->host->host_lock);
 
 	if (irsp->ulpStatus) {
 		abort_context = cmdiocb->iocb.un.acxri.abortContextTag;
 		abort_iotag = cmdiocb->iocb.un.acxri.abortIoTag;
 
+		spin_lock_irq(&phba->hbalock);
 		if (abort_iotag != 0 && abort_iotag <= phba->sli.last_iotag)
 			abort_iocb = phba->sli.iocbq_lookup[abort_iotag];
 
@@ -2777,41 +2798,40 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 		 * make sure we have the right iocbq before taking it
 		 * off the txcmplq and try to call completion routine.
 		 */
-		if (abort_iocb &&
-		    abort_iocb->iocb.ulpContext == abort_context &&
-		    abort_iocb->iocb_flag & LPFC_DRIVER_ABORTED) {
+		if (!abort_iocb ||
+		    abort_iocb->iocb.ulpContext != abort_context ||
+		    (abort_iocb->iocb_flag & LPFC_DRIVER_ABORTED) == 0)
+			spin_unlock_irq(&phba->hbalock);
+		else {
 			list_del(&abort_iocb->list);
 			pring->txcmplq_cnt--;
+			spin_unlock_irq(&phba->hbalock);
 
 			rsp_ab_iocb = lpfc_sli_get_iocbq(phba);
 			if (rsp_ab_iocb == NULL)
 				lpfc_sli_release_iocbq(phba, abort_iocb);
 			else {
-				abort_iocb->iocb_flag &=
-					~LPFC_DRIVER_ABORTED;
+				abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED;
 				rsp_ab_iocb->iocb.ulpStatus =
 					IOSTAT_LOCAL_REJECT;
 				rsp_ab_iocb->iocb.un.ulpWord[4] =
 					IOERR_SLI_ABORTED;
-				spin_unlock_irq(phba->host->host_lock);
-				(abort_iocb->iocb_cmpl)
-					(phba, abort_iocb, rsp_ab_iocb);
-				spin_lock_irq(phba->host->host_lock);
+				(abort_iocb->iocb_cmpl)(phba, abort_iocb,
+							rsp_ab_iocb);
 				lpfc_sli_release_iocbq(phba, rsp_ab_iocb);
 			}
 		}
 	}
 
 	lpfc_sli_release_iocbq(phba, cmdiocb);
-	spin_unlock_irq(phba->host->host_lock);
 	return;
 }
 
 int
-lpfc_sli_issue_abort_iotag(struct lpfc_hba * phba,
-			   struct lpfc_sli_ring * pring,
-			   struct lpfc_iocbq * cmdiocb)
+lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+			   struct lpfc_iocbq *cmdiocb)
 {
+	struct lpfc_vport *vport = cmdiocb->vport;
 	struct lpfc_iocbq *abtsiocbp;
 	IOCB_t *icmd = NULL;
 	IOCB_t *iabt = NULL;
@@ -2821,14 +2841,14 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba * phba,
 	 * to abort.
 	 */
 	icmd = &cmdiocb->iocb;
-	if ((icmd->ulpCommand == CMD_ABORT_XRI_CN) ||
-	    (icmd->ulpCommand == CMD_CLOSE_XRI_CN))
+	if (icmd->ulpCommand == CMD_ABORT_XRI_CN ||
+	    icmd->ulpCommand == CMD_CLOSE_XRI_CN)
 		return 0;
 
 	/* If we're unloading, interrupts are disabled so we
 	 * need to cleanup the iocb here.
 	 */
-	if (phba->fc_flag & FC_UNLOADING)
+	if (vport->load_flag & FC_UNLOADING)
 		goto abort_iotag_exit;
 
 	/* issue ABTS for this IOCB based on iotag */
@@ -2848,7 +2868,7 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba * phba,
 	iabt->ulpLe = 1;
 	iabt->ulpClass = icmd->ulpClass;
 
-	if (phba->hba_state >= LPFC_LINK_UP)
+	if (phba->link_state >= LPFC_LINK_UP)
 		iabt->ulpCommand = CMD_ABORT_XRI_CN;
 	else
 		iabt->ulpCommand = CMD_CLOSE_XRI_CN;
@@ -2863,25 +2883,12 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba * phba,
 	retval = lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0);
 
 abort_iotag_exit:
-
-	/* If we could not issue an abort dequeue the iocb and handle
-	 * the completion here.
+	/*
+	 * Caller to this routine should check for IOCB_ERROR
+	 * and handle it properly.  This routine no longer removes
+	 * iocb off txcmplq and call compl in case of IOCB_ERROR.
 	 */
-	if (retval == IOCB_ERROR) {
-		list_del(&cmdiocb->list);
-		pring->txcmplq_cnt--;
-
-		if (cmdiocb->iocb_cmpl) {
-			icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
-			icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
-			spin_unlock_irq(phba->host->host_lock);
-			(cmdiocb->iocb_cmpl) (phba, cmdiocb, cmdiocb);
-			spin_lock_irq(phba->host->host_lock);
-		} else
-			lpfc_sli_release_iocbq(phba, cmdiocb);
-	}
-
-	return 1;
+	return retval;
 }
 
 static int
@@ -2930,7 +2937,7 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, uint16_t tgt_id,
 
 int
 lpfc_sli_sum_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
-		uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd ctx_cmd)
+		  uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd ctx_cmd)
 {
 	struct lpfc_iocbq *iocbq;
 	int sum, i;
@@ -2947,14 +2954,10 @@ lpfc_sli_sum_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 }
 
 void
-lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
-			   struct lpfc_iocbq * rspiocb)
+lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+			struct lpfc_iocbq *rspiocb)
 {
-	unsigned long iflags;
-
-	spin_lock_irqsave(phba->host->host_lock, iflags);
 	lpfc_sli_release_iocbq(phba, cmdiocb);
-	spin_unlock_irqrestore(phba->host->host_lock, iflags);
 	return;
 }
 
@@ -2972,8 +2975,8 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 	for (i = 1; i <= phba->sli.last_iotag; i++) {
 		iocbq = phba->sli.iocbq_lookup[i];
 
-		if (lpfc_sli_validate_fcp_iocb (iocbq, tgt_id, lun_id,
-						0, abort_cmd) != 0)
+		if (lpfc_sli_validate_fcp_iocb(iocbq, tgt_id, lun_id, 0,
+					       abort_cmd) != 0)
 			continue;
 
 		/* issue ABTS for this IOCB based on iotag */
@@ -2989,8 +2992,9 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 		abtsiocb->iocb.un.acxri.abortIoTag = cmd->ulpIoTag;
 		abtsiocb->iocb.ulpLe = 1;
 		abtsiocb->iocb.ulpClass = cmd->ulpClass;
+		abtsiocb->vport = phba->pport;
 
-		if (phba->hba_state >= LPFC_LINK_UP)
+		if (lpfc_is_link_up(phba))
 			abtsiocb->iocb.ulpCommand = CMD_ABORT_XRI_CN;
 		else
 			abtsiocb->iocb.ulpCommand = CMD_CLOSE_XRI_CN;
@@ -3016,14 +3020,14 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
 	wait_queue_head_t *pdone_q;
 	unsigned long iflags;
 
-	spin_lock_irqsave(phba->host->host_lock, iflags);
+	spin_lock_irqsave(&phba->hbalock, iflags);
 	cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
 	if (cmdiocbq->context2 && rspiocbq)
 		memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
 		       &rspiocbq->iocb, sizeof(IOCB_t));
 
 	pdone_q = cmdiocbq->context_un.wait_queue;
-	spin_unlock_irqrestore(phba->host->host_lock, iflags);
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
 	if (pdone_q)
 		wake_up(pdone_q);
 	return;
@@ -3036,10 +3040,10 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
  * definition this is a wait function.
  */
 int
-lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
-			 struct lpfc_sli_ring * pring,
-			 struct lpfc_iocbq * piocb,
-			 struct lpfc_iocbq * prspiocbq,
+lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba,
+			 struct lpfc_sli_ring *pring,
+			 struct lpfc_iocbq *piocb,
+			 struct lpfc_iocbq *prspiocbq,
 			 uint32_t timeout)
 {
 	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q);
@@ -3071,11 +3075,11 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
 	retval = lpfc_sli_issue_iocb(phba, pring, piocb, 0);
 	if (retval == IOCB_SUCCESS) {
 		timeout_req = timeout * HZ;
-		spin_unlock_irq(phba->host->host_lock);
+		spin_unlock_irq(&phba->hbalock);
 		timeleft = wait_event_timeout(done_q,
 				piocb->iocb_flag & LPFC_IO_WAKE,
 				timeout_req);
-		spin_lock_irq(phba->host->host_lock);
+		spin_lock_irq(&phba->hbalock);
 
 		if (piocb->iocb_flag & LPFC_IO_WAKE) {
 			lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
@@ -3117,7 +3121,7 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
 }
 
 int
-lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
+lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq,
 			 uint32_t timeout)
 {
 	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q);
@@ -3125,7 +3129,7 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
 
 	/* The caller must leave context1 empty. */
 	if (pmboxq->context1 != 0) {
-		return (MBX_NOT_FINISHED);
+		return MBX_NOT_FINISHED;
 	}
 
 	/* setup wake call as IOCB callback */
@@ -3158,9 +3162,10 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
 int
 lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba)
 {
+	struct lpfc_vport *vport = phba->pport;
 	int i = 0;
 
-	while (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE && !phba->stopped) {
+	while (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE && !vport->stopped) {
 		if (i++ > LPFC_MBOX_TMO * 1000)
 			return 1;
 
@@ -3176,7 +3181,7 @@ lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba)
 irqreturn_t
 lpfc_intr_handler(int irq, void *dev_id)
 {
-	struct lpfc_hba *phba;
+	struct lpfc_hba  *phba;
 	uint32_t ha_copy;
 	uint32_t work_ha_copy;
 	unsigned long status;
@@ -3204,7 +3209,7 @@ lpfc_intr_handler(int irq, void *dev_id)
 	 */
 
 	/* Ignore all interrupts during initialization. */
-	if (unlikely(phba->hba_state < LPFC_LINK_DOWN))
+	if (unlikely(phba->link_state < LPFC_LINK_DOWN))
 		return IRQ_NONE;
 
 	/*
@@ -3212,16 +3217,16 @@ lpfc_intr_handler(int irq, void *dev_id)
 	 * Clear Attention Sources, except Error Attention (to
 	 * preserve status) and Link Attention
 	 */
-	spin_lock(phba->host->host_lock);
+	spin_lock(&phba->hbalock);
 	ha_copy = readl(phba->HAregaddr);
 	/* If somebody is waiting to handle an eratt don't process it
 	 * here.  The brdkill function will do this.
 	 */
-	if (phba->fc_flag & FC_IGNORE_ERATT)
+	if (phba->link_flag & LS_IGNORE_ERATT)
 		ha_copy &= ~HA_ERATT;
 	writel((ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr);
 	readl(phba->HAregaddr); /* flush */
-	spin_unlock(phba->host->host_lock);
+	spin_unlock(&phba->hbalock);
 
 	if (unlikely(!ha_copy))
 		return IRQ_NONE;
@@ -3235,13 +3240,13 @@ lpfc_intr_handler(int irq, void *dev_id)
 				 * Turn off Link Attention interrupts
 				 * until CLEAR_LA done
 				 */
-				spin_lock(phba->host->host_lock);
+				spin_lock(&phba->hbalock);
 				phba->sli.sli_flag &= ~LPFC_PROCESS_LA;
 				control = readl(phba->HCregaddr);
 				control &= ~HC_LAINT_ENA;
 				writel(control, phba->HCregaddr);
 				readl(phba->HCregaddr); /* flush */
-				spin_unlock(phba->host->host_lock);
+				spin_unlock(&phba->hbalock);
 			}
 			else
 				work_ha_copy &= ~HA_LATT;
@@ -3253,18 +3258,18 @@ lpfc_intr_handler(int irq, void *dev_id)
 					/*
 					 * Turn off Slow Rings interrupts
 					 */
-					spin_lock(phba->host->host_lock);
+					spin_lock(&phba->hbalock);
 					control = readl(phba->HCregaddr);
 					control &= ~(HC_R0INT_ENA << i);
 					writel(control, phba->HCregaddr);
 					readl(phba->HCregaddr); /* flush */
-					spin_unlock(phba->host->host_lock);
+					spin_unlock(&phba->hbalock);
 				}
 			}
 		}
 
 		if (work_ha_copy & HA_ERATT) {
-			phba->hba_state = LPFC_HBA_ERROR;
+			phba->link_state = LPFC_HBA_ERROR;
 			/*
 			 * There was a link/board error.  Read the
 			 * status register to retrieve the error event
@@ -3279,14 +3284,14 @@ lpfc_intr_handler(int irq, void *dev_id)
 			/* Clear Chip error bit */
 			writel(HA_ERATT, phba->HAregaddr);
 			readl(phba->HAregaddr); /* flush */
-			phba->stopped = 1;
+			phba->pport->stopped = 1;
 		}
 
-		spin_lock(phba->host->host_lock);
+		spin_lock(&phba->hbalock);
 		phba->work_ha |= work_ha_copy;
 		if (phba->work_wait)
 			wake_up(phba->work_wait);
-		spin_unlock(phba->host->host_lock);
+		spin_unlock(&phba->hbalock);
 	}
 
 	ha_copy &= ~(phba->work_ha_mask);
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 41c38d324ab005ce43efd90f27d7be2fd93c5db2..0e857e51a2c47f3d94091156c803d597cfd4e696 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -20,6 +20,7 @@
 
 /* forward declaration for LPFC_IOCB_t's use */
 struct lpfc_hba;
+struct lpfc_vport;
 
 /* Define the context types that SLI handles for abort and sums. */
 typedef enum _lpfc_ctx_cmd {
@@ -47,6 +48,7 @@ struct lpfc_iocbq {
 	uint8_t abort_count;
 	uint8_t rsvd2;
 	uint32_t drvrTimeout;	/* driver timeout in seconds */
+	struct lpfc_vport *vport;/* virtual port pointer */
 	void *context1;		/* caller context information */
 	void *context2;		/* caller context information */
 	void *context3;		/* caller context information */
@@ -74,6 +76,7 @@ typedef struct lpfcMboxq {
 	/* MBOXQs are used in single linked lists */
 	struct list_head list;	/* ptr to next mailbox command */
 	MAILBOX_t mb;		/* Mailbox cmd */
+	struct lpfc_vport *vport;/* virutal port pointer */
 	void *context1;		/* caller context information */
 	void *context2;		/* caller context information */
 
@@ -197,6 +200,7 @@ struct lpfc_sli {
 #define LPFC_SLI_MBOX_ACTIVE      0x100	/* HBA mailbox is currently active */
 #define LPFC_SLI2_ACTIVE          0x200	/* SLI2 overlay in firmware is active */
 #define LPFC_PROCESS_LA           0x400	/* Able to process link attention */
+#define LPFC_BLOCK_MGMT_IO        0x800	/* Don't allow mgmt mbx or iocb cmds */
 
 	struct lpfc_sli_ring ring[LPFC_MAX_RING];
 	int fcp_ring;		/* ring used for FCP initiator commands */
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 92a9107019d2c6de3b87a5ec7c899df256d6c063..0a7937351448d5b04c4624877e5e994fb45efccb 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.1.12"
+#define LPFC_DRIVER_VERSION "8.1.12_psplit"
 
 #define LPFC_DRIVER_NAME "lpfc"