⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpfc_hbadisc.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	psli->sli_flag |= LPFC_PROCESS_LA;	control = readl(phba->HCregaddr);	control |= HC_LAINT_ENA;	writel(control, phba->HCregaddr);	readl(phba->HCregaddr); /* flush */	spin_unlock_irq(phba->host->host_lock);	return;}static voidlpfc_mbx_cmpl_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb){	struct lpfc_sli *psli;	MAILBOX_t *mb;	psli = &phba->sli;	mb = &pmb->mb;	/* Check for error */	if (mb->mbxStatus) {		/* CONFIG_LINK mbox error <mbxStatus> state <hba_state> */		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,				"%d:0306 CONFIG_LINK mbxStatus error x%x "				"HBA state x%x\n",				phba->brd_no, mb->mbxStatus, phba->hba_state);		lpfc_linkdown(phba);		phba->hba_state = LPFC_HBA_ERROR;		goto out;	}	if (phba->hba_state == LPFC_LOCAL_CFG_LINK) {		if (phba->fc_topology == TOPOLOGY_LOOP) {			/* If we are public loop and L bit was set */			if ((phba->fc_flag & FC_PUBLIC_LOOP) &&			    !(phba->fc_flag & FC_LBIT)) {				/* Need to wait for FAN - use discovery timer				 * for timeout.  hba_state is identically				 * LPFC_LOCAL_CFG_LINK while waiting for FAN				 */				lpfc_set_disctmo(phba);				mempool_free( pmb, phba->mbox_mem_pool);				return;			}		}		/* Start discovery by sending a FLOGI hba_state is identically		 * LPFC_FLOGI while waiting for FLOGI cmpl		 */		phba->hba_state = LPFC_FLOGI;		lpfc_set_disctmo(phba);		lpfc_initial_flogi(phba);		mempool_free( pmb, phba->mbox_mem_pool);		return;	}	if (phba->hba_state == LPFC_FABRIC_CFG_LINK) {		mempool_free( pmb, phba->mbox_mem_pool);		return;	}out:	/* CONFIG_LINK bad hba state <hba_state> */	lpfc_printf_log(phba,			KERN_ERR,			LOG_DISCOVERY,			"%d:0200 CONFIG_LINK bad hba state x%x\n",			phba->brd_no, phba->hba_state);	if (phba->hba_state != LPFC_CLEAR_LA) {		lpfc_clear_la(phba, pmb);		pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la;		if (lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB))		    == MBX_NOT_FINISHED) {			mempool_free( pmb, phba->mbox_mem_pool);			lpfc_disc_flush_list(phba);			psli->ring[(psli->ip_ring)].flag &=				~LPFC_STOP_IOCB_EVENT;			psli->ring[(psli->fcp_ring)].flag &=				~LPFC_STOP_IOCB_EVENT;			psli->ring[(psli->next_ring)].flag &=				~LPFC_STOP_IOCB_EVENT;			phba->hba_state = LPFC_HBA_READY;		}	} else {		mempool_free( pmb, phba->mbox_mem_pool);	}	return;}static voidlpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb){	struct lpfc_sli *psli = &phba->sli;	MAILBOX_t *mb = &pmb->mb;	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1;	/* Check for error */	if (mb->mbxStatus) {		/* READ_SPARAM mbox error <mbxStatus> state <hba_state> */		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,				"%d:0319 READ_SPARAM mbxStatus error x%x "				"hba state x%x>\n",				phba->brd_no, mb->mbxStatus, phba->hba_state);		lpfc_linkdown(phba);		phba->hba_state = LPFC_HBA_ERROR;		goto out;	}	memcpy((uint8_t *) & phba->fc_sparam, (uint8_t *) mp->virt,	       sizeof (struct serv_parm));	memcpy((uint8_t *) & phba->fc_nodename,	       (uint8_t *) & phba->fc_sparam.nodeName,	       sizeof (struct lpfc_name));	memcpy((uint8_t *) & phba->fc_portname,	       (uint8_t *) & phba->fc_sparam.portName,	       sizeof (struct lpfc_name));	lpfc_mbuf_free(phba, mp->virt, mp->phys);	kfree(mp);	mempool_free( pmb, phba->mbox_mem_pool);	return;out:	pmb->context1 = NULL;	lpfc_mbuf_free(phba, mp->virt, mp->phys);	kfree(mp);	if (phba->hba_state != LPFC_CLEAR_LA) {		lpfc_clear_la(phba, pmb);		pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la;		if (lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB))		    == MBX_NOT_FINISHED) {			mempool_free( pmb, phba->mbox_mem_pool);			lpfc_disc_flush_list(phba);			psli->ring[(psli->ip_ring)].flag &=			    ~LPFC_STOP_IOCB_EVENT;			psli->ring[(psli->fcp_ring)].flag &=			    ~LPFC_STOP_IOCB_EVENT;			psli->ring[(psli->next_ring)].flag &=			    ~LPFC_STOP_IOCB_EVENT;			phba->hba_state = LPFC_HBA_READY;		}	} else {		mempool_free( pmb, phba->mbox_mem_pool);	}	return;}static voidlpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la){	int i;	LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox;	sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);	cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);	spin_lock_irq(phba->host->host_lock);	switch(la->UlnkSpeed) {		case LA_1GHZ_LINK:			phba->fc_linkspeed = LA_1GHZ_LINK;			break;		case LA_2GHZ_LINK:			phba->fc_linkspeed = LA_2GHZ_LINK;			break;		case LA_4GHZ_LINK:			phba->fc_linkspeed = LA_4GHZ_LINK;			break;		default:			phba->fc_linkspeed = LA_UNKNW_LINK;			break;	}	phba->fc_topology = la->topology;	if (phba->fc_topology == TOPOLOGY_LOOP) {	/* Get Loop Map information */		if (la->il)			phba->fc_flag |= FC_LBIT;		phba->fc_myDID = la->granted_AL_PA;		i = la->un.lilpBde64.tus.f.bdeSize;		if (i == 0) {			phba->alpa_map[0] = 0;		} else {			if (phba->cfg_log_verbose & LOG_LINK_EVENT) {				int numalpa, j, k;				union {					uint8_t pamap[16];					struct {						uint32_t wd1;						uint32_t wd2;						uint32_t wd3;						uint32_t wd4;					} pa;				} un;				numalpa = phba->alpa_map[0];				j = 0;				while (j < numalpa) {					memset(un.pamap, 0, 16);					for (k = 1; j < numalpa; k++) {						un.pamap[k - 1] =							phba->alpa_map[j + 1];						j++;						if (k == 16)							break;					}					/* Link Up Event ALPA map */					lpfc_printf_log(phba,						KERN_WARNING,						LOG_LINK_EVENT,						"%d:1304 Link Up Event "						"ALPA map Data: x%x "						"x%x x%x x%x\n",						phba->brd_no,						un.pa.wd1, un.pa.wd2,						un.pa.wd3, un.pa.wd4);				}			}		}	} else {		phba->fc_myDID = phba->fc_pref_DID;		phba->fc_flag |= FC_LBIT;	}	spin_unlock_irq(phba->host->host_lock);	lpfc_linkup(phba);	if (sparam_mbox) {		lpfc_read_sparam(phba, sparam_mbox);		sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;		lpfc_sli_issue_mbox(phba, sparam_mbox,						(MBX_NOWAIT | MBX_STOP_IOCB));	}	if (cfglink_mbox) {		phba->hba_state = LPFC_LOCAL_CFG_LINK;		lpfc_config_link(phba, cfglink_mbox);		cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_config_link;		lpfc_sli_issue_mbox(phba, cfglink_mbox,						(MBX_NOWAIT | MBX_STOP_IOCB));	}}static voidlpfc_mbx_issue_link_down(struct lpfc_hba *phba) {	uint32_t control;	struct lpfc_sli *psli = &phba->sli;	lpfc_linkdown(phba);	/* turn on Link Attention interrupts - no CLEAR_LA needed */	spin_lock_irq(phba->host->host_lock);	psli->sli_flag |= LPFC_PROCESS_LA;	control = readl(phba->HCregaddr);	control |= HC_LAINT_ENA;	writel(control, phba->HCregaddr);	readl(phba->HCregaddr); /* flush */	spin_unlock_irq(phba->host->host_lock);}/* * This routine handles processing a READ_LA mailbox * command upon completion. It is setup in the LPFC_MBOXQ * as the completion routine when the command is * handed off to the SLI layer. */voidlpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb){	READ_LA_VAR *la;	MAILBOX_t *mb = &pmb->mb;	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);	/* Check for error */	if (mb->mbxStatus) {		lpfc_printf_log(phba,				KERN_INFO,				LOG_LINK_EVENT,				"%d:1307 READ_LA mbox error x%x state x%x\n",				phba->brd_no,				mb->mbxStatus, phba->hba_state);		lpfc_mbx_issue_link_down(phba);		phba->hba_state = LPFC_HBA_ERROR;		goto lpfc_mbx_cmpl_read_la_free_mbuf;	}	la = (READ_LA_VAR *) & pmb->mb.un.varReadLA;	memcpy(&phba->alpa_map[0], mp->virt, 128);	if (((phba->fc_eventTag + 1) < la->eventTag) ||	     (phba->fc_eventTag == la->eventTag)) {		phba->fc_stat.LinkMultiEvent++;		if (la->attType == AT_LINK_UP) {			if (phba->fc_eventTag != 0)				lpfc_linkdown(phba);		}	}	phba->fc_eventTag = la->eventTag;	if (la->attType == AT_LINK_UP) {		phba->fc_stat.LinkUp++;		lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,				"%d:1303 Link Up Event x%x received "				"Data: x%x x%x x%x x%x\n",				phba->brd_no, la->eventTag, phba->fc_eventTag,				la->granted_AL_PA, la->UlnkSpeed,				phba->alpa_map[0]);		lpfc_mbx_process_link_up(phba, la);	} else {		phba->fc_stat.LinkDown++;		lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,				"%d:1305 Link Down Event x%x received "				"Data: x%x x%x x%x\n",				phba->brd_no, la->eventTag, phba->fc_eventTag,				phba->hba_state, phba->fc_flag);		lpfc_mbx_issue_link_down(phba);	}lpfc_mbx_cmpl_read_la_free_mbuf:	lpfc_mbuf_free(phba, mp->virt, mp->phys);	kfree(mp);	mempool_free(pmb, phba->mbox_mem_pool);	return;}/* * This routine handles processing a REG_LOGIN mailbox * command upon completion. It is setup in the LPFC_MBOXQ * as the completion routine when the command is * handed off to the SLI layer. */voidlpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb){	struct lpfc_sli *psli;	MAILBOX_t *mb;	struct lpfc_dmabuf *mp;	struct lpfc_nodelist *ndlp;	psli = &phba->sli;	mb = &pmb->mb;	ndlp = (struct lpfc_nodelist *) pmb->context2;	mp = (struct lpfc_dmabuf *) (pmb->context1);	pmb->context1 = NULL;	/* Good status, call state machine */	lpfc_disc_state_machine(phba, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN);	lpfc_mbuf_free(phba, mp->virt, mp->phys);	kfree(mp);	mempool_free( pmb, phba->mbox_mem_pool);	return;}/* * This routine handles processing a Fabric REG_LOGIN mailbox * command upon completion. It is setup in the LPFC_MBOXQ * as the completion routine when the command is * handed off to the SLI layer. */voidlpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb){	struct lpfc_sli *psli;	MAILBOX_t *mb;	struct lpfc_dmabuf *mp;	struct lpfc_nodelist *ndlp;	struct lpfc_nodelist *ndlp_fdmi;	psli = &phba->sli;	mb = &pmb->mb;	ndlp = (struct lpfc_nodelist *) pmb->context2;	mp = (struct lpfc_dmabuf *) (pmb->context1);	if (mb->mbxStatus) {		lpfc_mbuf_free(phba, mp->virt, mp->phys);		kfree(mp);		mempool_free( pmb, phba->mbox_mem_pool);		mempool_free( ndlp, phba->nlp_mem_pool);		/* FLOGI failed, so just use loop map to make discovery list */		lpfc_disc_list_loopmap(phba);		/* Start discovery */		lpfc_disc_start(phba);		return;	}	pmb->context1 = NULL;	ndlp->nlp_rpi = mb->un.varWords[0];	ndlp->nlp_type |= NLP_FABRIC;	ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;	lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);	if (phba->hba_state == LPFC_FABRIC_CFG_LINK) {		/* This NPort has been assigned an NPort_ID by the fabric as a		 * result of the completed fabric login.  Issue a State Change		 * Registration (SCR) ELS request to the fabric controller		 * (SCR_DID) so that this NPort gets RSCN events from the		 * fabric.		 */		lpfc_issue_els_scr(phba, SCR_DID, 0);		/* Allocate a new node instance.  If the pool is empty, just		 * start the discovery process and skip the Nameserver login		 * process.  This is attempted again later on.  Otherwise, issue		 * a Port Login (PLOGI) to the NameServer		 */		if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL))		    == 0) {			lpfc_disc_start(phba);		} else {			lpfc_nlp_init(phba, ndlp, NameServer_DID);			ndlp->nlp_type |= NLP_FABRIC;			ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;			lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);			lpfc_issue_els_plogi(phba, ndlp, 0);			if (phba->cfg_fdmi_on) {				if ((ndlp_fdmi = mempool_alloc(						       phba->nlp_mem_pool,						       GFP_KERNEL))) {					lpfc_nlp_init(phba, ndlp_fdmi,						FDMI_DID);					ndlp_fdmi->nlp_type |= NLP_FABRIC;					ndlp_fdmi->nlp_state =					    NLP_STE_PLOGI_ISSUE;					lpfc_issue_els_plogi(phba, ndlp_fdmi,							     0);				}			}		}	}	lpfc_mbuf_free(phba, mp->virt, mp->phys);	kfree(mp);	mempool_free( pmb, phba->mbox_mem_pool);	return;}/* * This routine handles processing a NameServer REG_LOGIN mailbox * command upon completion. It is setup in the LPFC_MBOXQ * as the completion routine when the command is * handed off to the SLI layer. */voidlpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb){	struct lpfc_sli *psli;	MAILBOX_t *mb;	struct lpfc_dmabuf *mp;	struct lpfc_nodelist *ndlp;	psli = &phba->sli;	mb = &pmb->mb;	ndlp = (struct lpfc_nodelist *) pmb->context2;	mp = (struct lpfc_dmabuf *) (pmb->context1);	if (mb->mbxStatus) {		lpfc_mbuf_free(phba, mp->virt, mp->phys);		kfree(mp);		mempool_free( pmb, phba->mbox_mem_pool);		lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);		/* RegLogin failed, so just use loop map to make discovery		   list */		lpfc_disc_list_loopmap(phba);		/* Start discovery */		lpfc_disc_start(phba);		return;	}	pmb->context1 = NULL;	ndlp->nlp_rpi = mb->un.varWords[0];	ndlp->nlp_type |= NLP_FABRIC;	ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;	lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);	if (phba->hba_state < LPFC_HBA_READY) {		/* Link up discovery requires Fabrib registration. */		lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RNN_ID);		lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RSNN_NN);		lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFT_ID);

⌨️ 快捷键说明

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