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 + -
显示快捷键?