[SCSI] lpfc 8.3.27: Miscellanous logic and interface fixes

Miscellanous logic and interface fixes

- Fix lpfc_init_vfi_cmpl to check the interface type for interface type 0
  before parsing the results.
- Cast uint32_t values that are multiplied to uint64_t before the
  multiplication.
- Instead of "break" statement when PCI read returned error, use the goto
  statement to the end of the routine after setting return value
- moved the msleep(10) to the beginning of the wait loop for checking the
  SLIPort_Status register
- Added the code to follow the existing wait for SLIPort_Status register RDY,
  ERR, and RN bits to be set by the port before proceeding to perform PCI
  function reset.
- Do not override ulpCt_h and ulpCt_l for SLI 4 ports.
- For vport delete, call lpfc_nlp_put when the vport's vpi state is not
  marked with VPI_REGISTERED.
- Added missed fields into the driver's Controller Attributes Structure
- Changed ringing EQ/CQ/RQ doorbell register to be dependent on the size
  of the queue.
- Return -EACCES in issue_reset if cfg_enable_hba_reset is zero.
- Added new logging flag LOG_FCP_UNDER 0x00040000 to qualify underrun logging.
- Add a check in the fabric name display routine to display 0 if the port
  state is <= FLOGI.
- Add a check to the switch statement in lpfc_decode_firmware_rev to check
  for an 'X'.

Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 13215cd..72cb750 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -749,9 +749,11 @@
 	struct Scsi_Host  *shost = class_to_shost(dev);
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
 	struct lpfc_hba   *phba = vport->phba;
-
 	int status = -EINVAL;
 
+	if (!phba->cfg_enable_hba_reset)
+		return -EACCES;
+
 	if (strncmp(buf, "selective", sizeof("selective") - 1) == 0)
 		status = phba->lpfc_selective_reset(phba);
 
@@ -772,7 +774,7 @@
  * Returns:
  * zero for success
  **/
-static int
+int
 lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba)
 {
 	struct lpfc_register portstat_reg = {0};
@@ -4494,9 +4496,10 @@
 
 	spin_lock_irq(shost->host_lock);
 
-	if ((vport->fc_flag & FC_FABRIC) ||
-	    ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
-	     (vport->fc_flag & FC_PUBLIC_LOOP)))
+	if ((vport->port_state > LPFC_FLOGI) &&
+	    ((vport->fc_flag & FC_FABRIC) ||
+	     ((phba->fc_topology == LPFC_TOPOLOGY_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 */
@@ -4569,9 +4572,17 @@
 	memset(hs, 0, sizeof (struct fc_host_statistics));
 
 	hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt;
-	hs->tx_words = (pmb->un.varRdStatus.xmitByteCnt * 256);
+	/*
+	 * The MBX_READ_STATUS returns tx_k_bytes which has to
+	 * converted to words
+	 */
+	hs->tx_words = (uint64_t)
+			((uint64_t)pmb->un.varRdStatus.xmitByteCnt
+			* (uint64_t)256);
 	hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
-	hs->rx_words = (pmb->un.varRdStatus.rcvByteCnt * 256);
+	hs->rx_words = (uint64_t)
+			((uint64_t)pmb->un.varRdStatus.rcvByteCnt
+			 * (uint64_t)256);
 
 	memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
 	pmb->mbxCommand = MBX_READ_LNK_STAT;