Home | History | Annotate | Download | only in common
      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 *******************************************************************************/
     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
    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 *******************************************************************************/
    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 *******************************************************************************/
    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
    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                 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
    500 void *GKI_getpoolbuf_debug (UINT8 pool_id, const char * _function_, int _line_)
    501 #else
    502 void *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 *******************************************************************************/
    584 void 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 *******************************************************************************/
    650 UINT16 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 *******************************************************************************/
    676 BOOLEAN 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 *******************************************************************************/
    707 void 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 *******************************************************************************/
    769 void *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 *******************************************************************************/
    810 void 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 *******************************************************************************/
    865 void 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 *******************************************************************************/
    919 void *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 *******************************************************************************/
    966 void *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 *******************************************************************************/
   1020 void *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 *******************************************************************************/
   1036 void *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 *******************************************************************************/
   1052 void *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 *******************************************************************************/
   1077 BOOLEAN 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 *******************************************************************************/
   1097 void *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 *******************************************************************************/
   1144 UINT8 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 *******************************************************************************/
   1172 static 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 *******************************************************************************/
   1206 static 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 *******************************************************************************/
   1238 void *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 *******************************************************************************/
   1283 UINT16 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 *******************************************************************************/
   1303 UINT16 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 *******************************************************************************/
   1327 void 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 *******************************************************************************/
   1346 void 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 *******************************************************************************/
   1417 UINT8 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 *******************************************************************************/
   1473 void 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 *******************************************************************************/
   1523 UINT16 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 *******************************************************************************/
   1543 UINT16 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