[SCSI] lpfc 8.3.0 : Fix multiple NPIV issues

- Fix lock up on rmmod with vports defined by having
  lpfc_pci_remove_one() invoke fc_vport_terminate() to remove all the
  vports before invoking fc_remove_host() for the physical port

- Fix echotest failure when NPIV is enabled

- Add the vport_disable function to the physical port's transport
  template to make the vport disable attribute visible

- Set the vport state to DISABLE on create if the disable flag is
  true

- Call lpfc_alloc_sysfs_attr() for vports so that statistical data
  collection works on them

- Support setting a vport's symbolic name via sysfs by writing to
  /sys/class/fc_vport/vportX/symbolic_name

- Fix create vport fails when link is down or in loop mode.  Should be
  able to be create vports any time NPIV is enabled

- Fix slow vport deletes when deleting multiple vports at once

Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index b213d1d..56ed528 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2041,8 +2041,6 @@
 	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 	struct lpfc_hba  *phba = vport->phba;
 
-	kfree(vport->vname);
-
 	lpfc_debugfs_terminate(vport);
 	fc_remove_host(shost);
 	scsi_remove_host(shost);
@@ -2716,18 +2714,27 @@
 {
 	struct Scsi_Host  *shost = pci_get_drvdata(pdev);
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_vport **vports;
 	struct lpfc_hba   *phba = vport->phba;
+	int i;
 	int bars = pci_select_bars(pdev, IORESOURCE_MEM);
 
 	spin_lock_irq(&phba->hbalock);
 	vport->load_flag |= FC_UNLOADING;
 	spin_unlock_irq(&phba->hbalock);
 
-	kfree(vport->vname);
 	lpfc_free_sysfs_attr(vport);
 
 	kthread_stop(phba->worker_thread);
 
+	/* Release all the vports against this physical port */
+	vports = lpfc_create_vport_work_array(phba);
+	if (vports != NULL)
+		for (i = 1; i <= phba->max_vpi && vports[i] != NULL; i++)
+			fc_vport_terminate(vports[i]->fc_vport);
+	lpfc_destroy_vport_work_array(phba, vports);
+
+	/* Remove FC host and then SCSI host with the physical port */
 	fc_remove_host(shost);
 	scsi_remove_host(shost);
 	lpfc_cleanup(vport);