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