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)
26static void gki_add_to_pool_list(UINT8 pool_id);
27static 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*******************************************************************************/
46static 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
101static 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*******************************************************************************/
145void 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*******************************************************************************/
331void 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
357void *GKI_getbuf_debug (UINT16 size, const char * _function_, int _line_)
358#else
359void *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                return NULL;
411            }
412        #endif
413
414            if(Q->p_first == 0)
415            {
416                /* gki_alloc_free_queue() failed to alloc memory */
417                GKI_TRACE_ERROR_0("GKI_getbuf() fail alloc free queue");
418                return NULL;
419            }
420
421            p_hdr = Q->p_first;
422            Q->p_first = p_hdr->p_next;
423
424            if (!Q->p_first)
425                Q->p_last = NULL;
426
427            if(++Q->cur_cnt > Q->max_cnt)
428                Q->max_cnt = Q->cur_cnt;
429
430            GKI_enable();
431
432            p_hdr->task_id = GKI_get_taskid();
433
434            p_hdr->status  = BUF_STATUS_UNLINKED;
435            p_hdr->p_next  = NULL;
436            p_hdr->Type    = 0;
437#if GKI_BUFFER_DEBUG
438            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);
439
440            strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
441            p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
442            p_hdr->_line = _line_;
443#endif
444            return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
445        }
446    }
447
448    GKI_TRACE_ERROR_0("GKI_getbuf() unable to allocate buffer!!!!!");
449#if GKI_BUFFER_DEBUG
450    LOGD("GKI_getbuf() unable to allocate buffer!!!!!");
451    LOGD("******************** GKI Memory Pool Dump ********************");
452
453    p_cb = &gki_cb.com;
454
455    LOGD("Dumping total of %d buffer pools", p_cb->curr_total_no_of_pools);
456
457    for (i=0 ; i < p_cb->curr_total_no_of_pools; i++)
458    {
459        p_hdr = (BUFFER_HDR_T *)p_cb->pool_start[i];
460
461        LOGD("pool %d has a total of %d buffers (start=%p)", i, p_cb->freeq[i].total, p_hdr);
462
463        for (x=0; p_hdr && x < p_cb->freeq[i].total; x++)
464        {
465            if (p_hdr->status != BUF_STATUS_FREE)
466            {
467                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);
468            }
469
470            p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_hdr + p_cb->pool_size[i]);
471        }
472    }
473    LOGD("**************************************************************");
474#endif
475
476    GKI_TRACE_ERROR_0("Failed to allocate GKI buffer");
477
478    GKI_enable();
479
480    return (NULL);
481}
482
483
484/*******************************************************************************
485**
486** Function         GKI_getpoolbuf
487**
488** Description      Called by an application to get a free buffer from
489**                  a specific buffer pool.
490**
491**                  Note: If there are no more buffers available from the pool,
492**                        the public buffers are searched for an available buffer.
493**
494** Parameters       pool_id - (input) pool ID to get a buffer out of.
495**
496** Returns          A pointer to the buffer, or NULL if none available
497**
498*******************************************************************************/
499#if GKI_BUFFER_DEBUG
500void *GKI_getpoolbuf_debug (UINT8 pool_id, const char * _function_, int _line_)
501#else
502void *GKI_getpoolbuf (UINT8 pool_id)
503#endif
504{
505    FREE_QUEUE_T  *Q;
506    BUFFER_HDR_T  *p_hdr;
507    tGKI_COM_CB *p_cb = &gki_cb.com;
508
509    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
510        return (NULL);
511
512#if GKI_BUFFER_DEBUG
513    LOGD("GKI_getpoolbuf() requesting from %d func:%s(line=%d)", pool_id, _function_, _line_);
514#endif
515    /* Make sure the buffers aren't disturbed til finished with allocation */
516    GKI_disable();
517
518    Q = &p_cb->freeq[pool_id];
519    if(Q->cur_cnt < Q->total)
520    {
521#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
522        if(Q->p_first == 0 && gki_alloc_free_queue(pool_id) != TRUE)
523            return NULL;
524#endif
525
526        if(Q->p_first == 0)
527        {
528            /* gki_alloc_free_queue() failed to alloc memory */
529            GKI_TRACE_ERROR_0("GKI_getpoolbuf() fail alloc free queue");
530            return NULL;
531        }
532
533        p_hdr = Q->p_first;
534        Q->p_first = p_hdr->p_next;
535
536        if (!Q->p_first)
537            Q->p_last = NULL;
538
539        if(++Q->cur_cnt > Q->max_cnt)
540            Q->max_cnt = Q->cur_cnt;
541
542        GKI_enable();
543
544
545        p_hdr->task_id = GKI_get_taskid();
546
547        p_hdr->status  = BUF_STATUS_UNLINKED;
548        p_hdr->p_next  = NULL;
549        p_hdr->Type    = 0;
550
551#if GKI_BUFFER_DEBUG
552        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);
553
554        strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
555        p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
556        p_hdr->_line = _line_;
557#endif
558        return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
559    }
560
561    /* If here, no buffers in the specified pool */
562    GKI_enable();
563
564#if GKI_BUFFER_DEBUG
565    /* try for free buffers in public pools */
566    return (GKI_getbuf_debug(p_cb->freeq[pool_id].size, _function_, _line_));
567#else
568    /* try for free buffers in public pools */
569    return (GKI_getbuf(p_cb->freeq[pool_id].size));
570#endif
571}
572
573/*******************************************************************************
574**
575** Function         GKI_freebuf
576**
577** Description      Called by an application to return a buffer to the free pool.
578**
579** Parameters       p_buf - (input) address of the beginning of a buffer.
580**
581** Returns          void
582**
583*******************************************************************************/
584void GKI_freebuf (void *p_buf)
585{
586    FREE_QUEUE_T    *Q;
587    BUFFER_HDR_T    *p_hdr;
588
589#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
590    if (!p_buf || gki_chk_buf_damage(p_buf))
591    {
592        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Free - Buf Corrupted");
593        return;
594    }
595#endif
596
597    p_hdr = (BUFFER_HDR_T *) ((UINT8 *)p_buf - BUFFER_HDR_SIZE);
598
599#if GKI_BUFFER_DEBUG
600    LOGD("GKI_freebuf() freeing, %x, %x, func:%s(line=%d)", p_buf, p_hdr, p_hdr->_function, p_hdr->_line);
601#endif
602
603    if (p_hdr->status != BUF_STATUS_UNLINKED)
604    {
605        GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf");
606        return;
607    }
608
609    if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS)
610    {
611        GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId");
612        return;
613    }
614
615    GKI_disable();
616
617    /*
618    ** Release the buffer
619    */
620    Q  = &gki_cb.com.freeq[p_hdr->q_id];
621    if (Q->p_last)
622        Q->p_last->p_next = p_hdr;
623    else
624        Q->p_first = p_hdr;
625
626    Q->p_last      = p_hdr;
627    p_hdr->p_next  = NULL;
628    p_hdr->status  = BUF_STATUS_FREE;
629    p_hdr->task_id = GKI_INVALID_TASK;
630    if (Q->cur_cnt > 0)
631        Q->cur_cnt--;
632
633    GKI_enable();
634
635    return;
636}
637
638
639/*******************************************************************************
640**
641** Function         GKI_get_buf_size
642**
643** Description      Called by an application to get the size of a buffer.
644**
645** Parameters       p_buf - (input) address of the beginning of a buffer.
646**
647** Returns          the size of the buffer
648**
649*******************************************************************************/
650UINT16 GKI_get_buf_size (void *p_buf)
651{
652    BUFFER_HDR_T    *p_hdr;
653
654    p_hdr = (BUFFER_HDR_T *)((UINT8 *) p_buf - BUFFER_HDR_SIZE);
655
656    if ((UINT32)p_hdr & 1)
657        return (0);
658
659    if (p_hdr->q_id < GKI_NUM_TOTAL_BUF_POOLS)
660    {
661        return (gki_cb.com.freeq[p_hdr->q_id].size);
662    }
663
664    return (0);
665}
666
667/*******************************************************************************
668**
669** Function         gki_chk_buf_damage
670**
671** Description      Called internally by OSS to check for buffer corruption.
672**
673** Returns          TRUE if there is a problem, else FALSE
674**
675*******************************************************************************/
676BOOLEAN gki_chk_buf_damage(void *p_buf)
677{
678#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
679
680    UINT32 *magic;
681    magic  = (UINT32 *)((UINT8 *) p_buf + GKI_get_buf_size(p_buf));
682
683    if ((UINT32)magic & 1)
684        return (TRUE);
685
686    if (*magic == MAGIC_NO)
687        return (FALSE);
688
689    return (TRUE);
690
691#else
692
693    return (FALSE);
694
695#endif
696}
697
698/*******************************************************************************
699**
700** Function         GKI_send_msg
701**
702** Description      Called by applications to send a buffer to a task
703**
704** Returns          Nothing
705**
706*******************************************************************************/
707void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)
708{
709    BUFFER_HDR_T    *p_hdr;
710    tGKI_COM_CB *p_cb = &gki_cb.com;
711
712    /* If task non-existant or not started, drop buffer */
713    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
714    {
715        GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
716        GKI_freebuf (msg);
717        return;
718    }
719
720#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
721    if (gki_chk_buf_damage(msg))
722    {
723        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
724        return;
725    }
726#endif
727
728    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
729
730    if (p_hdr->status != BUF_STATUS_UNLINKED)
731    {
732        GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
733        return;
734    }
735
736    GKI_disable();
737
738    if (p_cb->OSTaskQFirst[task_id][mbox])
739        p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
740    else
741        p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
742
743    p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
744
745    p_hdr->p_next = NULL;
746    p_hdr->status = BUF_STATUS_QUEUED;
747    p_hdr->task_id = task_id;
748
749
750    GKI_enable();
751
752    GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));
753
754    return;
755}
756
757/*******************************************************************************
758**
759** Function         GKI_read_mbox
760**
761** Description      Called by applications to read a buffer from one of
762**                  the task mailboxes.  A task can only read its own mailbox.
763**
764** Parameters:      mbox  - (input) mailbox ID to read (0, 1, 2, or 3)
765**
766** Returns          NULL if the mailbox was empty, else the address of a buffer
767**
768*******************************************************************************/
769void *GKI_read_mbox (UINT8 mbox)
770{
771    UINT8           task_id = GKI_get_taskid();
772    void            *p_buf = NULL;
773    BUFFER_HDR_T    *p_hdr;
774
775    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX))
776        return (NULL);
777
778    GKI_disable();
779
780    if (gki_cb.com.OSTaskQFirst[task_id][mbox])
781    {
782        p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];
783        gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
784
785        p_hdr->p_next = NULL;
786        p_hdr->status = BUF_STATUS_UNLINKED;
787
788        p_buf = (UINT8 *)p_hdr + BUFFER_HDR_SIZE;
789    }
790
791    GKI_enable();
792
793    return (p_buf);
794}
795
796
797
798/*******************************************************************************
799**
800** Function         GKI_enqueue
801**
802** Description      Enqueue a buffer at the tail of the queue
803**
804** Parameters:      p_q  -  (input) pointer to a queue.
805**                  p_buf - (input) address of the buffer to enqueue
806**
807** Returns          void
808**
809*******************************************************************************/
810void GKI_enqueue (BUFFER_Q *p_q, void *p_buf)
811{
812    BUFFER_HDR_T    *p_hdr;
813
814#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
815    if (gki_chk_buf_damage(p_buf))
816    {
817        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
818        return;
819    }
820#endif
821
822    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
823
824    if (p_hdr->status != BUF_STATUS_UNLINKED)
825    {
826        GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue - buf already linked");
827        return;
828    }
829
830    GKI_disable();
831
832    /* Since the queue is exposed (C vs C++), keep the pointers in exposed format */
833    if (p_q->p_first)
834    {
835        BUFFER_HDR_T *p_last_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_last - BUFFER_HDR_SIZE);
836        p_last_hdr->p_next = p_hdr;
837    }
838    else
839        p_q->p_first = p_buf;
840
841    p_q->p_last = p_buf;
842    p_q->count++;
843
844    p_hdr->p_next = NULL;
845    p_hdr->status = BUF_STATUS_QUEUED;
846
847    GKI_enable();
848
849    return;
850}
851
852
853/*******************************************************************************
854**
855** Function         GKI_enqueue_head
856**
857** Description      Enqueue a buffer at the head of the queue
858**
859** Parameters:      p_q  -  (input) pointer to a queue.
860**                  p_buf - (input) address of the buffer to enqueue
861**
862** Returns          void
863**
864*******************************************************************************/
865void GKI_enqueue_head (BUFFER_Q *p_q, void *p_buf)
866{
867    BUFFER_HDR_T    *p_hdr;
868
869#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
870    if (gki_chk_buf_damage(p_buf))
871    {
872        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
873        return;
874    }
875#endif
876
877    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
878
879    if (p_hdr->status != BUF_STATUS_UNLINKED)
880    {
881        GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue head - buf already linked");
882        return;
883    }
884
885    GKI_disable();
886
887    if (p_q->p_first)
888    {
889        p_hdr->p_next = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
890        p_q->p_first = p_buf;
891    }
892    else
893    {
894        p_q->p_first = p_buf;
895        p_q->p_last  = p_buf;
896        p_hdr->p_next = NULL;
897    }
898    p_q->count++;
899
900    p_hdr->status = BUF_STATUS_QUEUED;
901
902    GKI_enable();
903
904    return;
905}
906
907
908/*******************************************************************************
909**
910** Function         GKI_dequeue
911**
912** Description      Dequeues a buffer from the head of a queue
913**
914** Parameters:      p_q  - (input) pointer to a queue.
915**
916** Returns          NULL if queue is empty, else buffer
917**
918*******************************************************************************/
919void *GKI_dequeue (BUFFER_Q *p_q)
920{
921    BUFFER_HDR_T    *p_hdr;
922
923    GKI_disable();
924
925    if (!p_q || !p_q->count)
926    {
927        GKI_enable();
928        return (NULL);
929    }
930
931    p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
932
933    /* Keep buffers such that GKI header is invisible
934    */
935    if (p_hdr->p_next)
936        p_q->p_first = ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
937    else
938    {
939        p_q->p_first = NULL;
940        p_q->p_last  = NULL;
941    }
942
943    p_q->count--;
944
945    p_hdr->p_next = NULL;
946    p_hdr->status = BUF_STATUS_UNLINKED;
947
948    GKI_enable();
949
950    return ((UINT8 *)p_hdr + BUFFER_HDR_SIZE);
951}
952
953
954/*******************************************************************************
955**
956** Function         GKI_remove_from_queue
957**
958** Description      Dequeue a buffer from the middle of the queue
959**
960** Parameters:      p_q  - (input) pointer to a queue.
961**                  p_buf - (input) address of the buffer to enqueue
962**
963** Returns          NULL if queue is empty, else buffer
964**
965*******************************************************************************/
966void *GKI_remove_from_queue (BUFFER_Q *p_q, void *p_buf)
967{
968    BUFFER_HDR_T    *p_prev;
969    BUFFER_HDR_T    *p_buf_hdr;
970
971    GKI_disable();
972
973    if (p_buf == p_q->p_first)
974    {
975        GKI_enable();
976        return (GKI_dequeue (p_q));
977    }
978
979    p_buf_hdr = (BUFFER_HDR_T *)((UINT8 *)p_buf - BUFFER_HDR_SIZE);
980    p_prev    = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
981
982    for ( ; p_prev; p_prev = p_prev->p_next)
983    {
984        /* If the previous points to this one, move the pointers around */
985        if (p_prev->p_next == p_buf_hdr)
986        {
987            p_prev->p_next = p_buf_hdr->p_next;
988
989            /* If we are removing the last guy in the queue, update p_last */
990            if (p_buf == p_q->p_last)
991                p_q->p_last = p_prev + 1;
992
993            /* One less in the queue */
994            p_q->count--;
995
996            /* The buffer is now unlinked */
997            p_buf_hdr->p_next = NULL;
998            p_buf_hdr->status = BUF_STATUS_UNLINKED;
999
1000            GKI_enable();
1001            return (p_buf);
1002        }
1003    }
1004
1005    GKI_enable();
1006    return (NULL);
1007}
1008
1009/*******************************************************************************
1010**
1011** Function         GKI_getfirst
1012**
1013** Description      Return a pointer to the first buffer in a queue
1014**
1015** Parameters:      p_q  - (input) pointer to a queue.
1016**
1017** Returns          NULL if queue is empty, else buffer address
1018**
1019*******************************************************************************/
1020void *GKI_getfirst (BUFFER_Q *p_q)
1021{
1022    return (p_q->p_first);
1023}
1024
1025/*******************************************************************************
1026**
1027** Function         GKI_getlast
1028**
1029** Description      Return a pointer to the last buffer in a queue
1030**
1031** Parameters:      p_q  - (input) pointer to a queue.
1032**
1033** Returns          NULL if queue is empty, else buffer address
1034**
1035*******************************************************************************/
1036void *GKI_getlast (BUFFER_Q *p_q)
1037{
1038    return (p_q->p_last);
1039}
1040
1041/*******************************************************************************
1042**
1043** Function         GKI_getnext
1044**
1045** Description      Return a pointer to the next buffer in a queue
1046**
1047** Parameters:      p_buf  - (input) pointer to the buffer to find the next one from.
1048**
1049** Returns          NULL if no more buffers in the queue, else next buffer address
1050**
1051*******************************************************************************/
1052void *GKI_getnext (void *p_buf)
1053{
1054    BUFFER_HDR_T    *p_hdr;
1055
1056    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
1057
1058    if (p_hdr->p_next)
1059        return ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
1060    else
1061        return (NULL);
1062}
1063
1064
1065
1066/*******************************************************************************
1067**
1068** Function         GKI_queue_is_empty
1069**
1070** Description      Check the status of a queue.
1071**
1072** Parameters:      p_q  - (input) pointer to a queue.
1073**
1074** Returns          TRUE if queue is empty, else FALSE
1075**
1076*******************************************************************************/
1077BOOLEAN GKI_queue_is_empty(BUFFER_Q *p_q)
1078{
1079    return ((BOOLEAN) (p_q->count == 0));
1080}
1081
1082/*******************************************************************************
1083**
1084** Function         GKI_find_buf_start
1085**
1086** Description      This function is called with an address inside a buffer,
1087**                  and returns the start address ofthe buffer.
1088**
1089**                  The buffer should be one allocated from one of GKI's pools.
1090**
1091** Parameters:      p_user_area - (input) address of anywhere in a GKI buffer.
1092**
1093** Returns          void * - Address of the beginning of the specified buffer if successful,
1094**                          otherwise NULL if unsuccessful
1095**
1096*******************************************************************************/
1097void *GKI_find_buf_start (void *p_user_area)
1098{
1099    UINT16       xx, size;
1100    UINT32       yy;
1101    tGKI_COM_CB *p_cb = &gki_cb.com;
1102    UINT8       *p_ua = (UINT8 *)p_user_area;
1103
1104    for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
1105    {
1106        if ((p_ua > p_cb->pool_start[xx]) && (p_ua < p_cb->pool_end[xx]))
1107        {
1108            yy = (UINT32)(p_ua - p_cb->pool_start[xx]);
1109
1110            size = p_cb->pool_size[xx];
1111
1112            yy = (yy / size) * size;
1113
1114            return ((void *) (p_cb->pool_start[xx] + yy + sizeof(BUFFER_HDR_T)) );
1115        }
1116    }
1117
1118    /* If here, invalid address - not in one of our buffers */
1119    GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "GKI_get_buf_start:: bad addr");
1120
1121    return (NULL);
1122}
1123
1124
1125/********************************************************
1126* The following functions are not needed for light stack
1127*********************************************************/
1128#if (!defined(BTU_STACK_LITE_ENABLED) || BTU_STACK_LITE_ENABLED == FALSE)
1129
1130/*******************************************************************************
1131**
1132** Function         GKI_set_pool_permission
1133**
1134** Description      This function is called to set or change the permissions for
1135**                  the specified pool ID.
1136**
1137** Parameters       pool_id -       (input) pool ID to be set or changed
1138**                  permission -    (input) GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL
1139**
1140** Returns          GKI_SUCCESS if successful
1141**                  GKI_INVALID_POOL if unsuccessful
1142**
1143*******************************************************************************/
1144UINT8 GKI_set_pool_permission(UINT8 pool_id, UINT8 permission)
1145{
1146    tGKI_COM_CB *p_cb = &gki_cb.com;
1147
1148    if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
1149    {
1150        if (permission == GKI_RESTRICTED_POOL)
1151            p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask | (1 << pool_id));
1152
1153        else    /* mark the pool as public */
1154            p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask & ~(1 << pool_id));
1155
1156        return (GKI_SUCCESS);
1157    }
1158    else
1159        return (GKI_INVALID_POOL);
1160}
1161
1162/*******************************************************************************
1163**
1164** Function         gki_add_to_pool_list
1165**
1166** Description      Adds pool to the pool list which is arranged in the
1167**                  order of size
1168**
1169** Returns          void
1170**
1171*******************************************************************************/
1172static void gki_add_to_pool_list(UINT8 pool_id)
1173{
1174
1175    INT32 i, j;
1176    tGKI_COM_CB *p_cb = &gki_cb.com;
1177
1178     /* Find the position where the specified pool should be inserted into the list */
1179    for(i=0; i < p_cb->curr_total_no_of_pools; i++)
1180    {
1181
1182        if(p_cb->freeq[pool_id].size <= p_cb->freeq[ p_cb->pool_list[i] ].size)
1183            break;
1184    }
1185
1186    /* Insert the new buffer pool ID into the list of pools */
1187    for(j = p_cb->curr_total_no_of_pools; j > i; j--)
1188    {
1189        p_cb->pool_list[j] = p_cb->pool_list[j-1];
1190    }
1191
1192    p_cb->pool_list[i] = pool_id;
1193
1194    return;
1195}
1196
1197/*******************************************************************************
1198**
1199** Function         gki_remove_from_pool_list
1200**
1201** Description      Removes pool from the pool list. Called when a pool is deleted
1202**
1203** Returns          void
1204**
1205*******************************************************************************/
1206static void gki_remove_from_pool_list(UINT8 pool_id)
1207{
1208    tGKI_COM_CB *p_cb = &gki_cb.com;
1209    UINT8 i;
1210
1211    for(i=0; i < p_cb->curr_total_no_of_pools; i++)
1212    {
1213        if(pool_id == p_cb->pool_list[i])
1214            break;
1215    }
1216
1217    while (i < (p_cb->curr_total_no_of_pools - 1))
1218    {
1219        p_cb->pool_list[i] = p_cb->pool_list[i+1];
1220        i++;
1221    }
1222
1223    return;
1224}
1225
1226/*******************************************************************************
1227**
1228** Function         GKI_igetpoolbuf
1229**
1230** Description      Called by an interrupt service routine to get a free buffer from
1231**                  a specific buffer pool.
1232**
1233** Parameters       pool_id - (input) pool ID to get a buffer out of.
1234**
1235** Returns          A pointer to the buffer, or NULL if none available
1236**
1237*******************************************************************************/
1238void *GKI_igetpoolbuf (UINT8 pool_id)
1239{
1240    FREE_QUEUE_T  *Q;
1241    BUFFER_HDR_T  *p_hdr;
1242
1243    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1244        return (NULL);
1245
1246
1247    Q = &gki_cb.com.freeq[pool_id];
1248    if(Q->cur_cnt < Q->total)
1249    {
1250        p_hdr = Q->p_first;
1251        Q->p_first = p_hdr->p_next;
1252
1253        if (!Q->p_first)
1254            Q->p_last = NULL;
1255
1256        if(++Q->cur_cnt > Q->max_cnt)
1257            Q->max_cnt = Q->cur_cnt;
1258
1259        p_hdr->task_id = GKI_get_taskid();
1260
1261        p_hdr->status  = BUF_STATUS_UNLINKED;
1262        p_hdr->p_next  = NULL;
1263        p_hdr->Type    = 0;
1264
1265        return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
1266    }
1267
1268    return (NULL);
1269}
1270
1271/*******************************************************************************
1272**
1273** Function         GKI_poolcount
1274**
1275** Description      Called by an application to get the total number of buffers
1276**                  in the specified buffer pool.
1277**
1278** Parameters       pool_id - (input) pool ID to get the free count of.
1279**
1280** Returns          the total number of buffers in the pool
1281**
1282*******************************************************************************/
1283UINT16 GKI_poolcount (UINT8 pool_id)
1284{
1285    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1286        return (0);
1287
1288    return (gki_cb.com.freeq[pool_id].total);
1289}
1290
1291/*******************************************************************************
1292**
1293** Function         GKI_poolfreecount
1294**
1295** Description      Called by an application to get the number of free buffers
1296**                  in the specified buffer pool.
1297**
1298** Parameters       pool_id - (input) pool ID to get the free count of.
1299**
1300** Returns          the number of free buffers in the pool
1301**
1302*******************************************************************************/
1303UINT16 GKI_poolfreecount (UINT8 pool_id)
1304{
1305    FREE_QUEUE_T  *Q;
1306
1307    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1308        return (0);
1309
1310    Q  = &gki_cb.com.freeq[pool_id];
1311
1312    return ((UINT16)(Q->total - Q->cur_cnt));
1313}
1314
1315/*******************************************************************************
1316**
1317** Function         GKI_change_buf_owner
1318**
1319** Description      Called to change the task ownership of a buffer.
1320**
1321** Parameters:      p_buf   - (input) pointer to the buffer
1322**                  task_id - (input) task id to change ownership to
1323**
1324** Returns          void
1325**
1326*******************************************************************************/
1327void GKI_change_buf_owner (void *p_buf, UINT8 task_id)
1328{
1329    BUFFER_HDR_T    *p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
1330
1331    p_hdr->task_id = task_id;
1332
1333    return;
1334}
1335
1336#if (defined(GKI_SEND_MSG_FROM_ISR) &&  GKI_SEND_MSG_FROM_ISR == TRUE)
1337/*******************************************************************************
1338**
1339** Function         GKI_isend_msg
1340**
1341** Description      Called from interrupt context to send a buffer to a task
1342**
1343** Returns          Nothing
1344**
1345*******************************************************************************/
1346void GKI_isend_msg (UINT8 task_id, UINT8 mbox, void *msg)
1347{
1348    BUFFER_HDR_T    *p_hdr;
1349    tGKI_COM_CB *p_cb = &gki_cb.com;
1350
1351    /* If task non-existant or not started, drop buffer */
1352    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
1353    {
1354        GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
1355        GKI_freebuf (msg);
1356        return;
1357    }
1358
1359#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
1360    if (gki_chk_buf_damage(msg))
1361    {
1362        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
1363        return;
1364    }
1365#endif
1366
1367#if (GKI_ENABLE_OWNER_CHECK == TRUE)
1368    if (gki_chk_buf_owner(msg))
1369    {
1370        GKI_exception(GKI_ERROR_NOT_BUF_OWNER, "Send by non-owner");
1371        return;
1372    }
1373#endif
1374
1375    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
1376
1377    if (p_hdr->status != BUF_STATUS_UNLINKED)
1378    {
1379        GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
1380        return;
1381    }
1382
1383    if (p_cb->OSTaskQFirst[task_id][mbox])
1384        p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
1385    else
1386        p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
1387
1388    p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
1389
1390    p_hdr->p_next = NULL;
1391    p_hdr->status = BUF_STATUS_QUEUED;
1392    p_hdr->task_id = task_id;
1393
1394    GKI_isend_event(task_id, (UINT16)EVENT_MASK(mbox));
1395
1396    return;
1397}
1398#endif
1399
1400/*******************************************************************************
1401**
1402** Function         GKI_create_pool
1403**
1404** Description      Called by applications to create a buffer pool.
1405**
1406** Parameters:      size        - (input) length (in bytes) of each buffer in the pool
1407**                  count       - (input) number of buffers to allocate for the pool
1408**                  permission  - (input) restricted or public access?
1409**                                        (GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL)
1410**                  p_mem_pool  - (input) pointer to an OS memory pool, NULL if not provided
1411**
1412** Returns          the buffer pool ID, which should be used in calls to
1413**                  GKI_getpoolbuf(). If a pool could not be created, this
1414**                  function returns 0xff.
1415**
1416*******************************************************************************/
1417UINT8 GKI_create_pool (UINT16 size, UINT16 count, UINT8 permission, void *p_mem_pool)
1418{
1419    UINT8        xx;
1420    UINT32       mem_needed;
1421    INT32        tempsize = size;
1422    tGKI_COM_CB *p_cb = &gki_cb.com;
1423
1424    /* First make sure the size of each pool has a valid size with room for the header info */
1425    if (size > MAX_USER_BUF_SIZE)
1426        return (GKI_INVALID_POOL);
1427
1428    /* First, look for an unused pool */
1429    for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
1430    {
1431        if (!p_cb->pool_start[xx])
1432            break;
1433    }
1434
1435    if (xx == GKI_NUM_TOTAL_BUF_POOLS)
1436        return (GKI_INVALID_POOL);
1437
1438    /* Ensure an even number of longwords */
1439    tempsize = (INT32)ALIGN_POOL(size);
1440
1441    mem_needed = (tempsize + BUFFER_PADDING_SIZE) * count;
1442
1443    if (!p_mem_pool)
1444        p_mem_pool = GKI_os_malloc(mem_needed);
1445
1446    if (p_mem_pool)
1447    {
1448        /* Initialize the new pool */
1449        gki_init_free_queue (xx, size, count, p_mem_pool);
1450        gki_add_to_pool_list(xx);
1451        (void) GKI_set_pool_permission (xx, permission);
1452        p_cb->curr_total_no_of_pools++;
1453
1454        return (xx);
1455    }
1456    else
1457        return (GKI_INVALID_POOL);
1458}
1459
1460/*******************************************************************************
1461**
1462** Function         GKI_delete_pool
1463**
1464** Description      Called by applications to delete a buffer pool.  The function
1465**                  calls the operating specific function to free the actual memory.
1466**                  An exception is generated if an error is detected.
1467**
1468** Parameters:      pool_id - (input) Id of the poll being deleted.
1469**
1470** Returns          void
1471**
1472*******************************************************************************/
1473void GKI_delete_pool (UINT8 pool_id)
1474{
1475    FREE_QUEUE_T    *Q;
1476    tGKI_COM_CB     *p_cb = &gki_cb.com;
1477
1478    if ((pool_id >= GKI_NUM_TOTAL_BUF_POOLS) || (!p_cb->pool_start[pool_id]))
1479        return;
1480
1481    GKI_disable();
1482    Q  = &p_cb->freeq[pool_id];
1483
1484    if (!Q->cur_cnt)
1485    {
1486        Q->size      = 0;
1487        Q->total     = 0;
1488        Q->cur_cnt   = 0;
1489        Q->max_cnt   = 0;
1490        Q->p_first   = NULL;
1491        Q->p_last    = NULL;
1492
1493        GKI_os_free (p_cb->pool_start[pool_id]);
1494
1495        p_cb->pool_start[pool_id] = NULL;
1496        p_cb->pool_end[pool_id]   = NULL;
1497        p_cb->pool_size[pool_id]  = 0;
1498
1499        gki_remove_from_pool_list(pool_id);
1500        p_cb->curr_total_no_of_pools--;
1501    }
1502    else
1503        GKI_exception(GKI_ERROR_DELETE_POOL_BAD_QID, "Deleting bad pool");
1504
1505    GKI_enable();
1506
1507    return;
1508}
1509
1510#endif /*  BTU_STACK_LITE_ENABLED == FALSE */
1511
1512/*******************************************************************************
1513**
1514** Function         GKI_get_pool_bufsize
1515**
1516** Description      Called by an application to get the size of buffers in a pool
1517**
1518** Parameters       Pool ID.
1519**
1520** Returns          the size of buffers in the pool
1521**
1522*******************************************************************************/
1523UINT16 GKI_get_pool_bufsize (UINT8 pool_id)
1524{
1525    if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
1526        return (gki_cb.com.freeq[pool_id].size);
1527
1528    return (0);
1529}
1530
1531/*******************************************************************************
1532**
1533** Function         GKI_poolutilization
1534**
1535** Description      Called by an application to get the buffer utilization
1536**                  in the specified buffer pool.
1537**
1538** Parameters       pool_id - (input) pool ID to get the free count of.
1539**
1540** Returns          % of buffers used from 0 to 100
1541**
1542*******************************************************************************/
1543UINT16 GKI_poolutilization (UINT8 pool_id)
1544{
1545    FREE_QUEUE_T  *Q;
1546
1547    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
1548        return (100);
1549
1550    Q  = &gki_cb.com.freeq[pool_id];
1551
1552    if (Q->total == 0)
1553        return (100);
1554
1555    return ((Q->cur_cnt * 100) / Q->total);
1556}
1557
1558