Commit 78730cfe authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.3.12: Fix discovery issues



- Add code to prevent unreg_vpi mailbox command from failing.
- Add code to reset the HBA if unreg_vpi mailbox fails with busy status.
- Remove code that was clearing the nlp_type stored during rport discovery.

Signed-off-by: default avatarAlex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent c7495937
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *);
void lpfc_retry_pport_discovery(struct lpfc_hba *);
void lpfc_release_rpi(struct lpfc_hba *, struct lpfc_vport *, uint16_t);

void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *);
+1 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ enum lpfc_work_type {
	LPFC_EVT_ELS_RETRY,
	LPFC_EVT_DEV_LOSS,
	LPFC_EVT_FASTPATH_MGMT_EVT,
	LPFC_EVT_RESET_HBA,
};

/* structure used to queue event to the discovery tasklet */
+2 −0
Original line number Diff line number Diff line
@@ -584,6 +584,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
			spin_unlock_irq(shost->host_lock);
			lpfc_unreg_rpi(vport, np);
		}
		lpfc_cleanup_pending_mbox(vport);
		if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
			lpfc_mbx_unreg_vpi(vport);
			spin_lock_irq(shost->host_lock);
@@ -6316,6 +6317,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			spin_unlock_irq(shost->host_lock);
			lpfc_unreg_rpi(vport, np);
		}
		lpfc_cleanup_pending_mbox(vport);
		lpfc_mbx_unreg_vpi(vport);
		spin_lock_irq(shost->host_lock);
		vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
+13 −2
Original line number Diff line number Diff line
@@ -475,6 +475,10 @@ lpfc_work_list_done(struct lpfc_hba *phba)
			lpfc_send_fastpath_evt(phba, evtp);
			free_evt = 0;
			break;
		case LPFC_EVT_RESET_HBA:
			if (!(phba->pport->load_flag & FC_UNLOADING))
				lpfc_reset_hba(phba);
			break;
		}
		if (free_evt)
			kfree(evtp);
@@ -2737,11 +2741,18 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	switch (mb->mbxStatus) {
	case 0x0011:
	case 0x0020:
	case 0x9700:
		lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
				 "0911 cmpl_unreg_vpi, mb status = 0x%x\n",
				 mb->mbxStatus);
		break;
	/* If VPI is busy, reset the HBA */
	case 0x9700:
		lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
			"2798 Unreg_vpi failed vpi 0x%x, mb status = 0x%x\n",
			vport->vpi, mb->mbxStatus);
		if (!(phba->pport->load_flag & FC_UNLOADING))
			lpfc_workq_post_event(phba, NULL, NULL,
				LPFC_EVT_RESET_HBA);
	}
	spin_lock_irq(shost->host_lock);
	vport->vpi_state &= ~LPFC_VPI_REGISTERED;
@@ -3233,7 +3244,6 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
	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;
		ndlp->nlp_type |= NLP_FC_NODE;
	}
@@ -4991,6 +5001,7 @@ lpfc_unregister_fcf_prep(struct lpfc_hba *phba)
			ndlp = lpfc_findnode_did(vports[i], Fabric_DID);
			if (ndlp)
				lpfc_cancel_retry_delay_tmo(vports[i], ndlp);
			lpfc_cleanup_pending_mbox(vports[i]);
			lpfc_mbx_unreg_vpi(vports[i]);
			shost = lpfc_shost_from_vport(vports[i]);
			spin_lock_irq(shost->host_lock);
+17 −3
Original line number Diff line number Diff line
@@ -3227,12 +3227,26 @@ lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport)

	if (!vport)
		return NULL;
	ndlp = lpfc_findnode_did(vport, Fabric_DID);
	if (!ndlp)
		return NULL;
	phba = vport->phba;
	if (!phba)
		return NULL;
	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(vport, ndlp, Fabric_DID);
		/* Set the node type */
		ndlp->nlp_type |= NLP_FABRIC;
		/* Put ndlp onto node list */
		lpfc_enqueue_node(vport, ndlp);
	} else if (!NLP_CHK_NODE_ACT(ndlp)) {
		/* re-setup ndlp without removing from node list */
		ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
		if (!ndlp)
			return 0;
	}
	if (phba->pport->port_state <= LPFC_FLOGI)
		return NULL;
	/* If virtual link is not yet instantiated ignore CVL */
Loading