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

📄 lpfc_mbox.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
voidlpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb){	MAILBOX_t *mb;	mb = &pmb->mb;	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));	mb->mbxCommand = MBX_READ_CONFIG;	mb->mbxOwner = OWN_HOST;	return;}/********************************************//*  lpfc_reg_login  Issue a REG_LOGIN       *//*                  mailbox command         *//********************************************/intlpfc_reg_login(struct lpfc_hba * phba,	       uint32_t did, uint8_t * param, LPFC_MBOXQ_t * pmb, uint32_t flag){	uint8_t *sparam;	struct lpfc_dmabuf *mp;	MAILBOX_t *mb;	struct lpfc_sli *psli;	psli = &phba->sli;	mb = &pmb->mb;	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));	mb->un.varRegLogin.rpi = 0;	mb->un.varRegLogin.did = did;	mb->un.varWords[30] = flag;	/* Set flag to issue action on cmpl */	mb->mbxOwner = OWN_HOST;	/* Get a buffer to hold NPorts Service Parameters */	if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == NULL) ||	    ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) {		kfree(mp);		mb->mbxCommand = MBX_REG_LOGIN64;		/* REG_LOGIN: no buffers */		lpfc_printf_log(phba,			       KERN_WARNING,			       LOG_MBOX,			       "%d:0302 REG_LOGIN: no buffers Data x%x x%x\n",			       phba->brd_no,			       (uint32_t) did, (uint32_t) flag);		return (1);	}	INIT_LIST_HEAD(&mp->list);	sparam = mp->virt;	/* Copy param's into a new buffer */	memcpy(sparam, param, sizeof (struct serv_parm));	/* save address for completion */	pmb->context1 = (uint8_t *) mp;	mb->mbxCommand = MBX_REG_LOGIN64;	mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);	mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys);	mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys);	return (0);}/**********************************************//*  lpfc_unreg_login  Issue a UNREG_LOGIN     *//*                    mailbox command         *//**********************************************/voidlpfc_unreg_login(struct lpfc_hba * phba, uint32_t rpi, LPFC_MBOXQ_t * pmb){	MAILBOX_t *mb;	mb = &pmb->mb;	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));	mb->un.varUnregLogin.rpi = (uint16_t) rpi;	mb->un.varUnregLogin.rsvd1 = 0;	mb->mbxCommand = MBX_UNREG_LOGIN;	mb->mbxOwner = OWN_HOST;	return;}static voidlpfc_config_pcb_setup(struct lpfc_hba * phba){	struct lpfc_sli *psli = &phba->sli;	struct lpfc_sli_ring *pring;	PCB_t *pcbp = &phba->slim2p->pcb;	dma_addr_t pdma_addr;	uint32_t offset;	uint32_t iocbCnt;	int i;	pcbp->maxRing = (psli->num_rings - 1);	iocbCnt = 0;	for (i = 0; i < psli->num_rings; i++) {		pring = &psli->ring[i];		/* A ring MUST have both cmd and rsp entries defined to be		   valid */		if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) {			pcbp->rdsc[i].cmdEntries = 0;			pcbp->rdsc[i].rspEntries = 0;			pcbp->rdsc[i].cmdAddrHigh = 0;			pcbp->rdsc[i].rspAddrHigh = 0;			pcbp->rdsc[i].cmdAddrLow = 0;			pcbp->rdsc[i].rspAddrLow = 0;			pring->cmdringaddr = NULL;			pring->rspringaddr = NULL;			continue;		}		/* Command ring setup for ring */		pring->cmdringaddr =		    (void *)&phba->slim2p->IOCBs[iocbCnt];		pcbp->rdsc[i].cmdEntries = pring->numCiocb;		offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -			 (uint8_t *)phba->slim2p;		pdma_addr = phba->slim2p_mapping + offset;		pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr);		pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr);		iocbCnt += pring->numCiocb;		/* Response ring setup for ring */		pring->rspringaddr =		    (void *)&phba->slim2p->IOCBs[iocbCnt];		pcbp->rdsc[i].rspEntries = pring->numRiocb;		offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -			 (uint8_t *)phba->slim2p;		pdma_addr = phba->slim2p_mapping + offset;		pcbp->rdsc[i].rspAddrHigh = putPaddrHigh(pdma_addr);		pcbp->rdsc[i].rspAddrLow = putPaddrLow(pdma_addr);		iocbCnt += pring->numRiocb;	}}voidlpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb){	MAILBOX_t *mb;	mb = &pmb->mb;	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));	mb->un.varRdRev.cv = 1;	mb->mbxCommand = MBX_READ_REV;	mb->mbxOwner = OWN_HOST;	return;}voidlpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb){	int i;	MAILBOX_t *mb = &pmb->mb;	struct lpfc_sli *psli;	struct lpfc_sli_ring *pring;	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));	mb->un.varCfgRing.ring = ring;	mb->un.varCfgRing.maxOrigXchg = 0;	mb->un.varCfgRing.maxRespXchg = 0;	mb->un.varCfgRing.recvNotify = 1;	psli = &phba->sli;	pring = &psli->ring[ring];	mb->un.varCfgRing.numMask = pring->num_mask;	mb->mbxCommand = MBX_CONFIG_RING;	mb->mbxOwner = OWN_HOST;	/* Is this ring configured for a specific profile */	if (pring->prt[0].profile) {		mb->un.varCfgRing.profile = pring->prt[0].profile;		return;	}	/* Otherwise we setup specific rctl / type masks for this ring */	for (i = 0; i < pring->num_mask; i++) {		mb->un.varCfgRing.rrRegs[i].rval = pring->prt[i].rctl;		if (mb->un.varCfgRing.rrRegs[i].rval != FC_ELS_REQ)			mb->un.varCfgRing.rrRegs[i].rmask = 0xff;		else			mb->un.varCfgRing.rrRegs[i].rmask = 0xfe;		mb->un.varCfgRing.rrRegs[i].tval = pring->prt[i].type;		mb->un.varCfgRing.rrRegs[i].tmask = 0xff;	}	return;}voidlpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb){	MAILBOX_t *mb = &pmb->mb;	dma_addr_t pdma_addr;	uint32_t bar_low, bar_high;	size_t offset;	struct lpfc_hgp hgp;	void __iomem *to_slim;	int i;	memset(pmb, 0, sizeof(LPFC_MBOXQ_t));	mb->mbxCommand = MBX_CONFIG_PORT;	mb->mbxOwner = OWN_HOST;	mb->un.varCfgPort.pcbLen = sizeof(PCB_t);	offset = (uint8_t *)&phba->slim2p->pcb - (uint8_t *)phba->slim2p;	pdma_addr = phba->slim2p_mapping + offset;	mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr);	mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr);	/* Now setup pcb */	phba->slim2p->pcb.type = TYPE_NATIVE_SLI2;	phba->slim2p->pcb.feature = FEATURE_INITIAL_SLI2;	/* Setup Mailbox pointers */	phba->slim2p->pcb.mailBoxSize = sizeof(MAILBOX_t);	offset = (uint8_t *)&phba->slim2p->mbx - (uint8_t *)phba->slim2p;	pdma_addr = phba->slim2p_mapping + offset;	phba->slim2p->pcb.mbAddrHigh = putPaddrHigh(pdma_addr);	phba->slim2p->pcb.mbAddrLow = putPaddrLow(pdma_addr);	/*	 * Setup Host Group ring pointer.	 *	 * For efficiency reasons, the ring get/put pointers can be	 * placed in adapter memory (SLIM) rather than in host memory.	 * This allows firmware to avoid PCI reads/writes when updating	 * and checking pointers.	 *	 * The firmware recognizes the use of SLIM memory by comparing	 * the address of the get/put pointers structure with that of	 * the SLIM BAR (BAR0).	 *	 * Caution: be sure to use the PCI config space value of BAR0/BAR1	 * (the hardware's view of the base address), not the OS's	 * value of pci_resource_start() as the OS value may be a cookie	 * for ioremap/iomap.	 */	pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_0, &bar_low);	pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_1, &bar_high);	/* mask off BAR0's flag bits 0 - 3 */	phba->slim2p->pcb.hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) +					(SLIMOFF*sizeof(uint32_t));	if (bar_low & PCI_BASE_ADDRESS_MEM_TYPE_64)		phba->slim2p->pcb.hgpAddrHigh = bar_high;	else		phba->slim2p->pcb.hgpAddrHigh = 0;	/* write HGP data to SLIM at the required longword offset */	memset(&hgp, 0, sizeof(struct lpfc_hgp));	to_slim = phba->MBslimaddr + (SLIMOFF*sizeof (uint32_t));	for (i=0; i < phba->sli.num_rings; i++) {		lpfc_memcpy_to_slim(to_slim, &hgp, sizeof(struct lpfc_hgp));		to_slim += sizeof (struct lpfc_hgp);	}	/* Setup Port Group ring pointer */	offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port -		 (uint8_t *)phba->slim2p;	pdma_addr = phba->slim2p_mapping + offset;	phba->slim2p->pcb.pgpAddrHigh = putPaddrHigh(pdma_addr);	phba->slim2p->pcb.pgpAddrLow = putPaddrLow(pdma_addr);	/* Use callback routine to setp rings in the pcb */	lpfc_config_pcb_setup(phba);	/* special handling for LC HBAs */	if (lpfc_is_LC_HBA(phba->pcidev->device)) {		uint32_t hbainit[5];		lpfc_hba_init(phba, hbainit);		memcpy(&mb->un.varCfgPort.hbainit, hbainit, 20);	}	/* Swap PCB if needed */	lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb,								sizeof (PCB_t));	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,		        "%d:0405 Service Level Interface (SLI) 2 selected\n",		        phba->brd_no);}voidlpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq){	struct lpfc_sli *psli;	psli = &phba->sli;	list_add_tail(&mbq->list, &psli->mboxq);	psli->mboxq_cnt++;	return;}LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba * phba){	LPFC_MBOXQ_t *mbq = NULL;	struct lpfc_sli *psli = &phba->sli;	list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t,			 list);	if (mbq) {		psli->mboxq_cnt--;	}	return mbq;}

⌨️ 快捷键说明

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