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

📄 lpfc_init.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	struct lpfc_iocbq *iocb;	struct lpfc_dmabuf *mp1, *mp2;	cnt += pring->missbufcnt;	/* While there are buffers to post */	while (cnt > 0) {		/* Allocate buffer for  command iocb */		spin_lock_irq(phba->host->host_lock);		iocb = lpfc_sli_get_iocbq(phba);		spin_unlock_irq(phba->host->host_lock);		if (iocb == NULL) {			pring->missbufcnt = cnt;			return cnt;		}		icmd = &iocb->iocb;		/* 2 buffers can be posted per command */		/* Allocate buffer to post */		mp1 = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);		if (mp1)		    mp1->virt = lpfc_mbuf_alloc(phba, MEM_PRI,						&mp1->phys);		if (mp1 == 0 || mp1->virt == 0) {			kfree(mp1);			spin_lock_irq(phba->host->host_lock);			lpfc_sli_release_iocbq(phba, iocb);			spin_unlock_irq(phba->host->host_lock);			pring->missbufcnt = cnt;			return cnt;		}		INIT_LIST_HEAD(&mp1->list);		/* Allocate buffer to post */		if (cnt > 1) {			mp2 = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);			if (mp2)				mp2->virt = lpfc_mbuf_alloc(phba, MEM_PRI,							    &mp2->phys);			if (mp2 == 0 || mp2->virt == 0) {				kfree(mp2);				lpfc_mbuf_free(phba, mp1->virt, mp1->phys);				kfree(mp1);				spin_lock_irq(phba->host->host_lock);				lpfc_sli_release_iocbq(phba, iocb);				spin_unlock_irq(phba->host->host_lock);				pring->missbufcnt = cnt;				return cnt;			}			INIT_LIST_HEAD(&mp2->list);		} else {			mp2 = NULL;		}		icmd->un.cont64[0].addrHigh = putPaddrHigh(mp1->phys);		icmd->un.cont64[0].addrLow = putPaddrLow(mp1->phys);		icmd->un.cont64[0].tus.f.bdeSize = FCELSSIZE;		icmd->ulpBdeCount = 1;		cnt--;		if (mp2) {			icmd->un.cont64[1].addrHigh = putPaddrHigh(mp2->phys);			icmd->un.cont64[1].addrLow = putPaddrLow(mp2->phys);			icmd->un.cont64[1].tus.f.bdeSize = FCELSSIZE;			cnt--;			icmd->ulpBdeCount = 2;		}		icmd->ulpCommand = CMD_QUE_RING_BUF64_CN;		icmd->ulpLe = 1;		spin_lock_irq(phba->host->host_lock);		if (lpfc_sli_issue_iocb(phba, pring, iocb, 0) == IOCB_ERROR) {			lpfc_mbuf_free(phba, mp1->virt, mp1->phys);			kfree(mp1);			cnt++;			if (mp2) {				lpfc_mbuf_free(phba, mp2->virt, mp2->phys);				kfree(mp2);				cnt++;			}			lpfc_sli_release_iocbq(phba, iocb);			pring->missbufcnt = cnt;			spin_unlock_irq(phba->host->host_lock);			return cnt;		}		spin_unlock_irq(phba->host->host_lock);		lpfc_sli_ringpostbuf_put(phba, pring, mp1);		if (mp2) {			lpfc_sli_ringpostbuf_put(phba, pring, mp2);		}	}	pring->missbufcnt = 0;	return 0;}/************************************************************************//*                                                                      *//*   lpfc_post_rcv_buf                                                  *//*   This routine post initial rcv buffers to the configured rings      *//*                                                                      *//************************************************************************/static intlpfc_post_rcv_buf(struct lpfc_hba * phba){	struct lpfc_sli *psli = &phba->sli;	/* Ring 0, ELS / CT buffers */	lpfc_post_buffer(phba, &psli->ring[LPFC_ELS_RING], LPFC_BUF_RING0, 1);	/* Ring 2 - FCP no buffers needed */	return 0;}#define S(N,V) (((V)<<(N))|((V)>>(32-(N))))/************************************************************************//*                                                                      *//*   lpfc_sha_init                                                      *//*                                                                      *//************************************************************************/static voidlpfc_sha_init(uint32_t * HashResultPointer){	HashResultPointer[0] = 0x67452301;	HashResultPointer[1] = 0xEFCDAB89;	HashResultPointer[2] = 0x98BADCFE;	HashResultPointer[3] = 0x10325476;	HashResultPointer[4] = 0xC3D2E1F0;}/************************************************************************//*                                                                      *//*   lpfc_sha_iterate                                                   *//*                                                                      *//************************************************************************/static voidlpfc_sha_iterate(uint32_t * HashResultPointer, uint32_t * HashWorkingPointer){	int t;	uint32_t TEMP;	uint32_t A, B, C, D, E;	t = 16;	do {		HashWorkingPointer[t] =		    S(1,		      HashWorkingPointer[t - 3] ^ HashWorkingPointer[t -								     8] ^		      HashWorkingPointer[t - 14] ^ HashWorkingPointer[t - 16]);	} while (++t <= 79);	t = 0;	A = HashResultPointer[0];	B = HashResultPointer[1];	C = HashResultPointer[2];	D = HashResultPointer[3];	E = HashResultPointer[4];	do {		if (t < 20) {			TEMP = ((B & C) | ((~B) & D)) + 0x5A827999;		} else if (t < 40) {			TEMP = (B ^ C ^ D) + 0x6ED9EBA1;		} else if (t < 60) {			TEMP = ((B & C) | (B & D) | (C & D)) + 0x8F1BBCDC;		} else {			TEMP = (B ^ C ^ D) + 0xCA62C1D6;		}		TEMP += S(5, A) + E + HashWorkingPointer[t];		E = D;		D = C;		C = S(30, B);		B = A;		A = TEMP;	} while (++t <= 79);	HashResultPointer[0] += A;	HashResultPointer[1] += B;	HashResultPointer[2] += C;	HashResultPointer[3] += D;	HashResultPointer[4] += E;}/************************************************************************//*                                                                      *//*   lpfc_challenge_key                                                 *//*                                                                      *//************************************************************************/static voidlpfc_challenge_key(uint32_t * RandomChallenge, uint32_t * HashWorking){	*HashWorking = (*RandomChallenge ^ *HashWorking);}/************************************************************************//*                                                                      *//*   lpfc_hba_init                                                      *//*                                                                      *//************************************************************************/voidlpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit){	int t;	uint32_t *HashWorking;	uint32_t *pwwnn = phba->wwnn;	HashWorking = kmalloc(80 * sizeof(uint32_t), GFP_KERNEL);	if (!HashWorking)		return;	memset(HashWorking, 0, (80 * sizeof(uint32_t)));	HashWorking[0] = HashWorking[78] = *pwwnn++;	HashWorking[1] = HashWorking[79] = *pwwnn;	for (t = 0; t < 7; t++)		lpfc_challenge_key(phba->RandomData + t, HashWorking + t);	lpfc_sha_init(hbainit);	lpfc_sha_iterate(hbainit, HashWorking);	kfree(HashWorking);}static voidlpfc_cleanup(struct lpfc_hba * phba, uint32_t save_bind){	struct lpfc_nodelist *ndlp, *next_ndlp;	/* clean up phba - lpfc specific */	lpfc_can_disctmo(phba);	list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpunmap_list,				nlp_listp) {		lpfc_nlp_remove(phba, ndlp);	}	list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpmap_list,				 nlp_listp) {		lpfc_nlp_remove(phba, ndlp);	}	list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list,				nlp_listp) {		lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);	}	list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list,				nlp_listp) {		lpfc_nlp_remove(phba, ndlp);	}	list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list,				nlp_listp) {		lpfc_nlp_remove(phba, ndlp);	}	list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_reglogin_list,				nlp_listp) {		lpfc_nlp_remove(phba, ndlp);	}	list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_prli_list,				nlp_listp) {		lpfc_nlp_remove(phba, ndlp);	}	list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list,				nlp_listp) {		lpfc_nlp_remove(phba, ndlp);	}	INIT_LIST_HEAD(&phba->fc_nlpmap_list);	INIT_LIST_HEAD(&phba->fc_nlpunmap_list);	INIT_LIST_HEAD(&phba->fc_unused_list);	INIT_LIST_HEAD(&phba->fc_plogi_list);	INIT_LIST_HEAD(&phba->fc_adisc_list);	INIT_LIST_HEAD(&phba->fc_reglogin_list);	INIT_LIST_HEAD(&phba->fc_prli_list);	INIT_LIST_HEAD(&phba->fc_npr_list);	phba->fc_map_cnt   = 0;	phba->fc_unmap_cnt = 0;	phba->fc_plogi_cnt = 0;	phba->fc_adisc_cnt = 0;	phba->fc_reglogin_cnt = 0;	phba->fc_prli_cnt  = 0;	phba->fc_npr_cnt   = 0;	phba->fc_unused_cnt= 0;	return;}static voidlpfc_establish_link_tmo(unsigned long ptr){	struct lpfc_hba *phba = (struct lpfc_hba *)ptr;	unsigned long iflag;	/* Re-establishing Link, timer expired */	lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,			"%d:1300 Re-establishing Link, timer expired "			"Data: x%x x%x\n",			phba->brd_no, phba->fc_flag, phba->hba_state);	spin_lock_irqsave(phba->host->host_lock, iflag);	phba->fc_flag &= ~FC_ESTABLISH_LINK;	spin_unlock_irqrestore(phba->host->host_lock, iflag);}static intlpfc_stop_timer(struct lpfc_hba * phba){	struct lpfc_sli *psli = &phba->sli;	/* Instead of a timer, this has been converted to a	 * deferred procedding list.	 */	while (!list_empty(&phba->freebufList)) {		struct lpfc_dmabuf *mp = NULL;		list_remove_head((&phba->freebufList), mp,				 struct lpfc_dmabuf, list);		if (mp) {			lpfc_mbuf_free(phba, mp->virt, mp->phys);			kfree(mp);		}	}	del_timer_sync(&phba->fc_estabtmo);	del_timer_sync(&phba->fc_disctmo);	del_timer_sync(&phba->fc_fdmitmo);	del_timer_sync(&phba->els_tmofunc);	psli = &phba->sli;	del_timer_sync(&psli->mbox_tmo);	return(1);}intlpfc_online(struct lpfc_hba * phba){	if (!phba)		return 0;	if (!(phba->fc_flag & FC_OFFLINE_MODE))		return 0;	lpfc_printf_log(phba,		       KERN_WARNING,		       LOG_INIT,		       "%d:0458 Bring Adapter online\n",		       phba->brd_no);	if (!lpfc_sli_queue_setup(phba))		return 1;	if (lpfc_sli_hba_setup(phba))	/* Initialize the HBA */		return 1;	spin_lock_irq(phba->host->host_lock);	phba->fc_flag &= ~FC_OFFLINE_MODE;	spin_unlock_irq(phba->host->host_lock);	return 0;}intlpfc_offline(struct lpfc_hba * phba){	struct lpfc_sli_ring *pring;	struct lpfc_sli *psli;	unsigned long iflag;	int i = 0;	if (!phba)		return 0;	if (phba->fc_flag & FC_OFFLINE_MODE)		return 0;	psli = &phba->sli;	pring = &psli->ring[psli->fcp_ring];	lpfc_linkdown(phba);	/* The linkdown event takes 30 seconds to timeout. */	while (pring->txcmplq_cnt) {		mdelay(10);		if (i++ > 3000)			break;	}	/* stop all timers associated with this hba */	lpfc_stop_timer(phba);	phba->work_hba_events = 0;	lpfc_printf_log(phba,		       KERN_WARNING,		       LOG_INIT,		       "%d:0460 Bring Adapter offline\n",		       phba->brd_no);	/* Bring down the SLI Layer and cleanup.  The HBA is offline	   now.  */	lpfc_sli_hba_down(phba);	lpfc_cleanup(phba, 1);	spin_lock_irqsave(phba->host->host_lock, iflag);	phba->fc_flag |= FC_OFFLINE_MODE;	spin_unlock_irqrestore(phba->host->host_lock, iflag);	return 0;}/******************************************************************************* Function name: lpfc_scsi_free** Description: Called from lpfc_pci_remove_one free internal driver resources*******************************************************************************/static intlpfc_scsi_free(struct lpfc_hba * phba){	struct lpfc_scsi_buf *sb, *sb_next;	struct lpfc_iocbq *io, *io_next;	spin_lock_irq(phba->host->host_lock);	/* Release all the lpfc_scsi_bufs maintained by this host. */	list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) {		list_del(&sb->list);		pci_pool_free(phba->lpfc_scsi_dma_buf_pool, sb->data,								sb->dma_handle);		kfree(sb);		phba->total_scsi_bufs--;	}	/* Release all the lpfc_iocbq entries maintained by this host. */	list_for_each_entry_safe(io, io_next, &phba->lpfc_iocb_list, list) {		list_del(&io->list);		kfree(io);		phba->total_iocbq_bufs--;

⌨️ 快捷键说明

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