• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 1999-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 #include "gki_int.h"
19 #include <stdio.h>
20 
21 #if (GKI_NUM_TOTAL_BUF_POOLS > 16)
22 #error Number of pools out of range (16 Max)!
23 #endif
24 
25 #if (!defined(BTU_STACK_LITE_ENABLED) || BTU_STACK_LITE_ENABLED == FALSE)
26 static void gki_add_to_pool_list(UINT8 pool_id);
27 static void gki_remove_from_pool_list(UINT8 pool_id);
28 #endif /*  BTU_STACK_LITE_ENABLED == FALSE */
29 
30 #if GKI_BUFFER_DEBUG
31 #define LOG_TAG "GKI_DEBUG"
32 #define LOGD(format, ...)  LogMsg (TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC, format, ## __VA_ARGS__)
33 #endif
34 /*******************************************************************************
35 **
36 ** Function         gki_init_free_queue
37 **
38 ** Description      Internal function called at startup to initialize a free
39 **                  queue. It is called once for each free queue.
40 **
41 ** Returns          void
42 **
43 *******************************************************************************/
gki_init_free_queue(UINT8 id,UINT16 size,UINT16 total,void * p_mem)44 static void gki_init_free_queue (UINT8 id, UINT16 size, UINT16 total, void *p_mem)
45 {
46     UINT16           i;
47     UINT16           act_size;
48     BUFFER_HDR_T    *hdr;
49     BUFFER_HDR_T    *hdr1 = NULL;
50     UINT32          *magic;
51     INT32            tempsize = size;
52     tGKI_COM_CB     *p_cb = &gki_cb.com;
53 
54     /* Ensure an even number of longwords */
55     tempsize = (INT32)ALIGN_POOL(size);
56     act_size = (UINT16)(tempsize + BUFFER_PADDING_SIZE);
57 
58     /* Remember pool start and end addresses */
59     if(p_mem)
60     {
61         p_cb->pool_start[id] = (UINT8 *)p_mem;
62         p_cb->pool_end[id]   = (UINT8 *)p_mem + (act_size * total);
63     }
64 
65     p_cb->pool_size[id]  = act_size;
66 
67     p_cb->freeq[id].size      = (UINT16) tempsize;
68     p_cb->freeq[id].total     = total;
69     p_cb->freeq[id].cur_cnt   = 0;
70     p_cb->freeq[id].max_cnt   = 0;
71 
72 #if GKI_BUFFER_DEBUG
73     LOGD("gki_init_free_queue() init pool=%d, size=%d (aligned=%d) total=%d start=%p", id, size, tempsize, total, p_mem);
74 #endif
75 
76     /* Initialize  index table */
77     if(p_mem)
78     {
79         hdr = (BUFFER_HDR_T *)p_mem;
80         p_cb->freeq[id].p_first = hdr;
81         for (i = 0; i < total; i++)
82         {
83             hdr->task_id = GKI_INVALID_TASK;
84             hdr->q_id    = id;
85             hdr->status  = BUF_STATUS_FREE;
86             magic        = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + tempsize);
87             *magic       = MAGIC_NO;
88             hdr1         = hdr;
89             hdr          = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
90             hdr1->p_next = hdr;
91         }
92         hdr1->p_next = NULL;
93         p_cb->freeq[id].p_last = hdr1;
94     }
95     return;
96 }
97 
98 #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
gki_alloc_free_queue(UINT8 id)99 static BOOLEAN gki_alloc_free_queue(UINT8 id)
100 {
101     FREE_QUEUE_T  *Q;
102     tGKI_COM_CB *p_cb = &gki_cb.com;
103     printf("\ngki_alloc_free_queue in, id:%d \n", id);
104 
105     Q = &p_cb->freeq[p_cb->pool_list[id]];
106 
107     if(Q->p_first == 0)
108     {
109         void* p_mem = GKI_os_malloc((Q->size + BUFFER_PADDING_SIZE) * Q->total);
110         if(p_mem)
111         {
112             //re-initialize the queue with allocated memory
113             printf("\ngki_alloc_free_queue calling  gki_init_free_queue, id:%d  size:%d, totol:%d\n", id, Q->size, Q->total);
114             gki_init_free_queue(id, Q->size, Q->total, p_mem);
115             printf("\ngki_alloc_free_queue ret OK, id:%d  size:%d, totol:%d\n", id, Q->size, Q->total);
116             return TRUE;
117         }
118         GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "gki_alloc_free_queue: Not enough memory");
119     }
120     printf("\ngki_alloc_free_queue out failed, id:%d\n", id);
121     return FALSE;
122 }
123 #endif
124 
125 /*******************************************************************************
126 **
127 ** Function         gki_buffer_init
128 **
129 ** Description      Called once internally by GKI at startup to initialize all
130 **                  buffers and free buffer pools.
131 **
132 ** Returns          void
133 **
134 *******************************************************************************/
gki_buffer_init(void)135 void gki_buffer_init(void)
136 {
137     UINT8   i, tt, mb;
138     tGKI_COM_CB *p_cb = &gki_cb.com;
139 
140     /* Initialize mailboxes */
141     for (tt = 0; tt < GKI_MAX_TASKS; tt++)
142     {
143         for (mb = 0; mb < NUM_TASK_MBOX; mb++)
144         {
145             p_cb->OSTaskQFirst[tt][mb] = NULL;
146             p_cb->OSTaskQLast [tt][mb] = NULL;
147         }
148     }
149 
150     for (tt = 0; tt < GKI_NUM_TOTAL_BUF_POOLS; tt++)
151     {
152         p_cb->pool_start[tt] = NULL;
153         p_cb->pool_end[tt]   = NULL;
154         p_cb->pool_size[tt]  = 0;
155 
156         p_cb->freeq[tt].p_first = 0;
157         p_cb->freeq[tt].p_last  = 0;
158         p_cb->freeq[tt].size    = 0;
159         p_cb->freeq[tt].total   = 0;
160         p_cb->freeq[tt].cur_cnt = 0;
161         p_cb->freeq[tt].max_cnt = 0;
162     }
163 
164     /* Use default from target.h */
165     p_cb->pool_access_mask = GKI_DEF_BUFPOOL_PERM_MASK;
166 
167 #if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == TRUE))
168 
169 #if (GKI_NUM_FIXED_BUF_POOLS > 0)
170     p_cb->bufpool0 = (UINT8 *)GKI_os_malloc ((GKI_BUF0_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX);
171 #endif
172 
173 #if (GKI_NUM_FIXED_BUF_POOLS > 1)
174     p_cb->bufpool1 = (UINT8 *)GKI_os_malloc ((GKI_BUF1_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX);
175 #endif
176 
177 #if (GKI_NUM_FIXED_BUF_POOLS > 2)
178     p_cb->bufpool2 = (UINT8 *)GKI_os_malloc ((GKI_BUF2_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX);
179 #endif
180 
181 #if (GKI_NUM_FIXED_BUF_POOLS > 3)
182     p_cb->bufpool3 = (UINT8 *)GKI_os_malloc ((GKI_BUF3_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX);
183 #endif
184 
185 #if (GKI_NUM_FIXED_BUF_POOLS > 4)
186     p_cb->bufpool4 = (UINT8 *)GKI_os_malloc ((GKI_BUF4_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX);
187 #endif
188 
189 #if (GKI_NUM_FIXED_BUF_POOLS > 5)
190     p_cb->bufpool5 = (UINT8 *)GKI_os_malloc ((GKI_BUF5_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX);
191 #endif
192 
193 #if (GKI_NUM_FIXED_BUF_POOLS > 6)
194     p_cb->bufpool6 = (UINT8 *)GKI_os_malloc ((GKI_BUF6_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX);
195 #endif
196 
197 #if (GKI_NUM_FIXED_BUF_POOLS > 7)
198     p_cb->bufpool7 = (UINT8 *)GKI_os_malloc ((GKI_BUF7_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX);
199 #endif
200 
201 #if (GKI_NUM_FIXED_BUF_POOLS > 8)
202     p_cb->bufpool8 = (UINT8 *)GKI_os_malloc ((GKI_BUF8_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX);
203 #endif
204 
205 #if (GKI_NUM_FIXED_BUF_POOLS > 9)
206     p_cb->bufpool9 = (UINT8 *)GKI_os_malloc ((GKI_BUF9_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX);
207 #endif
208 
209 #if (GKI_NUM_FIXED_BUF_POOLS > 10)
210     p_cb->bufpool10 = (UINT8 *)GKI_os_malloc ((GKI_BUF10_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX);
211 #endif
212 
213 #if (GKI_NUM_FIXED_BUF_POOLS > 11)
214     p_cb->bufpool11 = (UINT8 *)GKI_os_malloc ((GKI_BUF11_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX);
215 #endif
216 
217 #if (GKI_NUM_FIXED_BUF_POOLS > 12)
218     p_cb->bufpool12 = (UINT8 *)GKI_os_malloc ((GKI_BUF12_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX);
219 #endif
220 
221 #if (GKI_NUM_FIXED_BUF_POOLS > 13)
222     p_cb->bufpool13 = (UINT8 *)GKI_os_malloc ((GKI_BUF13_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX);
223 #endif
224 
225 #if (GKI_NUM_FIXED_BUF_POOLS > 14)
226     p_cb->bufpool14 = (UINT8 *)GKI_os_malloc ((GKI_BUF14_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX);
227 #endif
228 
229 #if (GKI_NUM_FIXED_BUF_POOLS > 15)
230     p_cb->bufpool15 = (UINT8 *)GKI_os_malloc ((GKI_BUF15_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX);
231 #endif
232 
233 #endif
234 
235 
236 #if (GKI_NUM_FIXED_BUF_POOLS > 0)
237     gki_init_free_queue(0, GKI_BUF0_SIZE, GKI_BUF0_MAX, p_cb->bufpool0);
238 #endif
239 
240 #if (GKI_NUM_FIXED_BUF_POOLS > 1)
241     gki_init_free_queue(1, GKI_BUF1_SIZE, GKI_BUF1_MAX, p_cb->bufpool1);
242 #endif
243 
244 #if (GKI_NUM_FIXED_BUF_POOLS > 2)
245     gki_init_free_queue(2, GKI_BUF2_SIZE, GKI_BUF2_MAX, p_cb->bufpool2);
246 #endif
247 
248 #if (GKI_NUM_FIXED_BUF_POOLS > 3)
249     gki_init_free_queue(3, GKI_BUF3_SIZE, GKI_BUF3_MAX, p_cb->bufpool3);
250 #endif
251 
252 #if (GKI_NUM_FIXED_BUF_POOLS > 4)
253     gki_init_free_queue(4, GKI_BUF4_SIZE, GKI_BUF4_MAX, p_cb->bufpool4);
254 #endif
255 
256 #if (GKI_NUM_FIXED_BUF_POOLS > 5)
257     gki_init_free_queue(5, GKI_BUF5_SIZE, GKI_BUF5_MAX, p_cb->bufpool5);
258 #endif
259 
260 #if (GKI_NUM_FIXED_BUF_POOLS > 6)
261     gki_init_free_queue(6, GKI_BUF6_SIZE, GKI_BUF6_MAX, p_cb->bufpool6);
262 #endif
263 
264 #if (GKI_NUM_FIXED_BUF_POOLS > 7)
265     gki_init_free_queue(7, GKI_BUF7_SIZE, GKI_BUF7_MAX, p_cb->bufpool7);
266 #endif
267 
268 #if (GKI_NUM_FIXED_BUF_POOLS > 8)
269     gki_init_free_queue(8, GKI_BUF8_SIZE, GKI_BUF8_MAX, p_cb->bufpool8);
270 #endif
271 
272 #if (GKI_NUM_FIXED_BUF_POOLS > 9)
273     gki_init_free_queue(9, GKI_BUF9_SIZE, GKI_BUF9_MAX, p_cb->bufpool9);
274 #endif
275 
276 #if (GKI_NUM_FIXED_BUF_POOLS > 10)
277     gki_init_free_queue(10, GKI_BUF10_SIZE, GKI_BUF10_MAX, p_cb->bufpool10);
278 #endif
279 
280 #if (GKI_NUM_FIXED_BUF_POOLS > 11)
281     gki_init_free_queue(11, GKI_BUF11_SIZE, GKI_BUF11_MAX, p_cb->bufpool11);
282 #endif
283 
284 #if (GKI_NUM_FIXED_BUF_POOLS > 12)
285     gki_init_free_queue(12, GKI_BUF12_SIZE, GKI_BUF12_MAX, p_cb->bufpool12);
286 #endif
287 
288 #if (GKI_NUM_FIXED_BUF_POOLS > 13)
289     gki_init_free_queue(13, GKI_BUF13_SIZE, GKI_BUF13_MAX, p_cb->bufpool13);
290 #endif
291 
292 #if (GKI_NUM_FIXED_BUF_POOLS > 14)
293     gki_init_free_queue(14, GKI_BUF14_SIZE, GKI_BUF14_MAX, p_cb->bufpool14);
294 #endif
295 
296 #if (GKI_NUM_FIXED_BUF_POOLS > 15)
297     gki_init_free_queue(15, GKI_BUF15_SIZE, GKI_BUF15_MAX, p_cb->bufpool15);
298 #endif
299 
300     /* add pools to the pool_list which is arranged in the order of size */
301     for(i=0; i < GKI_NUM_FIXED_BUF_POOLS ; i++)
302     {
303         p_cb->pool_list[i] = i;
304     }
305 
306     p_cb->curr_total_no_of_pools = GKI_NUM_FIXED_BUF_POOLS;
307 
308     return;
309 }
310 
311 
312 /*******************************************************************************
313 **
314 ** Function         GKI_init_q
315 **
316 ** Description      Called by an application to initialize a buffer queue.
317 **
318 ** Returns          void
319 **
320 *******************************************************************************/
GKI_init_q(BUFFER_Q * p_q)321 void GKI_init_q (BUFFER_Q *p_q)
322 {
323     p_q->p_first = p_q->p_last = NULL;
324     p_q->count = 0;
325 
326     return;
327 }
328 
329 
330 /*******************************************************************************
331 **
332 ** Function         GKI_getbuf
333 **
334 ** Description      Called by an application to get a free buffer which
335 **                  is of size greater or equal to the requested size.
336 **
337 **                  Note: This routine only takes buffers from public pools.
338 **                        It will not use any buffers from pools
339 **                        marked GKI_RESTRICTED_POOL.
340 **
341 ** Parameters       size - (input) number of bytes needed.
342 **
343 ** Returns          A pointer to the buffer, or NULL if none available
344 **
345 *******************************************************************************/
346 #if GKI_BUFFER_DEBUG
GKI_getbuf_debug(UINT16 size,const char * _function_,int _line_)347 void *GKI_getbuf_debug (UINT16 size, const char * _function_, int _line_)
348 #else
349 void *GKI_getbuf (UINT16 size)
350 #endif
351 {
352     UINT8         i;
353     FREE_QUEUE_T  *Q;
354     BUFFER_HDR_T  *p_hdr;
355     tGKI_COM_CB *p_cb = &gki_cb.com;
356 #if GKI_BUFFER_DEBUG
357     UINT8         x;
358 #endif
359 
360     if (size == 0)
361     {
362         GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "getbuf: Size is zero");
363         return (NULL);
364     }
365 
366 #if GKI_BUFFER_DEBUG
367     LOGD("GKI_getbuf() requesting %d func:%s(line=%d)", size, _function_, _line_);
368 #endif
369     /* Find the first buffer pool that is public that can hold the desired size */
370     for (i=0; i < p_cb->curr_total_no_of_pools; i++)
371     {
372         if ( size <= p_cb->freeq[p_cb->pool_list[i]].size )
373             break;
374     }
375 
376     if(i == p_cb->curr_total_no_of_pools)
377     {
378         GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "getbuf: Size is too big");
379         return (NULL);
380     }
381 
382     /* Make sure the buffers aren't disturbed til finished with allocation */
383     GKI_disable();
384 
385     /* search the public buffer pools that are big enough to hold the size
386      * until a free buffer is found */
387     for ( ; i < p_cb->curr_total_no_of_pools; i++)
388     {
389         /* Only look at PUBLIC buffer pools (bypass RESTRICTED pools) */
390         if (((UINT16)1 << p_cb->pool_list[i]) & p_cb->pool_access_mask)
391             continue;
392 
393         Q = &p_cb->freeq[p_cb->pool_list[i]];
394         if(Q->cur_cnt < Q->total)
395         {
396         #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
397             if(Q->p_first == 0 && gki_alloc_free_queue(i) != TRUE)
398             {
399                 GKI_TRACE_ERROR_0("GKI_getbuf() out of buffer");
400                 return NULL;
401             }
402         #endif
403             p_hdr = Q->p_first;
404             Q->p_first = p_hdr->p_next;
405 
406             if (!Q->p_first)
407                 Q->p_last = NULL;
408 
409             if(++Q->cur_cnt > Q->max_cnt)
410                 Q->max_cnt = Q->cur_cnt;
411 
412             GKI_enable();
413 
414             p_hdr->task_id = GKI_get_taskid();
415 
416             p_hdr->status  = BUF_STATUS_UNLINKED;
417             p_hdr->p_next  = NULL;
418             p_hdr->Type    = 0;
419 #if GKI_BUFFER_DEBUG
420             LOGD("GKI_getbuf() allocated, %x, %x (%d of %d used) %d", (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total, p_cb->freeq[i].total);
421 
422             strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
423             p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
424             p_hdr->_line = _line_;
425 #endif
426             return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
427         }
428     }
429 
430     GKI_TRACE_ERROR_0("GKI_getbuf() unable to allocate buffer!!!!!");
431 #if GKI_BUFFER_DEBUG
432     LOGD("GKI_getbuf() unable to allocate buffer!!!!!");
433     LOGD("******************** GKI Memory Pool Dump ********************");
434 
435     p_cb = &gki_cb.com;
436 
437     LOGD("Dumping total of %d buffer pools", p_cb->curr_total_no_of_pools);
438 
439     for (i=0 ; i < p_cb->curr_total_no_of_pools; i++)
440     {
441         p_hdr = (BUFFER_HDR_T *)p_cb->pool_start[i];
442 
443         LOGD("pool %d has a total of %d buffers (start=%p)", i, p_cb->freeq[i].total, p_hdr);
444 
445         for (x=0; p_hdr && x < p_cb->freeq[i].total; x++)
446         {
447             if (p_hdr->status != BUF_STATUS_FREE)
448             {
449                 LOGD("pool:%d, buf[%d]:%x, hdr:%x status=%d func:%s(line=%d)", i, x, (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, p_hdr->status, p_hdr->_function, p_hdr->_line);
450             }
451 
452             p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_hdr + p_cb->pool_size[i]);
453         }
454     }
455     LOGD("**************************************************************");
456 #endif
457 
458     GKI_TRACE_ERROR_0("Failed to allocate GKI buffer");
459 
460     GKI_enable();
461 
462     return (NULL);
463 }
464 
465 
466 /*******************************************************************************
467 **
468 ** Function         GKI_getpoolbuf
469 **
470 ** Description      Called by an application to get a free buffer from
471 **                  a specific buffer pool.
472 **
473 **                  Note: If there are no more buffers available from the pool,
474 **                        the public buffers are searched for an available buffer.
475 **
476 ** Parameters       pool_id - (input) pool ID to get a buffer out of.
477 **
478 ** Returns          A pointer to the buffer, or NULL if none available
479 **
480 *******************************************************************************/
481 #if GKI_BUFFER_DEBUG
GKI_getpoolbuf_debug(UINT8 pool_id,const char * _function_,int _line_)482 void *GKI_getpoolbuf_debug (UINT8 pool_id, const char * _function_, int _line_)
483 #else
484 void *GKI_getpoolbuf (UINT8 pool_id)
485 #endif
486 {
487     FREE_QUEUE_T  *Q;
488     BUFFER_HDR_T  *p_hdr;
489     tGKI_COM_CB *p_cb = &gki_cb.com;
490 
491     if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
492         return (NULL);
493 
494 #if GKI_BUFFER_DEBUG
495     LOGD("GKI_getpoolbuf() requesting from %d func:%s(line=%d)", pool_id, _function_, _line_);
496 #endif
497     /* Make sure the buffers aren't disturbed til finished with allocation */
498     GKI_disable();
499 
500     Q = &p_cb->freeq[pool_id];
501     if(Q->cur_cnt < Q->total)
502     {
503 #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
504         if(Q->p_first == 0 && gki_alloc_free_queue(pool_id) != TRUE)
505             return NULL;
506 #endif
507         p_hdr = Q->p_first;
508         Q->p_first = p_hdr->p_next;
509 
510         if (!Q->p_first)
511             Q->p_last = NULL;
512 
513         if(++Q->cur_cnt > Q->max_cnt)
514             Q->max_cnt = Q->cur_cnt;
515 
516         GKI_enable();
517 
518 
519         p_hdr->task_id = GKI_get_taskid();
520 
521         p_hdr->status  = BUF_STATUS_UNLINKED;
522         p_hdr->p_next  = NULL;
523         p_hdr->Type    = 0;
524 
525 #if GKI_BUFFER_DEBUG
526         LOGD("GKI_getpoolbuf() allocated, %x, %x (%d of %d used) %d", (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total, p_cb->freeq[pool_id].total);
527 
528         strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
529         p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
530         p_hdr->_line = _line_;
531 #endif
532         return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
533     }
534 
535     /* If here, no buffers in the specified pool */
536     GKI_enable();
537 
538 #if GKI_BUFFER_DEBUG
539     /* try for free buffers in public pools */
540     return (GKI_getbuf_debug(p_cb->freeq[pool_id].size, _function_, _line_));
541 #else
542     /* try for free buffers in public pools */
543     return (GKI_getbuf(p_cb->freeq[pool_id].size));
544 #endif
545 }
546 
547 /*******************************************************************************
548 **
549 ** Function         GKI_freebuf
550 **
551 ** Description      Called by an application to return a buffer to the free pool.
552 **
553 ** Parameters       p_buf - (input) address of the beginning of a buffer.
554 **
555 ** Returns          void
556 **
557 *******************************************************************************/
GKI_freebuf(void * p_buf)558 void GKI_freebuf (void *p_buf)
559 {
560     FREE_QUEUE_T    *Q;
561     BUFFER_HDR_T    *p_hdr;
562 
563 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
564     if (!p_buf || gki_chk_buf_damage(p_buf))
565     {
566         GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Free - Buf Corrupted");
567         return;
568     }
569 #endif
570 
571     p_hdr = (BUFFER_HDR_T *) ((UINT8 *)p_buf - BUFFER_HDR_SIZE);
572 
573 #if GKI_BUFFER_DEBUG
574     LOGD("GKI_freebuf() freeing, %x, %x, func:%s(line=%d)", p_buf, p_hdr, p_hdr->_function, p_hdr->_line);
575 #endif
576 
577     if (p_hdr->status != BUF_STATUS_UNLINKED)
578     {
579         GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf");
580         return;
581     }
582 
583     if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS)
584     {
585         GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId");
586         return;
587     }
588 
589     GKI_disable();
590 
591     /*
592     ** Release the buffer
593     */
594     Q  = &gki_cb.com.freeq[p_hdr->q_id];
595     if (Q->p_last)
596         Q->p_last->p_next = p_hdr;
597     else
598         Q->p_first = p_hdr;
599 
600     Q->p_last      = p_hdr;
601     p_hdr->p_next  = NULL;
602     p_hdr->status  = BUF_STATUS_FREE;
603     p_hdr->task_id = GKI_INVALID_TASK;
604     if (Q->cur_cnt > 0)
605         Q->cur_cnt--;
606 
607     GKI_enable();
608 
609     return;
610 }
611 
612 
613 /*******************************************************************************
614 **
615 ** Function         GKI_get_buf_size
616 **
617 ** Description      Called by an application to get the size of a buffer.
618 **
619 ** Parameters       p_buf - (input) address of the beginning of a buffer.
620 **
621 ** Returns          the size of the buffer
622 **
623 *******************************************************************************/
GKI_get_buf_size(void * p_buf)624 UINT16 GKI_get_buf_size (void *p_buf)
625 {
626     BUFFER_HDR_T    *p_hdr;
627 
628     p_hdr = (BUFFER_HDR_T *)((UINT8 *) p_buf - BUFFER_HDR_SIZE);
629 
630     if ((UINT32)p_hdr & 1)
631         return (0);
632 
633     if (p_hdr->q_id < GKI_NUM_TOTAL_BUF_POOLS)
634     {
635         return (gki_cb.com.freeq[p_hdr->q_id].size);
636     }
637 
638     return (0);
639 }
640 
641 /*******************************************************************************
642 **
643 ** Function         gki_chk_buf_damage
644 **
645 ** Description      Called internally by OSS to check for buffer corruption.
646 **
647 ** Returns          TRUE if there is a problem, else FALSE
648 **
649 *******************************************************************************/
gki_chk_buf_damage(void * p_buf)650 BOOLEAN gki_chk_buf_damage(void *p_buf)
651 {
652 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
653 
654     UINT32 *magic;
655     magic  = (UINT32 *)((UINT8 *) p_buf + GKI_get_buf_size(p_buf));
656 
657     if ((UINT32)magic & 1)
658         return (TRUE);
659 
660     if (*magic == MAGIC_NO)
661         return (FALSE);
662 
663     return (TRUE);
664 
665 #else
666 
667     return (FALSE);
668 
669 #endif
670 }
671 
672 /*******************************************************************************
673 **
674 ** Function         GKI_send_msg
675 **
676 ** Description      Called by applications to send a buffer to a task
677 **
678 ** Returns          Nothing
679 **
680 *******************************************************************************/
GKI_send_msg(UINT8 task_id,UINT8 mbox,void * msg)681 void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)
682 {
683     BUFFER_HDR_T    *p_hdr;
684     tGKI_COM_CB *p_cb = &gki_cb.com;
685 
686     /* If task non-existant or not started, drop buffer */
687     if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
688     {
689         GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
690         GKI_freebuf (msg);
691         return;
692     }
693 
694 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
695     if (gki_chk_buf_damage(msg))
696     {
697         GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
698         return;
699     }
700 #endif
701 
702     p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
703 
704     if (p_hdr->status != BUF_STATUS_UNLINKED)
705     {
706         GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
707         return;
708     }
709 
710     GKI_disable();
711 
712     if (p_cb->OSTaskQFirst[task_id][mbox])
713         p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
714     else
715         p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
716 
717     p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
718 
719     p_hdr->p_next = NULL;
720     p_hdr->status = BUF_STATUS_QUEUED;
721     p_hdr->task_id = task_id;
722 
723 
724     GKI_enable();
725 
726     GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));
727 
728     return;
729 }
730 
731 /*******************************************************************************
732 **
733 ** Function         GKI_read_mbox
734 **
735 ** Description      Called by applications to read a buffer from one of
736 **                  the task mailboxes.  A task can only read its own mailbox.
737 **
738 ** Parameters:      mbox  - (input) mailbox ID to read (0, 1, 2, or 3)
739 **
740 ** Returns          NULL if the mailbox was empty, else the address of a buffer
741 **
742 *******************************************************************************/
GKI_read_mbox(UINT8 mbox)743 void *GKI_read_mbox (UINT8 mbox)
744 {
745     UINT8           task_id = GKI_get_taskid();
746     void            *p_buf = NULL;
747     BUFFER_HDR_T    *p_hdr;
748 
749     if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX))
750         return (NULL);
751 
752     GKI_disable();
753 
754     if (gki_cb.com.OSTaskQFirst[task_id][mbox])
755     {
756         p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];
757         gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
758 
759         p_hdr->p_next = NULL;
760         p_hdr->status = BUF_STATUS_UNLINKED;
761 
762         p_buf = (UINT8 *)p_hdr + BUFFER_HDR_SIZE;
763     }
764 
765     GKI_enable();
766 
767     return (p_buf);
768 }
769 
770 
771 
772 /*******************************************************************************
773 **
774 ** Function         GKI_enqueue
775 **
776 ** Description      Enqueue a buffer at the tail of the queue
777 **
778 ** Parameters:      p_q  -  (input) pointer to a queue.
779 **                  p_buf - (input) address of the buffer to enqueue
780 **
781 ** Returns          void
782 **
783 *******************************************************************************/
GKI_enqueue(BUFFER_Q * p_q,void * p_buf)784 void GKI_enqueue (BUFFER_Q *p_q, void *p_buf)
785 {
786     BUFFER_HDR_T    *p_hdr;
787 
788 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
789     if (gki_chk_buf_damage(p_buf))
790     {
791         GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
792         return;
793     }
794 #endif
795 
796     p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
797 
798     if (p_hdr->status != BUF_STATUS_UNLINKED)
799     {
800         GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue - buf already linked");
801         return;
802     }
803 
804     GKI_disable();
805 
806     /* Since the queue is exposed (C vs C++), keep the pointers in exposed format */
807     if (p_q->p_first)
808     {
809         BUFFER_HDR_T *p_last_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_last - BUFFER_HDR_SIZE);
810         p_last_hdr->p_next = p_hdr;
811     }
812     else
813         p_q->p_first = p_buf;
814 
815     p_q->p_last = p_buf;
816     p_q->count++;
817 
818     p_hdr->p_next = NULL;
819     p_hdr->status = BUF_STATUS_QUEUED;
820 
821     GKI_enable();
822 
823     return;
824 }
825 
826 
827 /*******************************************************************************
828 **
829 ** Function         GKI_enqueue_head
830 **
831 ** Description      Enqueue a buffer at the head of the queue
832 **
833 ** Parameters:      p_q  -  (input) pointer to a queue.
834 **                  p_buf - (input) address of the buffer to enqueue
835 **
836 ** Returns          void
837 **
838 *******************************************************************************/
GKI_enqueue_head(BUFFER_Q * p_q,void * p_buf)839 void GKI_enqueue_head (BUFFER_Q *p_q, void *p_buf)
840 {
841     BUFFER_HDR_T    *p_hdr;
842 
843 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
844     if (gki_chk_buf_damage(p_buf))
845     {
846         GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
847         return;
848     }
849 #endif
850 
851     p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
852 
853     if (p_hdr->status != BUF_STATUS_UNLINKED)
854     {
855         GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue head - buf already linked");
856         return;
857     }
858 
859     GKI_disable();
860 
861     if (p_q->p_first)
862     {
863         p_hdr->p_next = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
864         p_q->p_first = p_buf;
865     }
866     else
867     {
868         p_q->p_first = p_buf;
869         p_q->p_last  = p_buf;
870         p_hdr->p_next = NULL;
871     }
872     p_q->count++;
873 
874     p_hdr->status = BUF_STATUS_QUEUED;
875 
876     GKI_enable();
877 
878     return;
879 }
880 
881 
882 /*******************************************************************************
883 **
884 ** Function         GKI_dequeue
885 **
886 ** Description      Dequeues a buffer from the head of a queue
887 **
888 ** Parameters:      p_q  - (input) pointer to a queue.
889 **
890 ** Returns          NULL if queue is empty, else buffer
891 **
892 *******************************************************************************/
GKI_dequeue(BUFFER_Q * p_q)893 void *GKI_dequeue (BUFFER_Q *p_q)
894 {
895     BUFFER_HDR_T    *p_hdr;
896 
897     GKI_disable();
898 
899     if (!p_q || !p_q->count)
900     {
901         GKI_enable();
902         return (NULL);
903     }
904 
905     p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
906 
907     /* Keep buffers such that GKI header is invisible
908     */
909     if (p_hdr->p_next)
910         p_q->p_first = ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
911     else
912     {
913         p_q->p_first = NULL;
914         p_q->p_last  = NULL;
915     }
916 
917     p_q->count--;
918 
919     p_hdr->p_next = NULL;
920     p_hdr->status = BUF_STATUS_UNLINKED;
921 
922     GKI_enable();
923 
924     return ((UINT8 *)p_hdr + BUFFER_HDR_SIZE);
925 }
926 
927 
928 /*******************************************************************************
929 **
930 ** Function         GKI_remove_from_queue
931 **
932 ** Description      Dequeue a buffer from the middle of the queue
933 **
934 ** Parameters:      p_q  - (input) pointer to a queue.
935 **                  p_buf - (input) address of the buffer to enqueue
936 **
937 ** Returns          NULL if queue is empty, else buffer
938 **
939 *******************************************************************************/
GKI_remove_from_queue(BUFFER_Q * p_q,void * p_buf)940 void *GKI_remove_from_queue (BUFFER_Q *p_q, void *p_buf)
941 {
942     BUFFER_HDR_T    *p_prev;
943     BUFFER_HDR_T    *p_buf_hdr;
944 
945     GKI_disable();
946 
947     if (p_buf == p_q->p_first)
948     {
949         GKI_enable();
950         return (GKI_dequeue (p_q));
951     }
952 
953     p_buf_hdr = (BUFFER_HDR_T *)((UINT8 *)p_buf - BUFFER_HDR_SIZE);
954     p_prev    = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
955 
956     for ( ; p_prev; p_prev = p_prev->p_next)
957     {
958         /* If the previous points to this one, move the pointers around */
959         if (p_prev->p_next == p_buf_hdr)
960         {
961             p_prev->p_next = p_buf_hdr->p_next;
962 
963             /* If we are removing the last guy in the queue, update p_last */
964             if (p_buf == p_q->p_last)
965                 p_q->p_last = p_prev + 1;
966 
967             /* One less in the queue */
968             p_q->count--;
969 
970             /* The buffer is now unlinked */
971             p_buf_hdr->p_next = NULL;
972             p_buf_hdr->status = BUF_STATUS_UNLINKED;
973 
974             GKI_enable();
975             return (p_buf);
976         }
977     }
978 
979     GKI_enable();
980     return (NULL);
981 }
982 
983 /*******************************************************************************
984 **
985 ** Function         GKI_getfirst
986 **
987 ** Description      Return a pointer to the first buffer in a queue
988 **
989 ** Parameters:      p_q  - (input) pointer to a queue.
990 **
991 ** Returns          NULL if queue is empty, else buffer address
992 **
993 *******************************************************************************/
GKI_getfirst(BUFFER_Q * p_q)994 void *GKI_getfirst (BUFFER_Q *p_q)
995 {
996     return (p_q->p_first);
997 }
998 
999 /*******************************************************************************
1000 **
1001 ** Function         GKI_getlast
1002 **
1003 ** Description      Return a pointer to the last buffer in a queue
1004 **
1005 ** Parameters:      p_q  - (input) pointer to a queue.
1006 **
1007 ** Returns          NULL if queue is empty, else buffer address
1008 **
1009 *******************************************************************************/
GKI_getlast(BUFFER_Q * p_q)1010 void *GKI_getlast (BUFFER_Q *p_q)
1011 {
1012     return (p_q->p_last);
1013 }
1014 
1015 /*******************************************************************************
1016 **
1017 ** Function         GKI_getnext
1018 **
1019 ** Description      Return a pointer to the next buffer in a queue
1020 **
1021 ** Parameters:      p_buf  - (input) pointer to the buffer to find the next one from.
1022 **
1023 ** Returns          NULL if no more buffers in the queue, else next buffer address
1024 **
1025 *******************************************************************************/
GKI_getnext(void * p_buf)1026 void *GKI_getnext (void *p_buf)
1027 {
1028     BUFFER_HDR_T    *p_hdr;
1029 
1030     p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
1031 
1032     if (p_hdr->p_next)
1033         return ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
1034     else
1035         return (NULL);
1036 }
1037 
1038 
1039 
1040 /*******************************************************************************
1041 **
1042 ** Function         GKI_queue_is_empty
1043 **
1044 ** Description      Check the status of a queue.
1045 **
1046 ** Parameters:      p_q  - (input) pointer to a queue.
1047 **
1048 ** Returns          TRUE if queue is empty, else FALSE
1049 **
1050 *******************************************************************************/
GKI_queue_is_empty(BUFFER_Q * p_q)1051 BOOLEAN GKI_queue_is_empty(BUFFER_Q *p_q)
1052 {
1053     return ((BOOLEAN) (p_q->count == 0));
1054 }
1055 
1056 /*******************************************************************************
1057 **
1058 ** Function         GKI_find_buf_start
1059 **
1060 ** Description      This function is called with an address inside a buffer,
1061 **                  and returns the start address ofthe buffer.
1062 **
1063 **                  The buffer should be one allocated from one of GKI's pools.
1064 **
1065 ** Parameters:      p_user_area - (input) address of anywhere in a GKI buffer.
1066 **
1067 ** Returns          void * - Address of the beginning of the specified buffer if successful,
1068 **                          otherwise NULL if unsuccessful
1069 **
1070 *******************************************************************************/
GKI_find_buf_start(void * p_user_area)1071 void *GKI_find_buf_start (void *p_user_area)
1072 {
1073     UINT16       xx, size;
1074     UINT32       yy;
1075     tGKI_COM_CB *p_cb = &gki_cb.com;
1076     UINT8       *p_ua = (UINT8 *)p_user_area;
1077 
1078     for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
1079     {
1080         if ((p_ua > p_cb->pool_start[xx]) && (p_ua < p_cb->pool_end[xx]))
1081         {
1082             yy = (UINT32)(p_ua - p_cb->pool_start[xx]);
1083 
1084             size = p_cb->pool_size[xx];
1085 
1086             yy = (yy / size) * size;
1087 
1088             return ((void *) (p_cb->pool_start[xx] + yy + sizeof(BUFFER_HDR_T)) );
1089         }
1090     }
1091 
1092     /* If here, invalid address - not in one of our buffers */
1093     GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "GKI_get_buf_start:: bad addr");
1094 
1095     return (NULL);
1096 }
1097 
1098 
1099 /********************************************************
1100 * The following functions are not needed for light stack
1101 *********************************************************/
1102 #if (!defined(BTU_STACK_LITE_ENABLED) || BTU_STACK_LITE_ENABLED == FALSE)
1103 
1104 /*******************************************************************************
1105 **
1106 ** Function         GKI_set_pool_permission
1107 **
1108 ** Description      This function is called to set or change the permissions for
1109 **                  the specified pool ID.
1110 **
1111 ** Parameters       pool_id -       (input) pool ID to be set or changed
1112 **                  permission -    (input) GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL
1113 **
1114 ** Returns          GKI_SUCCESS if successful
1115 **                  GKI_INVALID_POOL if unsuccessful
1116 **
1117 *******************************************************************************/
GKI_set_pool_permission(UINT8 pool_id,UINT8 permission)1118 UINT8 GKI_set_pool_permission(UINT8 pool_id, UINT8 permission)
1119 {
1120     tGKI_COM_CB *p_cb = &gki_cb.com;
1121 
1122     if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
1123     {
1124         if (permission == GKI_RESTRICTED_POOL)
1125             p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask | (1 << pool_id));
1126 
1127         else    /* mark the pool as public */
1128             p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask & ~(1 << pool_id));
1129 
1130         return (GKI_SUCCESS);
1131     }
1132     else
1133         return (GKI_INVALID_POOL);
1134 }
1135 
1136 /*******************************************************************************
1137 **
1138 ** Function         gki_add_to_pool_list
1139 **
1140 ** Description      Adds pool to the pool list which is arranged in the
1141 **                  order of size
1142 **
1143 ** Returns          void
1144 **
1145 *******************************************************************************/
gki_add_to_pool_list(UINT8 pool_id)1146 static void gki_add_to_pool_list(UINT8 pool_id)
1147 {
1148 
1149     INT32 i, j;
1150     tGKI_COM_CB *p_cb = &gki_cb.com;
1151 
1152      /* Find the position where the specified pool should be inserted into the list */
1153     for(i=0; i < p_cb->curr_total_no_of_pools; i++)
1154     {
1155 
1156         if(p_cb->freeq[pool_id].size <= p_cb->freeq[ p_cb->pool_list[i] ].size)
1157             break;
1158     }
1159 
1160     /* Insert the new buffer pool ID into the list of pools */
1161     for(j = p_cb->curr_total_no_of_pools; j > i; j--)
1162     {
1163         p_cb->pool_list[j] = p_cb->pool_list[j-1];
1164     }
1165 
1166     p_cb->pool_list[i] = pool_id;
1167 
1168     return;
1169 }
1170 
1171 /*******************************************************************************
1172 **
1173 ** Function         gki_remove_from_pool_list
1174 **
1175 ** Description      Removes pool from the pool list. Called when a pool is deleted
1176 **
1177 ** Returns          void
1178 **
1179 *******************************************************************************/
gki_remove_from_pool_list(UINT8 pool_id)1180 static void gki_remove_from_pool_list(UINT8 pool_id)
1181 {
1182     tGKI_COM_CB *p_cb = &gki_cb.com;
1183     UINT8 i;
1184 
1185     for(i=0; i < p_cb->curr_total_no_of_pools; i++)
1186     {
1187         if(pool_id == p_cb->pool_list[i])
1188             break;
1189     }
1190 
1191     while (i < (p_cb->curr_total_no_of_pools - 1))
1192     {
1193         p_cb->pool_list[i] = p_cb->pool_list[i+1];
1194         i++;
1195     }
1196 
1197     return;
1198 }
1199 
1200 /*******************************************************************************
1201 **
1202 ** Function         GKI_igetpoolbuf
1203 **
1204 ** Description      Called by an interrupt service routine to get a free buffer from
1205 **                  a specific buffer pool.
1206 **
1207 ** Parameters       pool_id - (input) pool ID to get a buffer out of.
1208 **
1209 ** Returns          A pointer to the buffer, or NULL if none available
1210 **
1211 *******************************************************************************/
GKI_igetpoolbuf(UINT8 pool_id)1212 void *GKI_igetpoolbuf (UINT8 pool_id)
1213 {
1214     FREE_QUEUE_T  *Q;
1215     BUFFER_HDR_T  *p_hdr;
1216 
1217     if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1218         return (NULL);
1219 
1220 
1221     Q = &gki_cb.com.freeq[pool_id];
1222     if(Q->cur_cnt < Q->total)
1223     {
1224         p_hdr = Q->p_first;
1225         Q->p_first = p_hdr->p_next;
1226 
1227         if (!Q->p_first)
1228             Q->p_last = NULL;
1229 
1230         if(++Q->cur_cnt > Q->max_cnt)
1231             Q->max_cnt = Q->cur_cnt;
1232 
1233         p_hdr->task_id = GKI_get_taskid();
1234 
1235         p_hdr->status  = BUF_STATUS_UNLINKED;
1236         p_hdr->p_next  = NULL;
1237         p_hdr->Type    = 0;
1238 
1239         return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
1240     }
1241 
1242     return (NULL);
1243 }
1244 
1245 /*******************************************************************************
1246 **
1247 ** Function         GKI_poolcount
1248 **
1249 ** Description      Called by an application to get the total number of buffers
1250 **                  in the specified buffer pool.
1251 **
1252 ** Parameters       pool_id - (input) pool ID to get the free count of.
1253 **
1254 ** Returns          the total number of buffers in the pool
1255 **
1256 *******************************************************************************/
GKI_poolcount(UINT8 pool_id)1257 UINT16 GKI_poolcount (UINT8 pool_id)
1258 {
1259     if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1260         return (0);
1261 
1262     return (gki_cb.com.freeq[pool_id].total);
1263 }
1264 
1265 /*******************************************************************************
1266 **
1267 ** Function         GKI_poolfreecount
1268 **
1269 ** Description      Called by an application to get the number of free buffers
1270 **                  in the specified buffer pool.
1271 **
1272 ** Parameters       pool_id - (input) pool ID to get the free count of.
1273 **
1274 ** Returns          the number of free buffers in the pool
1275 **
1276 *******************************************************************************/
GKI_poolfreecount(UINT8 pool_id)1277 UINT16 GKI_poolfreecount (UINT8 pool_id)
1278 {
1279     FREE_QUEUE_T  *Q;
1280 
1281     if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1282         return (0);
1283 
1284     Q  = &gki_cb.com.freeq[pool_id];
1285 
1286     return ((UINT16)(Q->total - Q->cur_cnt));
1287 }
1288 
1289 /*******************************************************************************
1290 **
1291 ** Function         GKI_change_buf_owner
1292 **
1293 ** Description      Called to change the task ownership of a buffer.
1294 **
1295 ** Parameters:      p_buf   - (input) pointer to the buffer
1296 **                  task_id - (input) task id to change ownership to
1297 **
1298 ** Returns          void
1299 **
1300 *******************************************************************************/
GKI_change_buf_owner(void * p_buf,UINT8 task_id)1301 void GKI_change_buf_owner (void *p_buf, UINT8 task_id)
1302 {
1303     BUFFER_HDR_T    *p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
1304 
1305     p_hdr->task_id = task_id;
1306 
1307     return;
1308 }
1309 
1310 #if (defined(GKI_SEND_MSG_FROM_ISR) &&  GKI_SEND_MSG_FROM_ISR == TRUE)
1311 /*******************************************************************************
1312 **
1313 ** Function         GKI_isend_msg
1314 **
1315 ** Description      Called from interrupt context to send a buffer to a task
1316 **
1317 ** Returns          Nothing
1318 **
1319 *******************************************************************************/
GKI_isend_msg(UINT8 task_id,UINT8 mbox,void * msg)1320 void GKI_isend_msg (UINT8 task_id, UINT8 mbox, void *msg)
1321 {
1322     BUFFER_HDR_T    *p_hdr;
1323     tGKI_COM_CB *p_cb = &gki_cb.com;
1324 
1325     /* If task non-existant or not started, drop buffer */
1326     if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
1327     {
1328         GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
1329         GKI_freebuf (msg);
1330         return;
1331     }
1332 
1333 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
1334     if (gki_chk_buf_damage(msg))
1335     {
1336         GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
1337         return;
1338     }
1339 #endif
1340 
1341 #if (GKI_ENABLE_OWNER_CHECK == TRUE)
1342     if (gki_chk_buf_owner(msg))
1343     {
1344         GKI_exception(GKI_ERROR_NOT_BUF_OWNER, "Send by non-owner");
1345         return;
1346     }
1347 #endif
1348 
1349     p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
1350 
1351     if (p_hdr->status != BUF_STATUS_UNLINKED)
1352     {
1353         GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
1354         return;
1355     }
1356 
1357     if (p_cb->OSTaskQFirst[task_id][mbox])
1358         p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
1359     else
1360         p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
1361 
1362     p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
1363 
1364     p_hdr->p_next = NULL;
1365     p_hdr->status = BUF_STATUS_QUEUED;
1366     p_hdr->task_id = task_id;
1367 
1368     GKI_isend_event(task_id, (UINT16)EVENT_MASK(mbox));
1369 
1370     return;
1371 }
1372 #endif
1373 
1374 /*******************************************************************************
1375 **
1376 ** Function         GKI_create_pool
1377 **
1378 ** Description      Called by applications to create a buffer pool.
1379 **
1380 ** Parameters:      size        - (input) length (in bytes) of each buffer in the pool
1381 **                  count       - (input) number of buffers to allocate for the pool
1382 **                  permission  - (input) restricted or public access?
1383 **                                        (GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL)
1384 **                  p_mem_pool  - (input) pointer to an OS memory pool, NULL if not provided
1385 **
1386 ** Returns          the buffer pool ID, which should be used in calls to
1387 **                  GKI_getpoolbuf(). If a pool could not be created, this
1388 **                  function returns 0xff.
1389 **
1390 *******************************************************************************/
GKI_create_pool(UINT16 size,UINT16 count,UINT8 permission,void * p_mem_pool)1391 UINT8 GKI_create_pool (UINT16 size, UINT16 count, UINT8 permission, void *p_mem_pool)
1392 {
1393     UINT8        xx;
1394     UINT32       mem_needed;
1395     INT32        tempsize = size;
1396     tGKI_COM_CB *p_cb = &gki_cb.com;
1397 
1398     /* First make sure the size of each pool has a valid size with room for the header info */
1399     if (size > MAX_USER_BUF_SIZE)
1400         return (GKI_INVALID_POOL);
1401 
1402     /* First, look for an unused pool */
1403     for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
1404     {
1405         if (!p_cb->pool_start[xx])
1406             break;
1407     }
1408 
1409     if (xx == GKI_NUM_TOTAL_BUF_POOLS)
1410         return (GKI_INVALID_POOL);
1411 
1412     /* Ensure an even number of longwords */
1413     tempsize = (INT32)ALIGN_POOL(size);
1414 
1415     mem_needed = (tempsize + BUFFER_PADDING_SIZE) * count;
1416 
1417     if (!p_mem_pool)
1418         p_mem_pool = GKI_os_malloc(mem_needed);
1419 
1420     if (p_mem_pool)
1421     {
1422         /* Initialize the new pool */
1423         gki_init_free_queue (xx, size, count, p_mem_pool);
1424         gki_add_to_pool_list(xx);
1425         (void) GKI_set_pool_permission (xx, permission);
1426         p_cb->curr_total_no_of_pools++;
1427 
1428         return (xx);
1429     }
1430     else
1431         return (GKI_INVALID_POOL);
1432 }
1433 
1434 /*******************************************************************************
1435 **
1436 ** Function         GKI_delete_pool
1437 **
1438 ** Description      Called by applications to delete a buffer pool.  The function
1439 **                  calls the operating specific function to free the actual memory.
1440 **                  An exception is generated if an error is detected.
1441 **
1442 ** Parameters:      pool_id - (input) Id of the poll being deleted.
1443 **
1444 ** Returns          void
1445 **
1446 *******************************************************************************/
GKI_delete_pool(UINT8 pool_id)1447 void GKI_delete_pool (UINT8 pool_id)
1448 {
1449     FREE_QUEUE_T    *Q;
1450     tGKI_COM_CB     *p_cb = &gki_cb.com;
1451 
1452     if ((pool_id >= GKI_NUM_TOTAL_BUF_POOLS) || (!p_cb->pool_start[pool_id]))
1453         return;
1454 
1455     GKI_disable();
1456     Q  = &p_cb->freeq[pool_id];
1457 
1458     if (!Q->cur_cnt)
1459     {
1460         Q->size      = 0;
1461         Q->total     = 0;
1462         Q->cur_cnt   = 0;
1463         Q->max_cnt   = 0;
1464         Q->p_first   = NULL;
1465         Q->p_last    = NULL;
1466 
1467         GKI_os_free (p_cb->pool_start[pool_id]);
1468 
1469         p_cb->pool_start[pool_id] = NULL;
1470         p_cb->pool_end[pool_id]   = NULL;
1471         p_cb->pool_size[pool_id]  = 0;
1472 
1473         gki_remove_from_pool_list(pool_id);
1474         p_cb->curr_total_no_of_pools--;
1475     }
1476     else
1477         GKI_exception(GKI_ERROR_DELETE_POOL_BAD_QID, "Deleting bad pool");
1478 
1479     GKI_enable();
1480 
1481     return;
1482 }
1483 
1484 #endif /*  BTU_STACK_LITE_ENABLED == FALSE */
1485 
1486 /*******************************************************************************
1487 **
1488 ** Function         GKI_get_pool_bufsize
1489 **
1490 ** Description      Called by an application to get the size of buffers in a pool
1491 **
1492 ** Parameters       Pool ID.
1493 **
1494 ** Returns          the size of buffers in the pool
1495 **
1496 *******************************************************************************/
GKI_get_pool_bufsize(UINT8 pool_id)1497 UINT16 GKI_get_pool_bufsize (UINT8 pool_id)
1498 {
1499     if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
1500         return (gki_cb.com.freeq[pool_id].size);
1501 
1502     return (0);
1503 }
1504 
1505 /*******************************************************************************
1506 **
1507 ** Function         GKI_poolutilization
1508 **
1509 ** Description      Called by an application to get the buffer utilization
1510 **                  in the specified buffer pool.
1511 **
1512 ** Parameters       pool_id - (input) pool ID to get the free count of.
1513 **
1514 ** Returns          % of buffers used from 0 to 100
1515 **
1516 *******************************************************************************/
GKI_poolutilization(UINT8 pool_id)1517 UINT16 GKI_poolutilization (UINT8 pool_id)
1518 {
1519     FREE_QUEUE_T  *Q;
1520 
1521     if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1522         return (100);
1523 
1524     Q  = &gki_cb.com.freeq[pool_id];
1525 
1526     if (Q->total == 0)
1527         return (100);
1528 
1529     return ((Q->cur_cnt * 100) / Q->total);
1530 }
1531 
1532