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

📄 lpfc_hbadisc.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* First do ADISCs - if any */	num_sent = lpfc_els_disc_adisc(phba);	if (num_sent)		return;	if ((phba->hba_state < LPFC_HBA_READY) && (!clear_la_pending)) {		/* If we get here, there is nothing to ADISC */		if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) {			phba->hba_state = LPFC_CLEAR_LA;			lpfc_clear_la(phba, mbox);			mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la;			rc = lpfc_sli_issue_mbox(phba, mbox,						 (MBX_NOWAIT | MBX_STOP_IOCB));			if (rc == MBX_NOT_FINISHED) {				mempool_free( mbox, 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 {		/* Next do PLOGIs - if any */		num_sent = lpfc_els_disc_plogi(phba);		if (num_sent)			return;		if (phba->fc_flag & FC_RSCN_MODE) {			/* Check to see if more RSCNs came in while we			 * were processing this one.			 */			if ((phba->fc_rscn_id_cnt == 0) &&			    (!(phba->fc_flag & FC_RSCN_DISCOVERY))) {				spin_lock_irq(phba->host->host_lock);				phba->fc_flag &= ~FC_RSCN_MODE;				spin_unlock_irq(phba->host->host_lock);			}			else				lpfc_els_handle_rscn(phba);		}	}	return;}/* *  Ignore completion for all IOCBs on tx and txcmpl queue for ELS *  ring the match the sppecified nodelist. */static voidlpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp){	struct lpfc_sli *psli;	IOCB_t     *icmd;	struct lpfc_iocbq    *iocb, *next_iocb;	struct lpfc_sli_ring *pring;	struct lpfc_dmabuf   *mp;	psli = &phba->sli;	pring = &psli->ring[LPFC_ELS_RING];	/* Error matching iocb on txq or txcmplq	 * First check the txq.	 */	list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {		if (iocb->context1 != ndlp) {			continue;		}		icmd = &iocb->iocb;		if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) ||		    (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) {			list_del(&iocb->list);			pring->txq_cnt--;			lpfc_els_free_iocb(phba, iocb);		}	}	/* Next check the txcmplq */	list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {		if (iocb->context1 != ndlp) {			continue;		}		icmd = &iocb->iocb;		if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) ||		    (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) {			iocb->iocb_cmpl = NULL;			/* context2 = cmd, context2->next = rsp, context3 =			   bpl */			if (iocb->context2) {				/* Free the response IOCB before handling the				   command. */				mp = (struct lpfc_dmabuf *) (iocb->context2);				mp = list_get_first(&mp->list,						    struct lpfc_dmabuf,						    list);				if (mp) {					/* Delay before releasing rsp buffer to					 * give UNREG mbox a chance to take					 * effect.					 */					list_add(&mp->list,						&phba->freebufList);				}				lpfc_mbuf_free(phba,					       ((struct lpfc_dmabuf *)						iocb->context2)->virt,					       ((struct lpfc_dmabuf *)						iocb->context2)->phys);				kfree(iocb->context2);			}			if (iocb->context3) {				lpfc_mbuf_free(phba,					       ((struct lpfc_dmabuf *)						iocb->context3)->virt,					       ((struct lpfc_dmabuf *)						iocb->context3)->phys);				kfree(iocb->context3);			}		}	}	return;}voidlpfc_disc_flush_list(struct lpfc_hba * phba){	struct lpfc_nodelist *ndlp, *next_ndlp;	if (phba->fc_plogi_cnt) {		list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list,					nlp_listp) {			lpfc_free_tx(phba, ndlp);			lpfc_nlp_remove(phba, ndlp);		}	}	if (phba->fc_adisc_cnt) {		list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list,					nlp_listp) {			lpfc_free_tx(phba, ndlp);			lpfc_nlp_remove(phba, ndlp);		}	}	return;}/*****************************************************************************//* * NAME:     lpfc_disc_timeout * * FUNCTION: Fibre Channel driver discovery timeout routine. * * EXECUTION ENVIRONMENT: interrupt only * * CALLED FROM: *      Timer function * * RETURNS: *      none *//*****************************************************************************/voidlpfc_disc_timeout(unsigned long ptr){	struct lpfc_hba *phba = (struct lpfc_hba *)ptr;	unsigned long flags = 0;	if (unlikely(!phba))		return;	spin_lock_irqsave(phba->host->host_lock, flags);	if (!(phba->work_hba_events & WORKER_DISC_TMO)) {		phba->work_hba_events |= WORKER_DISC_TMO;		if (phba->work_wait)			wake_up(phba->work_wait);	}	spin_unlock_irqrestore(phba->host->host_lock, flags);	return;}static voidlpfc_disc_timeout_handler(struct lpfc_hba *phba){	struct lpfc_sli *psli;	struct lpfc_nodelist *ndlp;	LPFC_MBOXQ_t *clearlambox, *initlinkmbox;	int rc, clrlaerr = 0;	if (unlikely(!phba))		return;	if (!(phba->fc_flag & FC_DISC_TMO))		return;	psli = &phba->sli;	spin_lock_irq(phba->host->host_lock);	phba->fc_flag &= ~FC_DISC_TMO;	spin_unlock_irq(phba->host->host_lock);	switch (phba->hba_state) {	case LPFC_LOCAL_CFG_LINK:	/* hba_state is identically LPFC_LOCAL_CFG_LINK while waiting for FAN */		/* FAN timeout */		lpfc_printf_log(phba,				 KERN_WARNING,				 LOG_DISCOVERY,				 "%d:0221 FAN timeout\n",				 phba->brd_no);		/* Forget about FAN, 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);		break;	case LPFC_FLOGI:	/* hba_state is identically LPFC_FLOGI while waiting for FLOGI cmpl */		/* Initial FLOGI timeout */		lpfc_printf_log(phba,				 KERN_ERR,				 LOG_DISCOVERY,				 "%d:0222 Initial FLOGI timeout\n",				 phba->brd_no);		/* Assume no Fabric and go on with discovery.		 * Check for outstanding ELS FLOGI to abort.		 */		/* FLOGI failed, so just use loop map to make discovery list */		lpfc_disc_list_loopmap(phba);		/* Start discovery */		lpfc_disc_start(phba);		break;	case LPFC_FABRIC_CFG_LINK:	/* hba_state is identically LPFC_FABRIC_CFG_LINK while waiting for	   NameServer login */		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,				"%d:0223 Timeout while waiting for NameServer "				"login\n", phba->brd_no);		/* Next look for NameServer ndlp */		ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID);		if (ndlp)			lpfc_nlp_remove(phba, ndlp);		/* Start discovery */		lpfc_disc_start(phba);		break;	case LPFC_NS_QRY:	/* Check for wait for NameServer Rsp timeout */		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,				"%d:0224 NameServer Query timeout "				"Data: x%x x%x\n",				phba->brd_no,				phba->fc_ns_retry, LPFC_MAX_NS_RETRY);		ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED,								NameServer_DID);		if (ndlp) {			if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) {				/* Try it one more time */				rc = lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT);				if (rc == 0)					break;			}			phba->fc_ns_retry = 0;		}		/* Nothing to authenticate, so CLEAR_LA right now */		clearlambox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);		if (!clearlambox) {			clrlaerr = 1;			lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,					"%d:0226 Device Discovery "					"completion error\n",					phba->brd_no);			phba->hba_state = LPFC_HBA_ERROR;			break;		}		phba->hba_state = LPFC_CLEAR_LA;		lpfc_clear_la(phba, clearlambox);		clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la;		rc = lpfc_sli_issue_mbox(phba, clearlambox,					 (MBX_NOWAIT | MBX_STOP_IOCB));		if (rc == MBX_NOT_FINISHED) {			mempool_free(clearlambox, phba->mbox_mem_pool);			clrlaerr = 1;			break;		}		/* Setup and issue mailbox INITIALIZE LINK command */		initlinkmbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);		if (!initlinkmbox) {			lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,					"%d:0226 Device Discovery "					"completion error\n",					phba->brd_no);			phba->hba_state = LPFC_HBA_ERROR;			break;		}		lpfc_linkdown(phba);		lpfc_init_link(phba, initlinkmbox, phba->cfg_topology,			       phba->cfg_link_speed);		initlinkmbox->mb.un.varInitLnk.lipsr_AL_PA = 0;		rc = lpfc_sli_issue_mbox(phba, initlinkmbox,					 (MBX_NOWAIT | MBX_STOP_IOCB));		if (rc == MBX_NOT_FINISHED)			mempool_free(initlinkmbox, phba->mbox_mem_pool);		break;	case LPFC_DISC_AUTH:	/* Node Authentication timeout */		lpfc_printf_log(phba,				 KERN_ERR,				 LOG_DISCOVERY,				 "%d:0227 Node Authentication timeout\n",				 phba->brd_no);		lpfc_disc_flush_list(phba);		clearlambox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);		if (!clearlambox) {			clrlaerr = 1;			lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,					"%d:0226 Device Discovery "					"completion error\n",					phba->brd_no);			phba->hba_state = LPFC_HBA_ERROR;			break;		}		phba->hba_state = LPFC_CLEAR_LA;		lpfc_clear_la(phba, clearlambox);		clearlambox->mbox_cmpl = lpfc_mbx_cmpl_clear_la;		rc = lpfc_sli_issue_mbox(phba, clearlambox,					 (MBX_NOWAIT | MBX_STOP_IOCB));		if (rc == MBX_NOT_FINISHED) {			mempool_free(clearlambox, phba->mbox_mem_pool);			clrlaerr = 1;		}		break;	case LPFC_CLEAR_LA:	/* CLEAR LA timeout */		lpfc_printf_log(phba,				 KERN_ERR,				 LOG_DISCOVERY,				 "%d:0228 CLEAR LA timeout\n",				 phba->brd_no);		clrlaerr = 1;		break;	case LPFC_HBA_READY:		if (phba->fc_flag & FC_RSCN_MODE) {			lpfc_printf_log(phba,					KERN_ERR,					LOG_DISCOVERY,					"%d:0231 RSCN timeout Data: x%x x%x\n",					phba->brd_no,					phba->fc_ns_retry, LPFC_MAX_NS_RETRY);			/* Cleanup any outstanding ELS commands */			lpfc_els_flush_cmd(phba);			lpfc_els_flush_rscn(phba);			lpfc_disc_flush_list(phba);		}		break;	}	if (clrlaerr) {		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;	}	return;}static voidlpfc_nodev_timeout(unsigned long ptr){	struct lpfc_hba *phba;	struct lpfc_nodelist *ndlp;	unsigned long iflag;	struct lpfc_work_evt  *evtp;	ndlp = (struct lpfc_nodelist *)ptr;	phba = ndlp->nlp_phba;	evtp = &ndlp->nodev_timeout_evt;	spin_lock_irqsave(phba->host->host_lock, iflag);	if (!list_empty(&evtp->evt_listp)) {		spin_unlock_irqrestore(phba->host->host_lock, iflag);		return;	}	evtp->evt_arg1  = ndlp;	evtp->evt       = LPFC_EVT_NODEV_TMO;	list_add_tail(&evtp->evt_listp, &phba->work_list);	if (phba->work_wait)		wake_up(phba->work_wait);	spin_unlock_irqrestore(phba->host->host_lock, iflag);	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_fdmi_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;	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);	/* Start issuing Fabric-Device Management Interface (FDMI)	 * command to 0xfffffa (FDMI well known port)	 */	if (phba->cfg_fdmi_on == 1) {		lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA);	} else {		/*		 * Delay issuing FDMI command if fdmi-on=2		 * (supporting RPA/hostnmae)		 */		mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60);	}	lpfc_mbuf_free(phba, mp->virt, mp->phys);	kfree(mp);	mempool_free( pmb, phba->mbox_mem_pool);	return;}/* * This routine looks up the ndlp  lists * for the given RPI. If rpi found * it return the node list pointer * else return NULL. */struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi){	struct lpfc_nodelist *ndlp;	struct list_head * lists[]={&phba->fc_nlpunmap_list,				    &phba->fc_nlpmap_list,				    &phba->fc_plogi_list,				    &phba->fc_adisc_list,				    &phba->fc_reglogin_list};	int i;	for (i = 0;

⌨️ 快捷键说明

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