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