[SCSI] lpfc: NPIV: split ports

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

Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 95fe77e..b8adff8 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -76,55 +76,68 @@
 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 @@
 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 @@
 						"   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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 	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_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 @@
 
 	phba->cfg_poll = val;
 
-	spin_unlock_irq(phba->host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	return strlen(buf);
 }
@@ -459,8 +504,9 @@
 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 @@
 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 @@
 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(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 @@
 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 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 @@
 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 @@
 		}
 	}
 	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 @@
 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 @@
 	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 @@
 	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 @@
 		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_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 @@
 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 @@
 	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 @@
 {
 	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 @@
 	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 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 @@
 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 @@
 		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 @@
 		    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 @@
 
 	phba->sysfs_mbox.offset = off + count;
 
-	spin_unlock_irq(host->host_lock);
+	spin_unlock_irq(&phba->hbalock);
 
 	return count;
 }
@@ -1276,10 +1319,11 @@
 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 @@
 	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 @@
 		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 @@
 			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 @@
 				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 @@
 		 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 @@
 	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 @@
 };
 
 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 @@
 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 @@
 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 @@
 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 @@
 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 @@
 	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 @@
 	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 @@
 	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 @@
 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 @@
 	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 @@
 	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 @@
 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 @@
 	.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.