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