]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/ncsw/Peripherals/BM/bm_pool.c
Add LLVM openmp trunk r351319 (just before the release_80 branch point)
[FreeBSD/FreeBSD.git] / sys / contrib / ncsw / Peripherals / BM / bm_pool.c
1 /******************************************************************************
2
3  © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
4  All rights reserved.
5
6  This is proprietary source code of Freescale Semiconductor Inc.,
7  and its use is subject to the NetComm Device Drivers EULA.
8  The copyright notice above does not evidence any actual or intended
9  publication of such source code.
10
11  ALTERNATIVELY, redistribution and use in source and binary forms, with
12  or without modification, are permitted provided that the following
13  conditions are met:
14      * Redistributions of source code must retain the above copyright
15        notice, this list of conditions and the following disclaimer.
16      * Redistributions in binary form must reproduce the above copyright
17        notice, this list of conditions and the following disclaimer in the
18        documentation and/or other materials provided with the distribution.
19      * Neither the name of Freescale Semiconductor nor the
20        names of its contributors may be used to endorse or promote products
21        derived from this software without specific prior written permission.
22
23  THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34
35  **************************************************************************/
36 /******************************************************************************
37  @File          bm.c
38
39  @Description   BM
40 *//***************************************************************************/
41 #include "error_ext.h"
42 #include "std_ext.h"
43 #include "string_ext.h"
44 #include "mem_ext.h"
45 #include "core_ext.h"
46
47 #include "bm.h"
48
49
50 #define __ERR_MODULE__  MODULE_BM
51
52
53 /****************************************/
54 /*       static functions               */
55 /****************************************/
56
57 /* (De)Registration of depletion notification callbacks */
58 static void depletion_link(t_BmPool *p_BmPool)
59 {
60     t_BmPortal *p_Portal = (t_BmPortal *)p_BmPool->h_BmPortal;
61
62     NCSW_PLOCK(p_Portal);
63     p_Portal->depletionPoolsTable[p_BmPool->bpid] = p_BmPool;
64     bm_isr_bscn_mask(p_Portal->p_BmPortalLow, (uint8_t)p_BmPool->bpid, 1);
65     PUNLOCK(p_Portal);
66 }
67
68 static void depletion_unlink(t_BmPool *p_BmPool)
69 {
70     t_BmPortal *p_Portal = (t_BmPortal *)p_BmPool->h_BmPortal;
71
72     NCSW_PLOCK(p_Portal);
73     p_Portal->depletionPoolsTable[p_BmPool->bpid] = NULL;
74     bm_isr_bscn_mask(p_Portal->p_BmPortalLow, (uint8_t)p_BmPool->bpid, 0);
75     PUNLOCK(p_Portal);
76 }
77
78 static t_Error BmPoolRelease(t_BmPool *p_BmPool,
79                              t_Handle h_BmPortal,
80                              struct bm_buffer *bufs,
81                              uint8_t num,
82                              uint32_t flags)
83 {
84     ASSERT_COND(num && (num <= 8));
85     if (p_BmPool->flags & BMAN_POOL_FLAG_NO_RELEASE)
86         return ERROR_CODE(E_INVALID_VALUE);
87
88     /* Without stockpile, this API is a pass-through to the h/w operation */
89     if (!(p_BmPool->flags & BMAN_POOL_FLAG_STOCKPILE))
90         return BmPortalRelease(h_BmPortal, p_BmPool->bpid, bufs, num, flags);
91
92     /* This needs some explanation. Adding the given buffers may take the
93      * stockpile over the threshold, but in fact the stockpile may already
94      * *be* over the threshold if a previous release-to-hw attempt had
95      * failed. So we have 3 cases to cover;
96      *   1. we add to the stockpile and don't hit the threshold,
97      *   2. we add to the stockpile, hit the threshold and release-to-hw,
98      *   3. we have to release-to-hw before adding to the stockpile
99      *      (not enough room in the stockpile for case 2).
100      * Our constraints on thresholds guarantee that in case 3, there must be
101      * at least 8 bufs already in the stockpile, so all release-to-hw ops
102      * are for 8 bufs. Despite all this, the API must indicate whether the
103      * given buffers were taken off the caller's hands, irrespective of
104      * whether a release-to-hw was attempted. */
105     while (num)
106     {
107         /* Add buffers to stockpile if they fit */
108         if ((p_BmPool->spFill + num) <= p_BmPool->spMaxBufs)
109         {
110             memcpy(PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill)),
111                    bufs,
112                    sizeof(struct bm_buffer) * num);
113             p_BmPool->spFill += num;
114             num = 0; /* --> will return success no matter what */
115         }
116         else
117         /* Do hw op if hitting the high-water threshold */
118         {
119             t_Error ret = BmPortalRelease(h_BmPortal,
120                                           p_BmPool->bpid,
121                                           (struct bm_buffer *)PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill - p_BmPool->spBufsCmd)),
122                                           p_BmPool->spBufsCmd,
123                                           flags);
124             if (ret)
125                 return (num ? ret : E_OK);
126             p_BmPool->spFill -= p_BmPool->spBufsCmd;
127         }
128     }
129
130     return E_OK;
131 }
132
133 static int BmPoolAcquire(t_BmPool *p_BmPool,t_Handle h_BmPortal,
134             struct bm_buffer *bufs, uint8_t num, uint32_t flags)
135 {
136     ASSERT_COND(IN_RANGE(1, num, 8));
137     if (p_BmPool->flags & BMAN_POOL_FLAG_ONLY_RELEASE)
138         return 0;
139
140     /* Without stockpile, this API is a pass-through to the h/w operation */
141     if (!(p_BmPool->flags & BMAN_POOL_FLAG_STOCKPILE))
142         return BmPortalAcquire(h_BmPortal, p_BmPool->bpid, bufs, num);
143     /* Only need a h/w op if we'll hit the low-water thresh */
144     if (!(flags & BMAN_ACQUIRE_FLAG_STOCKPILE) &&
145             ((p_BmPool->spFill - num) < p_BmPool->spMinBufs))
146     {
147             p_BmPool->spFill += BmPortalAcquire(h_BmPortal,
148                                                p_BmPool->bpid,
149                                                (struct bm_buffer *)PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill)),
150                                                p_BmPool->spBufsCmd);
151     }
152     else if (p_BmPool->spFill < num)
153         return 0;
154     if (!p_BmPool->spFill)
155         return 0;
156     memcpy(bufs,
157            PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill - num)),
158            sizeof(struct bm_buffer) * num);
159     p_BmPool->spFill -= num;
160     return num;
161 }
162
163 static t_Error BmPoolFree(t_BmPool *p_BmPool, bool discardBuffers)
164 {
165     t_Handle    h_BufContext;
166     void        *p_Data;
167
168     ASSERT_COND(p_BmPool);
169
170     if (!p_BmPool->shadowMode)
171     {
172         if (p_BmPool->flags & BMAN_POOL_FLAG_DEPLETION)
173         {
174             depletion_unlink(p_BmPool);
175             BmUnSetPoolThresholds(p_BmPool->h_Bm, p_BmPool->bpid);
176         }
177         while (TRUE)
178         {
179             p_Data = BM_POOL_GetBuf(p_BmPool, p_BmPool->h_BmPortal);
180             if (!p_Data)
181                 break;
182             h_BufContext = BM_POOL_GetBufferContext(p_BmPool, p_Data);
183             if (!discardBuffers)
184                 p_BmPool->bufferPoolInfo.f_PutBuf(p_BmPool->bufferPoolInfo.h_BufferPool, p_Data, h_BufContext);
185         }
186         BmBpidPut(p_BmPool->h_Bm, p_BmPool->bpid);
187     }
188
189     if (p_BmPool->sp)
190         XX_Free(p_BmPool->sp);
191
192     XX_Free(p_BmPool);
193
194     return E_OK;
195 }
196
197 /****************************************/
198 /*       API Init unit functions        */
199 /****************************************/
200
201 t_Handle BM_POOL_Config(t_BmPoolParam *p_BmPoolParam)
202 {
203     t_BmPool        *p_BmPool;
204
205     SANITY_CHECK_RETURN_VALUE(p_BmPoolParam, E_INVALID_HANDLE, NULL);
206     SANITY_CHECK_RETURN_VALUE(p_BmPoolParam->h_Bm, E_INVALID_HANDLE, NULL);
207     SANITY_CHECK_RETURN_VALUE((p_BmPoolParam->shadowMode ||
208                                (p_BmPoolParam->bufferPoolInfo.h_BufferPool &&
209                                p_BmPoolParam->bufferPoolInfo.f_GetBuf &&
210                                p_BmPoolParam->bufferPoolInfo.f_PutBuf &&
211                                p_BmPoolParam->bufferPoolInfo.bufferSize)), E_INVALID_STATE, NULL);
212
213     p_BmPool = (t_BmPool*)XX_Malloc(sizeof(t_BmPool));
214     if (!p_BmPool)
215     {
216         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("BM Pool obj!!!"));
217         return NULL;
218     }
219     memset(p_BmPool, 0, sizeof(t_BmPool));
220
221     p_BmPool->p_BmPoolDriverParams = (t_BmPoolDriverParams *)XX_Malloc(sizeof(t_BmPoolDriverParams));
222     if (!p_BmPool->p_BmPoolDriverParams)
223     {
224         XX_Free(p_BmPool);
225         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Bm Pool driver parameters"));
226         return NULL;
227     }
228     memset(p_BmPool->p_BmPoolDriverParams, 0, sizeof(t_BmPoolDriverParams));
229
230     p_BmPool->h_Bm          = p_BmPoolParam->h_Bm;
231     p_BmPool->h_BmPortal    = p_BmPoolParam->h_BmPortal;
232     p_BmPool->h_App         = p_BmPoolParam->h_App;
233     p_BmPool->numOfBuffers  = p_BmPoolParam->numOfBuffers;
234     p_BmPool->shadowMode    = p_BmPoolParam->shadowMode;
235
236     if (!p_BmPool->h_BmPortal)
237     {
238         p_BmPool->h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
239         SANITY_CHECK_RETURN_VALUE(p_BmPool->h_BmPortal, E_INVALID_HANDLE, NULL);
240     }
241
242     memcpy(&p_BmPool->bufferPoolInfo, &p_BmPoolParam->bufferPoolInfo, sizeof(t_BufferPoolInfo));
243     if (!p_BmPool->bufferPoolInfo.f_PhysToVirt)
244         p_BmPool->bufferPoolInfo.f_PhysToVirt = XX_PhysToVirt;
245     if (!p_BmPool->bufferPoolInfo.f_VirtToPhys)
246         p_BmPool->bufferPoolInfo.f_VirtToPhys = XX_VirtToPhys;
247
248     p_BmPool->p_BmPoolDriverParams->dynamicBpid     = DEFAULT_dynamicBpid;
249     p_BmPool->p_BmPoolDriverParams->useDepletion    = DEFAULT_useDepletion;
250     p_BmPool->p_BmPoolDriverParams->useStockpile    = DEFAULT_useStockpile;
251
252     if (p_BmPool->shadowMode)
253     {
254         p_BmPool->numOfBuffers = 0;
255         BM_POOL_ConfigBpid(p_BmPool, p_BmPoolParam->bpid);
256     }
257
258     return p_BmPool;
259 }
260
261 t_Error BM_POOL_Init(t_Handle h_BmPool)
262 {
263     t_BmPool        *p_BmPool = (t_BmPool *)h_BmPool;
264     t_Error         err;
265
266     SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
267     SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
268
269     p_BmPool->flags |= (p_BmPool->p_BmPoolDriverParams->dynamicBpid)?BMAN_POOL_FLAG_DYNAMIC_BPID:0;
270     p_BmPool->flags |= (p_BmPool->p_BmPoolDriverParams->useStockpile)?BMAN_POOL_FLAG_STOCKPILE:0;
271     p_BmPool->flags |= ((!p_BmPool->shadowMode) &&
272                         (p_BmPool->p_BmPoolDriverParams->useDepletion))?BMAN_POOL_FLAG_DEPLETION:0;
273
274     if (p_BmPool->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
275     {
276         if((p_BmPool->bpid = (uint8_t)BmBpidGet(p_BmPool->h_Bm, FALSE, (uint32_t)0)) == (uint8_t)ILLEGAL_BASE)
277         {
278             BM_POOL_Free(p_BmPool);
279             RETURN_ERROR(CRITICAL, E_INVALID_STATE, ("can't allocate new dynamic pool id"));
280         }
281     }
282     else
283     {
284         if (BmBpidGet(p_BmPool->h_Bm, TRUE, (uint32_t)p_BmPool->bpid) == (uint32_t)ILLEGAL_BASE)
285         {
286             BM_POOL_Free(p_BmPool);
287             RETURN_ERROR(CRITICAL, E_INVALID_STATE, ("can't force pool id %d", p_BmPool->bpid));
288         }
289     }
290     if (p_BmPool->flags & BMAN_POOL_FLAG_DEPLETION)
291     {
292         if(BmSetPoolThresholds(p_BmPool->h_Bm, p_BmPool->bpid, p_BmPool->p_BmPoolDriverParams->depletionThresholds))
293         {
294             BM_POOL_Free(p_BmPool);
295             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can't set thresh for pool bpid %d",p_BmPool->bpid));
296         }
297
298         depletion_link(p_BmPool);
299     }
300
301     if (p_BmPool->flags & BMAN_POOL_FLAG_STOCKPILE)
302     {
303         p_BmPool->sp = (struct bm_buffer *)XX_Malloc(sizeof(struct bm_buffer) * p_BmPool->spMaxBufs);
304         if (!p_BmPool->sp)
305         {
306             BM_POOL_Free(p_BmPool);
307             RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Bm Pool Stockpile"));
308         }
309         memset(p_BmPool->sp, 0, sizeof(struct bm_buffer) * p_BmPool->spMaxBufs);
310     }
311
312     XX_Free(p_BmPool->p_BmPoolDriverParams);
313     p_BmPool->p_BmPoolDriverParams = NULL;
314
315     /*******************/
316     /* Create buffers  */
317     /*******************/
318     if ((err = BM_POOL_FillBufs (p_BmPool, p_BmPool->h_BmPortal, p_BmPool->numOfBuffers)) != E_OK)
319     {
320         BM_POOL_Free(p_BmPool);
321         RETURN_ERROR(MAJOR, err, NO_MSG);
322     }
323
324     return E_OK;
325 }
326
327 t_Error BM_POOL_Free(t_Handle h_BmPool)
328 {
329     SANITY_CHECK_RETURN_ERROR(h_BmPool, E_INVALID_HANDLE);
330
331     return BmPoolFree(h_BmPool, FALSE);
332 }
333
334 t_Error  BM_POOL_ConfigBpid(t_Handle h_BmPool, uint8_t bpid)
335 {
336     t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
337
338     SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
339     SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
340     SANITY_CHECK_RETURN_ERROR(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE);
341
342     p_BmPool->p_BmPoolDriverParams->dynamicBpid = FALSE;
343     p_BmPool->bpid = bpid;
344
345     return E_OK;
346 }
347
348
349 t_Error  BM_POOL_ConfigDepletion(t_Handle h_BmPool, t_BmDepletionCallback *f_Depletion, uint32_t *p_Thresholds)
350 {
351     t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
352
353     SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
354     SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
355     SANITY_CHECK_RETURN_ERROR(f_Depletion, E_INVALID_HANDLE);
356
357     p_BmPool->p_BmPoolDriverParams->useDepletion = TRUE;
358     p_BmPool->f_Depletion = f_Depletion;
359     memcpy(&p_BmPool->p_BmPoolDriverParams->depletionThresholds,
360            p_Thresholds,
361            sizeof(p_BmPool->p_BmPoolDriverParams->depletionThresholds));
362
363     return E_OK;
364 }
365
366 t_Error  BM_POOL_ConfigStockpile(t_Handle h_BmPool, uint16_t maxBuffers, uint16_t minBuffers)
367 {
368     t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
369
370     SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
371     SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
372     SANITY_CHECK_RETURN_ERROR(maxBuffers, E_INVALID_STATE);
373     SANITY_CHECK_RETURN_ERROR(maxBuffers >= minBuffers, E_INVALID_STATE);
374     SANITY_CHECK_RETURN_ERROR((p_BmPool->shadowMode ||
375                               ((maxBuffers * 2) <= p_BmPool->numOfBuffers)),
376                               E_INVALID_STATE);
377
378     p_BmPool->p_BmPoolDriverParams->useStockpile = TRUE;
379     p_BmPool->spMaxBufs     = maxBuffers;
380     p_BmPool->spMinBufs     = minBuffers;
381     p_BmPool->spBufsCmd     = DEFAULT_numOfBufsPerCmd;
382
383     SANITY_CHECK_RETURN_ERROR((p_BmPool->spMaxBufs >=
384                                (p_BmPool->spMinBufs + p_BmPool->spBufsCmd)),
385                               E_INVALID_STATE);
386
387     return E_OK;
388 }
389
390 t_Error  BM_POOL_ConfigBuffContextMode(t_Handle h_BmPool, bool en)
391 {
392     t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
393
394     SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
395     SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
396
397     p_BmPool->noBuffCtxt = !en;
398
399     return E_OK;
400 }
401
402 void * BM_POOL_GetBuf(t_Handle h_BmPool, t_Handle h_BmPortal)
403 {
404     t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
405     struct bm_buffer    bufs[1];
406     uint8_t             retBufsNum;
407     uint64_t            physAddr;
408     uint32_t            flags = 0;
409
410     SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, NULL);
411     SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, NULL);
412     SANITY_CHECK_RETURN_VALUE(p_BmPool->bufferPoolInfo.f_PhysToVirt, E_INVALID_STATE, NULL);
413
414     if (!h_BmPortal)
415     {
416         if (p_BmPool->h_BmPortal)
417             h_BmPortal = p_BmPool->h_BmPortal;
418         else
419         {
420             SANITY_CHECK_RETURN_VALUE(p_BmPool->h_Bm, E_INVALID_HANDLE, NULL);
421             h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
422             SANITY_CHECK_RETURN_VALUE(h_BmPortal, E_INVALID_HANDLE, NULL);
423         }
424     }
425
426     retBufsNum = (uint8_t)BmPoolAcquire(p_BmPool, h_BmPortal, bufs, 1, flags);
427     if (!retBufsNum)
428     {
429         REPORT_ERROR(TRACE, E_NOT_AVAILABLE, ("buffer"));
430         return NULL;
431     }
432     physAddr  = (uint64_t)bufs[0].lo;
433     physAddr |= (uint64_t)(((uint64_t)bufs[0].hi << 32) & 0x000000ff00000000LL);
434     DBG(TRACE,("Get Buffer : poolId %d, address 0x%016llx",
435                p_BmPool->bpid,
436                p_BmPool->bufferPoolInfo.f_PhysToVirt((physAddress_t)physAddr)));
437
438     return p_BmPool->bufferPoolInfo.f_PhysToVirt((physAddress_t)physAddr);
439 }
440
441 t_Error BM_POOL_PutBuf(t_Handle h_BmPool, t_Handle h_BmPortal, void *p_Buff)
442 {
443     t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
444     uint64_t            physAddress;
445     struct bm_buffer    bufs[1];
446
447     SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
448     SANITY_CHECK_RETURN_ERROR(!p_BmPool->p_BmPoolDriverParams, E_INVALID_STATE);
449     SANITY_CHECK_RETURN_ERROR(p_Buff, E_NULL_POINTER);
450
451     physAddress = (uint64_t)(XX_VirtToPhys(p_Buff));
452
453     bufs[0].bpid = p_BmPool->bpid;
454     bufs[0].hi = (uint8_t)((physAddress & 0x000000ff00000000LL) >> 32);
455     bufs[0].lo = (uint32_t)(physAddress & 0xffffffff);
456
457     DBG(TRACE,("Put Buffer : poolId %d, address 0x%016llx, phys 0x%016llx",
458                p_BmPool->bpid, (uint64_t)PTR_TO_UINT(p_Buff), physAddress));
459
460     if (!h_BmPortal)
461     {
462         if (p_BmPool->h_BmPortal)
463             h_BmPortal = p_BmPool->h_BmPortal;
464         else
465         {
466             SANITY_CHECK_RETURN_ERROR(p_BmPool->h_Bm, E_INVALID_HANDLE);
467             h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
468             SANITY_CHECK_RETURN_ERROR(h_BmPortal, E_INVALID_HANDLE);
469         }
470     }
471
472     return BmPoolRelease(p_BmPool, h_BmPortal, bufs, 1, BMAN_RELEASE_FLAG_WAIT);
473 }
474
475 t_Error BM_POOL_FillBufs(t_Handle h_BmPool, t_Handle h_BmPortal, uint32_t numBufs)
476 {
477     t_BmPool    *p_BmPool   = (t_BmPool *)h_BmPool;
478
479     SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
480     SANITY_CHECK_RETURN_ERROR(!p_BmPool->p_BmPoolDriverParams, E_INVALID_STATE);
481
482     if (!h_BmPortal)
483     {
484         if (p_BmPool->h_BmPortal)
485             h_BmPortal = p_BmPool->h_BmPortal;
486         else
487         {
488             SANITY_CHECK_RETURN_ERROR(p_BmPool->h_Bm, E_INVALID_HANDLE);
489             h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
490             SANITY_CHECK_RETURN_ERROR(h_BmPortal, E_INVALID_HANDLE);
491         }
492     }
493
494     while (numBufs--)
495     {
496         uint8_t             *p_Data;
497         t_Error             res;
498         t_Handle            h_BufContext;
499
500         p_Data = p_BmPool->bufferPoolInfo.f_GetBuf(p_BmPool->bufferPoolInfo.h_BufferPool, &h_BufContext);
501         if(!p_Data)
502             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("run-out of buffers for bpid %d",p_BmPool->bpid));
503
504         if (!p_BmPool->noBuffCtxt)
505             *(t_Handle *)(p_Data - sizeof(t_Handle)) = h_BufContext;
506
507         if ((res = BM_POOL_PutBuf(p_BmPool, h_BmPortal, p_Data)) != E_OK)
508             RETURN_ERROR(CRITICAL, res, ("Seeding reserved buffer pool failed"));
509     }
510
511     return E_OK;
512 }
513
514 uint8_t BM_POOL_GetId(t_Handle h_BmPool)
515 {
516     t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
517
518     SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, 0);
519     SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, 0);
520
521     return p_BmPool->bpid;
522 }
523
524 uint16_t BM_POOL_GetBufferSize(t_Handle h_BmPool)
525 {
526     t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
527
528     SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, 0);
529     SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, 0);
530
531     return p_BmPool->bufferPoolInfo.bufferSize;
532 }
533
534 t_Handle BM_POOL_GetBufferContext(t_Handle h_BmPool, void *p_Buff)
535 {
536     t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
537
538     SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, NULL);
539     SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, NULL);
540     SANITY_CHECK_RETURN_VALUE(p_Buff, E_NULL_POINTER, NULL);
541
542     if (p_BmPool->noBuffCtxt)
543         return NULL;
544
545     return *(t_Handle *)PTR_MOVE(p_Buff, -(sizeof(t_Handle)));
546 }
547
548 uint32_t BM_POOL_GetCounter(t_Handle h_BmPool, e_BmPoolCounters counter)
549 {
550     t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
551
552     SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, 0);
553     SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, 0);
554
555     switch(counter)
556     {
557         case(e_BM_POOL_COUNTERS_CONTENT):
558             return BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_CONTENT, p_BmPool->bpid);
559         case(e_BM_POOL_COUNTERS_SW_DEPLETION):
560             return (p_BmPool->swDepletionCount +=
561                 BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_SW_DEPLETION, p_BmPool->bpid));
562         case(e_BM_POOL_COUNTERS_HW_DEPLETION):
563             return (p_BmPool->hwDepletionCount +=
564                 BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_HW_DEPLETION, p_BmPool->bpid));
565         default:
566             break;
567     }
568
569     /* should never get here */
570     ASSERT_COND(FALSE);
571
572     return 0;
573 }