lpfc_nportdisc.c

来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 1,971 行 · 第 1/4 页

C
1,971
字号
	}	return ndlp->nlp_state;}static uint32_tlpfc_device_rm_adisc_issue(struct lpfc_hba * phba,			    struct lpfc_nodelist * ndlp, void *arg,			    uint32_t evt){	if(ndlp->nlp_flag & NLP_NPR_2B_DISC) {		ndlp->nlp_flag |= NLP_NODEV_REMOVE;		return ndlp->nlp_state;	}	else {		/* software abort outstanding ADISC */		lpfc_els_abort(phba, ndlp, 1);		lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);		return NLP_STE_FREED_NODE;	}}static uint32_tlpfc_device_recov_adisc_issue(struct lpfc_hba * phba,			    struct lpfc_nodelist * ndlp, void *arg,			    uint32_t evt){	/* software abort outstanding ADISC */	lpfc_els_abort(phba, ndlp, 1);	ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;	ndlp->nlp_state = NLP_STE_NPR_NODE;	lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);	spin_lock_irq(phba->host->host_lock);	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);	ndlp->nlp_flag |= NLP_NPR_ADISC;	spin_unlock_irq(phba->host->host_lock);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_plogi_reglogin_issue(struct lpfc_hba * phba,			      struct lpfc_nodelist * ndlp, void *arg,			      uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_rcv_plogi(phba, ndlp, cmdiocb);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_prli_reglogin_issue(struct lpfc_hba * phba,			     struct lpfc_nodelist * ndlp, void *arg,			     uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba,			     struct lpfc_nodelist * ndlp, void *arg,			     uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_padisc_reglogin_issue(struct lpfc_hba * phba,			       struct lpfc_nodelist * ndlp, void *arg,			       uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_rcv_padisc(phba, ndlp, cmdiocb);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba,			     struct lpfc_nodelist * ndlp, void *arg,			     uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);	return ndlp->nlp_state;}static uint32_tlpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,				  struct lpfc_nodelist * ndlp,				  void *arg, uint32_t evt){	LPFC_MBOXQ_t *pmb;	MAILBOX_t *mb;	uint32_t did;	pmb = (LPFC_MBOXQ_t *) arg;	mb = &pmb->mb;	did = mb->un.varWords[1];	if (mb->mbxStatus) {		/* RegLogin failed */		lpfc_printf_log(phba,				KERN_ERR,				LOG_DISCOVERY,				"%d:0246 RegLogin failed Data: x%x x%x x%x\n",				phba->brd_no,				did, mb->mbxStatus, phba->hba_state);		/* Put ndlp in npr list set plogi timer for 1 sec */		mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);		spin_lock_irq(phba->host->host_lock);		ndlp->nlp_flag |= NLP_DELAY_TMO;		spin_unlock_irq(phba->host->host_lock);		ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;		lpfc_issue_els_logo(phba, ndlp, 0);		ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;		ndlp->nlp_state = NLP_STE_NPR_NODE;		lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);		return ndlp->nlp_state;	}	ndlp->nlp_rpi = mb->un.varWords[0];	/* Only if we are not a fabric nport do we issue PRLI */	if (!(ndlp->nlp_type & NLP_FABRIC)) {		ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;		ndlp->nlp_state = NLP_STE_PRLI_ISSUE;		lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST);		lpfc_issue_els_prli(phba, ndlp, 0);	} else {		ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;		ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;		lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);	}	return ndlp->nlp_state;}static uint32_tlpfc_device_rm_reglogin_issue(struct lpfc_hba * phba,			      struct lpfc_nodelist * ndlp, void *arg,			      uint32_t evt){	if(ndlp->nlp_flag & NLP_NPR_2B_DISC) {		ndlp->nlp_flag |= NLP_NODEV_REMOVE;		return ndlp->nlp_state;	}	else {		lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);		return NLP_STE_FREED_NODE;	}}static uint32_tlpfc_device_recov_reglogin_issue(struct lpfc_hba * phba,			       struct lpfc_nodelist * ndlp, void *arg,			       uint32_t evt){	ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;	ndlp->nlp_state = NLP_STE_NPR_NODE;	lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);	spin_lock_irq(phba->host->host_lock);	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);	spin_unlock_irq(phba->host->host_lock);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_plogi_prli_issue(struct lpfc_hba * phba,			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_rcv_plogi(phba, ndlp, cmdiocb);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_prli_prli_issue(struct lpfc_hba * phba,			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_logo_prli_issue(struct lpfc_hba * phba,			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	/* Software abort outstanding PRLI before sending acc */	lpfc_els_abort(phba, ndlp, 1);	lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_padisc_prli_issue(struct lpfc_hba * phba,			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_rcv_padisc(phba, ndlp, cmdiocb);	return ndlp->nlp_state;}/* This routine is envoked when we rcv a PRLO request from a nport * we are logged into.  We should send back a PRLO rsp setting the * appropriate bits. * NEXT STATE = PRLI_ISSUE */static uint32_tlpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba,			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);	return ndlp->nlp_state;}static uint32_tlpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba,			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb, *rspiocb;	IOCB_t *irsp;	PRLI *npr;	cmdiocb = (struct lpfc_iocbq *) arg;	rspiocb = cmdiocb->context_un.rsp_iocb;	npr = (PRLI *)lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb);	irsp = &rspiocb->iocb;	if (irsp->ulpStatus) {		ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;		ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;		lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);		return ndlp->nlp_state;	}	/* Check out PRLI rsp */	ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);	ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;	if ((npr->acceptRspCode == PRLI_REQ_EXECUTED) &&	    (npr->prliType == PRLI_FCP_TYPE)) {		if (npr->initiatorFunc)			ndlp->nlp_type |= NLP_FCP_INITIATOR;		if (npr->targetFunc)			ndlp->nlp_type |= NLP_FCP_TARGET;		if (npr->Retry)			ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;	}	ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;	ndlp->nlp_state = NLP_STE_MAPPED_NODE;	lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST);	return ndlp->nlp_state;}/*! lpfc_device_rm_prli_issue  *  * \pre  * \post  * \param   phba  * \param   ndlp  * \param   arg  * \param   evt  * \return  uint32_t  *  * \b Description:  *    This routine is envoked when we a request to remove a nport we are in the  *    process of PRLIing. We should software abort outstanding prli, unreg  *    login, send a logout. We will change node state to UNUSED_NODE, put it  *    on plogi list so it can be freed when LOGO completes.  *  */static uint32_tlpfc_device_rm_prli_issue(struct lpfc_hba * phba,			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	if(ndlp->nlp_flag & NLP_NPR_2B_DISC) {		ndlp->nlp_flag |= NLP_NODEV_REMOVE;		return ndlp->nlp_state;	}	else {		/* software abort outstanding PLOGI */		lpfc_els_abort(phba, ndlp, 1);		lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);		return NLP_STE_FREED_NODE;	}}/*! lpfc_device_recov_prli_issue  *  * \pre  * \post  * \param   phba  * \param   ndlp  * \param   arg  * \param   evt  * \return  uint32_t  *  * \b Description:  *    The routine is envoked when the state of a device is unknown, like  *    during a link down. We should remove the nodelist entry from the  *    unmapped list, issue a UNREG_LOGIN, do a software abort of the  *    outstanding PRLI command, then free the node entry.  */static uint32_tlpfc_device_recov_prli_issue(struct lpfc_hba * phba,			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	/* software abort outstanding PRLI */	lpfc_els_abort(phba, ndlp, 1);	ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;	ndlp->nlp_state = NLP_STE_NPR_NODE;	lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);	spin_lock_irq(phba->host->host_lock);	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);	spin_unlock_irq(phba->host->host_lock);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_plogi_unmap_node(struct lpfc_hba * phba,			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_rcv_plogi(phba, ndlp, cmdiocb);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_prli_unmap_node(struct lpfc_hba * phba,			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_rcv_prli(phba, ndlp, cmdiocb);	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_logo_unmap_node(struct lpfc_hba * phba,			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_padisc_unmap_node(struct lpfc_hba * phba,			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_rcv_padisc(phba, ndlp, cmdiocb);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba,			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);	return ndlp->nlp_state;}static uint32_tlpfc_device_recov_unmap_node(struct lpfc_hba * phba,			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE;	ndlp->nlp_state = NLP_STE_NPR_NODE;	lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);	lpfc_disc_set_adisc(phba, ndlp);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_plogi_mapped_node(struct lpfc_hba * phba,			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_rcv_plogi(phba, ndlp, cmdiocb);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_prli_mapped_node(struct lpfc_hba * phba,			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_logo_mapped_node(struct lpfc_hba * phba,			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_padisc_mapped_node(struct lpfc_hba * phba,			    struct lpfc_nodelist * ndlp, void *arg,			    uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	lpfc_rcv_padisc(phba, ndlp, cmdiocb);	return ndlp->nlp_state;}static uint32_tlpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba,			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt){	struct lpfc_iocbq *cmdiocb;	cmdiocb = (struct lpfc_iocbq *) arg;	/* flush the target */	spin_lock_irq(phba->host->host_lock);	lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],			       ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?