[SCSI] lpfc 8.2.2 : Miscellaneous Bug Fixes

- Fix vport ndlp ref counting errors
- Fix use after free of ndlp structure
- Use the correct flag to check for LOADING setting.
- Fix driver unload bugs (related to shost references) after link down or rscn
- Fix up HBQ initialization
- Fix port_list locking around driver unload.
- Fix references to hostdata as a phba
- Fix GFFID type offset to work correctly with big endian structure.
- Only call pci_disable_msi if the pci_enable_msi succeeded
- Fix vport_delete wait/fail if in discovery
- Put a reference on the nameservers ndlp when performing CT traffic.
- Remove unbalanced hba unlock.
- Fix up HBQ processing
- Fix lpfc debugfs discovery trace output for ELS rsp cmpl
- Send ADISC when rpi is 0
- Stop FDISC retrying forever
- Unable to retrieve correct config parameter for vport
- Fix sli_validate_fcp_iocb, sli_sum_iocb, sli_abort_iocb to be vport-aware.
- Fix index-out-of-range error in iocb. Spotted by Coverity.

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_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index ad7f33a..6f187f3 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -257,6 +257,10 @@
 {
 	struct lpfc_dmabuf *buf_ptr;
 
+	if (ctiocb->context_un.ndlp) {
+		lpfc_nlp_put(ctiocb->context_un.ndlp);
+		ctiocb->context_un.ndlp = NULL;
+	}
 	if (ctiocb->context1) {
 		buf_ptr = (struct lpfc_dmabuf *) ctiocb->context1;
 		lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
@@ -314,6 +318,7 @@
 	/* Save for completion so we can release these resources */
 	geniocb->context1 = (uint8_t *) inp;
 	geniocb->context2 = (uint8_t *) outp;
+	geniocb->context_un.ndlp = ndlp;
 
 	/* Fill in payload, bp points to frame payload */
 	icmd->ulpCommand = CMD_GEN_REQUEST64_CR;
@@ -548,8 +553,12 @@
 	struct lpfc_dmabuf *bmp;
 	struct lpfc_dmabuf *outp;
 	struct lpfc_sli_ct_request *CTrsp;
+	struct lpfc_nodelist *ndlp;
 	int rc;
 
+	/* First save ndlp, before we overwrite it */
+	ndlp = cmdiocb->context_un.ndlp;
+
 	/* we pass cmdiocb to state machine which needs rspiocb as well */
 	cmdiocb->context_un.rsp_iocb = rspiocb;
 
@@ -674,6 +683,7 @@
 		lpfc_disc_start(vport);
 	}
 out:
+	cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
 	lpfc_ct_free_iocb(phba, cmdiocb);
 	return;
 }
@@ -776,10 +786,14 @@
 	struct lpfc_dmabuf *outp;
 	IOCB_t *irsp;
 	struct lpfc_sli_ct_request *CTrsp;
+	struct lpfc_nodelist *ndlp;
 	int cmdcode, rc;
 	uint8_t retry;
 	uint32_t latt;
 
+	/* First save ndlp, before we overwrite it */
+	ndlp = cmdiocb->context_un.ndlp;
+
 	/* we pass cmdiocb to state machine which needs rspiocb as well */
 	cmdiocb->context_un.rsp_iocb = rspiocb;
 
@@ -828,6 +842,7 @@
 	}
 
 out:
+	cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
 	lpfc_ct_free_iocb(phba, cmdiocb);
 	return;
 }
@@ -1066,6 +1081,7 @@
 		cmpl = lpfc_cmpl_ct_cmd_rff_id;
 		break;
 	}
+	lpfc_nlp_get(ndlp);
 
 	if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) {
 		/* On success, The cmpl function will free the buffers */
@@ -1076,6 +1092,7 @@
 	}
 
 	rc=6;
+	lpfc_nlp_put(ndlp);
 	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
 ns_cmd_free_bmp:
 	kfree(bmp);
@@ -1501,10 +1518,12 @@
 	bpl->tus.w = le32_to_cpu(bpl->tus.w);
 
 	cmpl = lpfc_cmpl_ct_cmd_fdmi;
+	lpfc_nlp_get(ndlp);
 
 	if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP, 0))
 		return 0;
 
+	lpfc_nlp_put(ndlp);
 	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
 fdmi_cmd_free_bmp:
 	kfree(bmp);