fore_buffer.c

来自「基于组件方式开发操作系统的OSKIT源代码」· C语言 代码 · 共 773 行 · 第 1/2 页

C
773
字号
/* * * =================================== * HARP  |  Host ATM Research Platform * =================================== * * * This Host ATM Research Platform ("HARP") file (the "Software") is * made available by Network Computing Services, Inc. ("NetworkCS") * "AS IS".  NetworkCS does not provide maintenance, improvements or * support of any kind. * * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED, * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE. * In no event shall NetworkCS be responsible for any damages, including * but not limited to consequential damages, arising from or relating to * any use of the Software or related support. * * Copyright 1994-1998 Network Computing Services, Inc. * * Copies of this Software may be made, however, the above copyright * notice must be reproduced on all copies. * *	@(#) $Id: fore_buffer.c,v 1.2 1998/10/31 20:06:52 phk Exp $ * *//* * FORE Systems 200-Series Adapter Support * --------------------------------------- * * Buffer Supply queue management * */#include <dev/hfa/fore_include.h>#ifndef lint__RCSID("@(#) $Id: fore_buffer.c,v 1.2 1998/10/31 20:06:52 phk Exp $");#endif/* * Local functions */static void	fore_buf_drain __P((Fore_unit *));static void	fore_buf_supply_1s __P((Fore_unit *));static void	fore_buf_supply_1l __P((Fore_unit *));/* * Allocate Buffer Supply Queues Data Structures * * Here we are allocating memory for both Strategy 1 Small and Large * structures contiguously. * * Arguments: *	fup		pointer to device unit structure * * Returns: *	0		allocations successful *	else		allocation failed */intfore_buf_allocate(fup)	Fore_unit	*fup;{	caddr_t		memp;	/*	 * Allocate non-cacheable memory for buffer supply status words	 */	memp = atm_dev_alloc(			sizeof(Q_status) * (BUF1_SM_QUELEN + BUF1_LG_QUELEN),			QSTAT_ALIGN, ATM_DEV_NONCACHE);	if (memp == NULL) {		return (1);	}	fup->fu_buf1s_stat = (Q_status *) memp;	fup->fu_buf1l_stat = ((Q_status *) memp) + BUF1_SM_QUELEN;	memp = DMA_GET_ADDR(fup->fu_buf1s_stat,			sizeof(Q_status) * (BUF1_SM_QUELEN + BUF1_LG_QUELEN),			QSTAT_ALIGN, ATM_DEV_NONCACHE);	if (memp == NULL) {		return (1);	}	fup->fu_buf1s_statd = (Q_status *) memp;	fup->fu_buf1l_statd = ((Q_status *) memp) + BUF1_SM_QUELEN;	/*	 * Allocate memory for buffer supply descriptors	 */	memp = atm_dev_alloc(sizeof(Buf_descr) * 			((BUF1_SM_QUELEN * BUF1_SM_ENTSIZE) + 			 (BUF1_LG_QUELEN * BUF1_LG_ENTSIZE)),			BUF_DESCR_ALIGN, 0);	if (memp == NULL) {		return (1);	}	fup->fu_buf1s_desc = (Buf_descr *) memp;	fup->fu_buf1l_desc = ((Buf_descr *) memp) + 			(BUF1_SM_QUELEN * BUF1_SM_ENTSIZE);	memp = DMA_GET_ADDR(fup->fu_buf1s_desc, sizeof(Buf_descr) *			((BUF1_SM_QUELEN * BUF1_SM_ENTSIZE) + 			 (BUF1_LG_QUELEN * BUF1_LG_ENTSIZE)),			BUF_DESCR_ALIGN, 0);	if (memp == NULL) {		return (1);	}	fup->fu_buf1s_descd = (Buf_descr *) memp;	fup->fu_buf1l_descd = ((Buf_descr *) memp) + 			(BUF1_SM_QUELEN * BUF1_SM_ENTSIZE);	return (0);}/* * Buffer Supply Queues Initialization * * Allocate and initialize the host-resident buffer supply queue structures * and then initialize the CP-resident queue structures. *  * Called at interrupt level. * * Arguments: *	fup		pointer to device unit structure * * Returns: *	none */voidfore_buf_initialize(fup)	Fore_unit	*fup;{	Aali		*aap = fup->fu_aali;	Buf_queue	*cqp;	H_buf_queue	*hbp;	Buf_descr	*bdp;	Buf_descr	*bdp_dma;	Q_status	*qsp;	Q_status	*qsp_dma;	int		i;	/*	 * Initialize Strategy 1 Small Queues	 */	/*	 * Point to CP-resident buffer supply queue	 */	cqp = (Buf_queue *)(fup->fu_ram + CP_READ(aap->aali_buf1s_q));	/*	 * Point to host-resident buffer supply queue structures	 */	hbp = fup->fu_buf1s_q;	qsp = fup->fu_buf1s_stat;	qsp_dma = fup->fu_buf1s_statd;	bdp = fup->fu_buf1s_desc;	bdp_dma = fup->fu_buf1s_descd;	/*	 * Loop thru all queue entries and do whatever needs doing	 */	for (i = 0; i < BUF1_SM_QUELEN; i++) {		/*		 * Set queue status word to free		 */		*qsp = QSTAT_FREE;		/*		 * Set up host queue entry and link into ring		 */		hbp->hbq_cpelem = cqp;		hbp->hbq_status = qsp;		hbp->hbq_descr = bdp;		hbp->hbq_descr_dma = bdp_dma;		if (i == (BUF1_SM_QUELEN - 1))			hbp->hbq_next = fup->fu_buf1s_q;		else			hbp->hbq_next = hbp + 1;		/*		 * Now let the CP into the game		 */		cqp->cq_status = (CP_dma) CP_WRITE(qsp_dma);		/*		 * Bump all queue pointers		 */		hbp++;		qsp++;		qsp_dma++;		bdp += BUF1_SM_ENTSIZE;		bdp_dma += BUF1_SM_ENTSIZE;		cqp++;	}	/*	 * Initialize queue pointers	 */	fup->fu_buf1s_head = fup->fu_buf1s_tail = fup->fu_buf1s_q;	/*	 * Initialize Strategy 1 Large Queues	 */	/*	 * Point to CP-resident buffer supply queue	 */	cqp = (Buf_queue *)(fup->fu_ram + CP_READ(aap->aali_buf1l_q));	/*	 * Point to host-resident buffer supply queue structures	 */	hbp = fup->fu_buf1l_q;	qsp = fup->fu_buf1l_stat;	qsp_dma = fup->fu_buf1l_statd;	bdp = fup->fu_buf1l_desc;	bdp_dma = fup->fu_buf1l_descd;	/*	 * Loop thru all queue entries and do whatever needs doing	 */	for (i = 0; i < BUF1_LG_QUELEN; i++) {		/*		 * Set queue status word to free		 */		*qsp = QSTAT_FREE;		/*		 * Set up host queue entry and link into ring		 */		hbp->hbq_cpelem = cqp;		hbp->hbq_status = qsp;		hbp->hbq_descr = bdp;		hbp->hbq_descr_dma = bdp_dma;		if (i == (BUF1_LG_QUELEN - 1))			hbp->hbq_next = fup->fu_buf1l_q;		else			hbp->hbq_next = hbp + 1;		/*		 * Now let the CP into the game		 */		cqp->cq_status = (CP_dma) CP_WRITE(qsp_dma);		/*		 * Bump all queue pointers		 */		hbp++;		qsp++;		qsp_dma++;		bdp += BUF1_LG_ENTSIZE;		bdp_dma += BUF1_LG_ENTSIZE;		cqp++;	}	/*	 * Initialize queue pointers	 */	fup->fu_buf1l_head = fup->fu_buf1l_tail = fup->fu_buf1l_q;	return;}/* * Supply Buffers to CP * * This function will resupply the CP with buffers to be used to * store incoming data. * * May be called in interrupt state. * Must be called with interrupts locked out. * * Arguments: *	fup		pointer to device unit structure * * Returns: *	none */voidfore_buf_supply(fup)	Fore_unit	*fup;{	/*	 * First, clean out the supply queues	 */	fore_buf_drain(fup);	/*	 * Then, supply the buffers for each queue	 */	fore_buf_supply_1s(fup);	fore_buf_supply_1l(fup);	return;}/* * Supply Strategy 1 Small Buffers to CP * * May be called in interrupt state. * Must be called with interrupts locked out. * * Arguments: *	fup		pointer to device unit structure * * Returns: *	none */static voidfore_buf_supply_1s(fup)	Fore_unit	*fup;{	H_buf_queue	*hbp;	Buf_queue	*cqp;	Buf_descr	*bdp;	Buf_handle	*bhp;	KBuffer		*m;	int		nvcc, nbuf, i;	/*	 * Figure out how many buffers we should be giving to the CP.	 * We're basing this calculation on the current number of open	 * VCCs thru this device, with certain minimum and maximum values	 * enforced.  This will then allow us to figure out how many more 	 * buffers we need to supply to the CP.  This will be rounded up 	 * to fill a supply queue entry.	 */	nvcc = MAX(fup->fu_open_vcc, BUF_MIN_VCC);	nbuf = nvcc * 4;	nbuf = MIN(nbuf, BUF1_SM_CPPOOL);	nbuf -= fup->fu_buf1s_cnt;	nbuf = roundup(nbuf, BUF1_SM_ENTSIZE);	/*	 * OK, now supply the buffers to the CP	 */	while (nbuf > 0) {		/*		 * Acquire a supply queue entry		 */		hbp = fup->fu_buf1s_tail;		if (!((*hbp->hbq_status) & QSTAT_FREE))			break;		bdp = hbp->hbq_descr;		/*		 * Get a buffer for each descriptor in the queue entry		 */		for (i = 0; i < BUF1_SM_ENTSIZE; i++, bdp++) {			caddr_t		cp;			/*			 * Get a small buffer			 */			KB_ALLOCPKT(m, BUF1_SM_SIZE, KB_F_NOWAIT, KB_T_DATA);			if (m == 0) {				break;			}			KB_HEADSET(m, BUF1_SM_DOFF);			/*			 * Point to buffer handle structure			 */			bhp = (Buf_handle *)((caddr_t)m + BUF1_SM_HOFF);			bhp->bh_type = BHT_S1_SMALL;			/*			 * Setup buffer descriptor			 */			bdp->bsd_handle = bhp;			KB_DATASTART(m, cp, caddr_t);			bhp->bh_dma = bdp->bsd_buffer = (H_dma) DMA_GET_ADDR(

⌨️ 快捷键说明

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