fore_buffer.c
来自「基于组件方式开发操作系统的OSKIT源代码」· C语言 代码 · 共 773 行 · 第 1/2 页
C
773 行
cp, BUF1_SM_SIZE, BUF_DATA_ALIGN, 0); if (bdp->bsd_buffer == NULL) { /* * Unable to assign dma address - free up * this descriptor's buffer */ fup->fu_stats->st_drv.drv_bf_segdma++; KB_FREEALL(m); break; } /* * All set, so queue buffer (handle) */ ENQUEUE(bhp, Buf_handle, bh_qelem, fup->fu_buf1s_bq); } /* * If we we're not able to fill all the descriptors for * an entry, free up what's been partially built */ if (i != BUF1_SM_ENTSIZE) { /* * Clean up each used descriptor */ for (bdp = hbp->hbq_descr; i; i--, bdp++) { bhp = bdp->bsd_handle; DEQUEUE(bhp, Buf_handle, bh_qelem, fup->fu_buf1s_bq); m = (KBuffer *) ((caddr_t)bhp - BUF1_SM_HOFF); KB_FREEALL(m); } break; } /* * Finally, we've got an entry ready for the CP. * So claim the host queue entry and setup the CP-resident * queue entry. The CP will (potentially) grab the supplied * buffers when the descriptor pointer is set. */ fup->fu_buf1s_tail = hbp->hbq_next; (*hbp->hbq_status) = QSTAT_PENDING; cqp = hbp->hbq_cpelem; cqp->cq_descr = (CP_dma) CP_WRITE((u_long)hbp->hbq_descr_dma); /* * Update counters, etc for supplied buffers */ fup->fu_buf1s_cnt += BUF1_SM_ENTSIZE; nbuf -= BUF1_SM_ENTSIZE; } return;}/* * Supply Strategy 1 Large 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_1l(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 * RECV_MAX_SEGS; nbuf = MIN(nbuf, BUF1_LG_CPPOOL); nbuf -= fup->fu_buf1l_cnt; nbuf = roundup(nbuf, BUF1_LG_ENTSIZE); /* * OK, now supply the buffers to the CP */ while (nbuf > 0) { /* * Acquire a supply queue entry */ hbp = fup->fu_buf1l_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_LG_ENTSIZE; i++, bdp++) { caddr_t cp; /* * Get a cluster buffer */ KB_ALLOCEXT(m, BUF1_LG_SIZE, KB_F_NOWAIT, KB_T_DATA); if (m == 0) { break; } KB_HEADSET(m, BUF1_LG_DOFF); /* * Point to buffer handle structure */ bhp = (Buf_handle *)((caddr_t)m + BUF1_LG_HOFF); bhp->bh_type = BHT_S1_LARGE; /* * Setup buffer descriptor */ bdp->bsd_handle = bhp; KB_DATASTART(m, cp, caddr_t); bhp->bh_dma = bdp->bsd_buffer = (H_dma) DMA_GET_ADDR( cp, BUF1_LG_SIZE, BUF_DATA_ALIGN, 0); if (bdp->bsd_buffer == NULL) { /* * Unable to assign dma address - free up * this descriptor's buffer */ fup->fu_stats->st_drv.drv_bf_segdma++; KB_FREEALL(m); break; } /* * All set, so queue buffer (handle) */ ENQUEUE(bhp, Buf_handle, bh_qelem, fup->fu_buf1l_bq); } /* * If we we're not able to fill all the descriptors for * an entry, free up what's been partially built */ if (i != BUF1_LG_ENTSIZE) { /* * Clean up each used descriptor */ for (bdp = hbp->hbq_descr; i; i--, bdp++) { bhp = bdp->bsd_handle; DEQUEUE(bhp, Buf_handle, bh_qelem, fup->fu_buf1l_bq); m = (KBuffer *) ((caddr_t)bhp - BUF1_LG_HOFF); KB_FREEALL(m); } break; } /* * Finally, we've got an entry ready for the CP. * So claim the host queue entry and setup the CP-resident * queue entry. The CP will (potentially) grab the supplied * buffers when the descriptor pointer is set. */ fup->fu_buf1l_tail = hbp->hbq_next; (*hbp->hbq_status) = QSTAT_PENDING; cqp = hbp->hbq_cpelem; cqp->cq_descr = (CP_dma) CP_WRITE((u_long)hbp->hbq_descr_dma); /* * Update counters, etc for supplied buffers */ fup->fu_buf1l_cnt += BUF1_LG_ENTSIZE; nbuf -= BUF1_LG_ENTSIZE; } return;}/* * Drain Buffer Supply Queues * * This function will free all completed entries at the head of each * buffer supply queue. Since we consider the CP to "own" the buffers * once we put them on a supply queue and since a completed supply queue * entry is only telling us that the CP has accepted the buffers that we * gave to it, there's not much to do here. * * 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_drain(fup) Fore_unit *fup;{ H_buf_queue *hbp; /* * Drain Strategy 1 Small Queue */ /* * Process each completed entry */ while (*fup->fu_buf1s_head->hbq_status & QSTAT_COMPLETED) { hbp = fup->fu_buf1s_head; if (*hbp->hbq_status & QSTAT_ERROR) { /* * XXX - what does this mean??? */ log(LOG_ERR, "fore_buf_drain: buf1s queue error\n"); } /* * Mark this entry free for use and bump head pointer * to the next entry in the queue */ *hbp->hbq_status = QSTAT_FREE; fup->fu_buf1s_head = hbp->hbq_next; } /* * Drain Strategy 1 Large Queue */ /* * Process each completed entry */ while (*fup->fu_buf1l_head->hbq_status & QSTAT_COMPLETED) { hbp = fup->fu_buf1l_head; if (*hbp->hbq_status & QSTAT_ERROR) { /* * XXX - what does this mean??? */ log(LOG_ERR, "fore_buf_drain: buf1l queue error\n"); } /* * Mark this entry free for use and bump head pointer * to the next entry in the queue */ *hbp->hbq_status = QSTAT_FREE; fup->fu_buf1l_head = hbp->hbq_next; } return;}/* * Free Buffer Supply Queue Data Structures * * Arguments: * fup pointer to device unit structure * * Returns: * none */voidfore_buf_free(fup) Fore_unit *fup;{ Buf_handle *bhp; KBuffer *m; /* * Free any previously supplied and not returned buffers */ if (fup->fu_flags & CUF_INITED) { /* * Run through Strategy 1 Small queue */ while (bhp = Q_HEAD(fup->fu_buf1s_bq, Buf_handle)) { caddr_t cp; /* * Back off to buffer */ m = (KBuffer *)((caddr_t)bhp - BUF1_SM_HOFF); /* * Dequeue handle and free buffer */ DEQUEUE(bhp, Buf_handle, bh_qelem, fup->fu_buf1s_bq); KB_DATASTART(m, cp, caddr_t); DMA_FREE_ADDR(cp, bhp->bh_dma, BUF1_SM_SIZE, 0); KB_FREEALL(m); } /* * Run through Strategy 1 Large queue */ while (bhp = Q_HEAD(fup->fu_buf1l_bq, Buf_handle)) { caddr_t cp; /* * Back off to buffer */ m = (KBuffer *)((caddr_t)bhp - BUF1_LG_HOFF); /* * Dequeue handle and free buffer */ DEQUEUE(bhp, Buf_handle, bh_qelem, fup->fu_buf1l_bq); KB_DATASTART(m, cp, caddr_t); DMA_FREE_ADDR(cp, bhp->bh_dma, BUF1_LG_SIZE, 0); KB_FREEALL(m); } } /* * Free the status words */ if (fup->fu_buf1s_stat) { if (fup->fu_buf1s_statd) { DMA_FREE_ADDR(fup->fu_buf1s_stat, fup->fu_buf1s_statd, sizeof(Q_status) * (BUF1_SM_QUELEN + BUF1_LG_QUELEN), ATM_DEV_NONCACHE); } atm_dev_free((void *)fup->fu_buf1s_stat); fup->fu_buf1s_stat = NULL; fup->fu_buf1s_statd = NULL; fup->fu_buf1l_stat = NULL; fup->fu_buf1l_statd = NULL; } /* * Free the transmit descriptors */ if (fup->fu_buf1s_desc) { if (fup->fu_buf1s_descd) { DMA_FREE_ADDR(fup->fu_buf1s_desc, fup->fu_buf1s_descd, sizeof(Buf_descr) * ((BUF1_SM_QUELEN * BUF1_SM_ENTSIZE) + (BUF1_LG_QUELEN * BUF1_LG_ENTSIZE)), 0); } atm_dev_free(fup->fu_buf1s_desc); fup->fu_buf1s_desc = NULL; fup->fu_buf1s_descd = NULL; fup->fu_buf1l_desc = NULL; fup->fu_buf1l_descd = NULL; } return;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?