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 <cutils/log.h>
     20 
     21 #if (GKI_NUM_TOTAL_BUF_POOLS > 16)
     22 #error Number of pools out of range (16 Max)!
     23 #endif
     24 
     25 static void gki_add_to_pool_list(UINT8 pool_id);
     26 static void gki_remove_from_pool_list(UINT8 pool_id);
     27 
     28 /*******************************************************************************
     29 **
     30 ** Function         gki_init_free_queue
     31 **
     32 ** Description      Internal function called at startup to initialize a free
     33 **                  queue. It is called once for each free queue.
     34 **
     35 ** Returns          void
     36 **
     37 *******************************************************************************/
     38 static void gki_init_free_queue (UINT8 id, UINT16 size, UINT16 total, void *p_mem)
     39 {
     40     UINT16           i;
     41     UINT16           act_size;
     42     BUFFER_HDR_T    *hdr;
     43     BUFFER_HDR_T    *hdr1 = NULL;
     44     UINT32          *magic;
     45     INT32            tempsize = size;
     46     tGKI_COM_CB     *p_cb = &gki_cb.com;
     47 
     48     /* Ensure an even number of longwords */
     49     tempsize = (INT32)ALIGN_POOL(size);
     50     act_size = (UINT16)(tempsize + BUFFER_PADDING_SIZE);
     51 
     52     /* Remember pool start and end addresses */
     53 // btla-specific ++
     54     if(p_mem)
     55     {
     56         p_cb->pool_start[id] = (UINT8 *)p_mem;
     57         p_cb->pool_end[id]   = (UINT8 *)p_mem + (act_size * total);
     58     }
     59 // btla-specific --
     60 
     61     p_cb->pool_size[id]  = act_size;
     62 
     63     p_cb->freeq[id].size      = (UINT16) tempsize;
     64     p_cb->freeq[id].total     = total;
     65     p_cb->freeq[id].cur_cnt   = 0;
     66     p_cb->freeq[id].max_cnt   = 0;
     67 
     68     /* Initialize  index table */
     69 // btla-specific ++
     70     if(p_mem)
     71     {
     72         hdr = (BUFFER_HDR_T *)p_mem;
     73         p_cb->freeq[id].p_first = hdr;
     74         for (i = 0; i < total; i++)
     75         {
     76             hdr->task_id = GKI_INVALID_TASK;
     77             hdr->q_id    = id;
     78             hdr->status  = BUF_STATUS_FREE;
     79             magic        = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + tempsize);
     80             *magic       = MAGIC_NO;
     81             hdr1         = hdr;
     82             hdr          = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
     83             hdr1->p_next = hdr;
     84         }
     85         hdr1->p_next = NULL;
     86         p_cb->freeq[id].p_last = hdr1;
     87     }
     88 // btla-specific --
     89     return;
     90 }
     91 
     92 // btla-specific ++
     93 #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
     94 static BOOLEAN gki_alloc_free_queue(UINT8 id)
     95 {
     96     FREE_QUEUE_T  *Q;
     97     tGKI_COM_CB *p_cb = &gki_cb.com;
     98     GKI_TRACE("\ngki_alloc_free_queue in, id:%d \n", (int)id );
     99 
    100     Q = &p_cb->freeq[p_cb->pool_list[id]];
    101 
    102     if(Q->p_first == 0)
    103     {
    104         void* p_mem = GKI_os_malloc((Q->size + BUFFER_PADDING_SIZE) * Q->total);
    105         if(p_mem)
    106         {
    107             //re-initialize the queue with allocated memory
    108             GKI_TRACE("\ngki_alloc_free_queue calling  gki_init_free_queue, id:%d  size:%d, totol:%d\n", id, Q->size, Q->total);
    109             gki_init_free_queue(id, Q->size, Q->total, p_mem);
    110             GKI_TRACE("\ngki_alloc_free_queue ret OK, id:%d  size:%d, totol:%d\n", id, Q->size, Q->total);
    111             return TRUE;
    112         }
    113         GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "gki_alloc_free_queue: Not enough memory");
    114     }
    115     GKI_TRACE("\ngki_alloc_free_queue out failed, id:%d\n", id);
    116     return FALSE;
    117 }
    118 
    119 void gki_dealloc_free_queue(void)
    120 {
    121     UINT8   i;
    122     tGKI_COM_CB *p_cb = &gki_cb.com;
    123 
    124     for (i=0; i < p_cb->curr_total_no_of_pools; i++)
    125     {
    126         if ( 0 < p_cb->freeq[i].max_cnt )
    127         {
    128             GKI_os_free(p_cb->pool_start[i]);
    129 
    130             p_cb->freeq[i].cur_cnt   = 0;
    131             p_cb->freeq[i].max_cnt   = 0;
    132             p_cb->freeq[i].p_first   = NULL;
    133             p_cb->freeq[i].p_last    = NULL;
    134 
    135             p_cb->pool_start[i] = NULL;
    136             p_cb->pool_end[i]   = NULL;
    137             p_cb->pool_size[i]  = 0;
    138         }
    139     }
    140 }
    141 
    142 #endif
    143 // btla-specific --
    144 
    145 /*******************************************************************************
    146 **
    147 ** Function         gki_buffer_init
    148 **
    149 ** Description      Called once internally by GKI at startup to initialize all
    150 **                  buffers and free buffer pools.
    151 **
    152 ** Returns          void
    153 **
    154 *******************************************************************************/
    155 void gki_buffer_init(void)
    156 {
    157     UINT8   i, tt, mb;
    158     tGKI_COM_CB *p_cb = &gki_cb.com;
    159 
    160     /* Initialize mailboxes */
    161     for (tt = 0; tt < GKI_MAX_TASKS; tt++)
    162     {
    163         for (mb = 0; mb < NUM_TASK_MBOX; mb++)
    164         {
    165             p_cb->OSTaskQFirst[tt][mb] = NULL;
    166             p_cb->OSTaskQLast [tt][mb] = NULL;
    167         }
    168     }
    169 
    170     for (tt = 0; tt < GKI_NUM_TOTAL_BUF_POOLS; tt++)
    171     {
    172         p_cb->pool_start[tt] = NULL;
    173         p_cb->pool_end[tt]   = NULL;
    174         p_cb->pool_size[tt]  = 0;
    175 
    176         p_cb->freeq[tt].p_first = 0;
    177         p_cb->freeq[tt].p_last  = 0;
    178         p_cb->freeq[tt].size    = 0;
    179         p_cb->freeq[tt].total   = 0;
    180         p_cb->freeq[tt].cur_cnt = 0;
    181         p_cb->freeq[tt].max_cnt = 0;
    182     }
    183 
    184     /* Use default from target.h */
    185     p_cb->pool_access_mask = GKI_DEF_BUFPOOL_PERM_MASK;
    186 
    187 // btla-specific ++
    188 #if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == TRUE))
    189 // btla-specific --
    190 
    191 #if (GKI_NUM_FIXED_BUF_POOLS > 0)
    192     p_cb->bufpool0 = (UINT8 *)GKI_os_malloc ((GKI_BUF0_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX);
    193 #endif
    194 
    195 #if (GKI_NUM_FIXED_BUF_POOLS > 1)
    196     p_cb->bufpool1 = (UINT8 *)GKI_os_malloc ((GKI_BUF1_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX);
    197 #endif
    198 
    199 #if (GKI_NUM_FIXED_BUF_POOLS > 2)
    200     p_cb->bufpool2 = (UINT8 *)GKI_os_malloc ((GKI_BUF2_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX);
    201 #endif
    202 
    203 #if (GKI_NUM_FIXED_BUF_POOLS > 3)
    204     p_cb->bufpool3 = (UINT8 *)GKI_os_malloc ((GKI_BUF3_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX);
    205 #endif
    206 
    207 #if (GKI_NUM_FIXED_BUF_POOLS > 4)
    208     p_cb->bufpool4 = (UINT8 *)GKI_os_malloc ((GKI_BUF4_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX);
    209 #endif
    210 
    211 #if (GKI_NUM_FIXED_BUF_POOLS > 5)
    212     p_cb->bufpool5 = (UINT8 *)GKI_os_malloc ((GKI_BUF5_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX);
    213 #endif
    214 
    215 #if (GKI_NUM_FIXED_BUF_POOLS > 6)
    216     p_cb->bufpool6 = (UINT8 *)GKI_os_malloc ((GKI_BUF6_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX);
    217 #endif
    218 
    219 #if (GKI_NUM_FIXED_BUF_POOLS > 7)
    220     p_cb->bufpool7 = (UINT8 *)GKI_os_malloc ((GKI_BUF7_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX);
    221 #endif
    222 
    223 #if (GKI_NUM_FIXED_BUF_POOLS > 8)
    224     p_cb->bufpool8 = (UINT8 *)GKI_os_malloc ((GKI_BUF8_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX);
    225 #endif
    226 
    227 #if (GKI_NUM_FIXED_BUF_POOLS > 9)
    228     p_cb->bufpool9 = (UINT8 *)GKI_os_malloc ((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 *)GKI_os_malloc ((GKI_BUF10_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX);
    233 #endif
    234 
    235 #if (GKI_NUM_FIXED_BUF_POOLS > 11)
    236     p_cb->bufpool11 = (UINT8 *)GKI_os_malloc ((GKI_BUF11_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX);
    237 #endif
    238 
    239 #if (GKI_NUM_FIXED_BUF_POOLS > 12)
    240     p_cb->bufpool12 = (UINT8 *)GKI_os_malloc ((GKI_BUF12_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX);
    241 #endif
    242 
    243 #if (GKI_NUM_FIXED_BUF_POOLS > 13)
    244     p_cb->bufpool13 = (UINT8 *)GKI_os_malloc ((GKI_BUF13_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX);
    245 #endif
    246 
    247 #if (GKI_NUM_FIXED_BUF_POOLS > 14)
    248     p_cb->bufpool14 = (UINT8 *)GKI_os_malloc ((GKI_BUF14_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX);
    249 #endif
    250 
    251 #if (GKI_NUM_FIXED_BUF_POOLS > 15)
    252     p_cb->bufpool15 = (UINT8 *)GKI_os_malloc ((GKI_BUF15_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX);
    253 #endif
    254 
    255 #endif
    256 
    257 
    258 #if (GKI_NUM_FIXED_BUF_POOLS > 0)
    259     gki_init_free_queue(0, GKI_BUF0_SIZE, GKI_BUF0_MAX, p_cb->bufpool0);
    260 #endif
    261 
    262 #if (GKI_NUM_FIXED_BUF_POOLS > 1)
    263     gki_init_free_queue(1, GKI_BUF1_SIZE, GKI_BUF1_MAX, p_cb->bufpool1);
    264 #endif
    265 
    266 #if (GKI_NUM_FIXED_BUF_POOLS > 2)
    267     gki_init_free_queue(2, GKI_BUF2_SIZE, GKI_BUF2_MAX, p_cb->bufpool2);
    268 #endif
    269 
    270 #if (GKI_NUM_FIXED_BUF_POOLS > 3)
    271     gki_init_free_queue(3, GKI_BUF3_SIZE, GKI_BUF3_MAX, p_cb->bufpool3);
    272 #endif
    273 
    274 #if (GKI_NUM_FIXED_BUF_POOLS > 4)
    275     gki_init_free_queue(4, GKI_BUF4_SIZE, GKI_BUF4_MAX, p_cb->bufpool4);
    276 #endif
    277 
    278 #if (GKI_NUM_FIXED_BUF_POOLS > 5)
    279     gki_init_free_queue(5, GKI_BUF5_SIZE, GKI_BUF5_MAX, p_cb->bufpool5);
    280 #endif
    281 
    282 #if (GKI_NUM_FIXED_BUF_POOLS > 6)
    283     gki_init_free_queue(6, GKI_BUF6_SIZE, GKI_BUF6_MAX, p_cb->bufpool6);
    284 #endif
    285 
    286 #if (GKI_NUM_FIXED_BUF_POOLS > 7)
    287     gki_init_free_queue(7, GKI_BUF7_SIZE, GKI_BUF7_MAX, p_cb->bufpool7);
    288 #endif
    289 
    290 #if (GKI_NUM_FIXED_BUF_POOLS > 8)
    291     gki_init_free_queue(8, GKI_BUF8_SIZE, GKI_BUF8_MAX, p_cb->bufpool8);
    292 #endif
    293 
    294 #if (GKI_NUM_FIXED_BUF_POOLS > 9)
    295     gki_init_free_queue(9, GKI_BUF9_SIZE, GKI_BUF9_MAX, p_cb->bufpool9);
    296 #endif
    297 
    298 #if (GKI_NUM_FIXED_BUF_POOLS > 10)
    299     gki_init_free_queue(10, GKI_BUF10_SIZE, GKI_BUF10_MAX, p_cb->bufpool10);
    300 #endif
    301 
    302 #if (GKI_NUM_FIXED_BUF_POOLS > 11)
    303     gki_init_free_queue(11, GKI_BUF11_SIZE, GKI_BUF11_MAX, p_cb->bufpool11);
    304 #endif
    305 
    306 #if (GKI_NUM_FIXED_BUF_POOLS > 12)
    307     gki_init_free_queue(12, GKI_BUF12_SIZE, GKI_BUF12_MAX, p_cb->bufpool12);
    308 #endif
    309 
    310 #if (GKI_NUM_FIXED_BUF_POOLS > 13)
    311     gki_init_free_queue(13, GKI_BUF13_SIZE, GKI_BUF13_MAX, p_cb->bufpool13);
    312 #endif
    313 
    314 #if (GKI_NUM_FIXED_BUF_POOLS > 14)
    315     gki_init_free_queue(14, GKI_BUF14_SIZE, GKI_BUF14_MAX, p_cb->bufpool14);
    316 #endif
    317 
    318 #if (GKI_NUM_FIXED_BUF_POOLS > 15)
    319     gki_init_free_queue(15, GKI_BUF15_SIZE, GKI_BUF15_MAX, p_cb->bufpool15);
    320 #endif
    321 
    322     /* add pools to the pool_list which is arranged in the order of size */
    323     for(i=0; i < GKI_NUM_FIXED_BUF_POOLS ; i++)
    324     {
    325         p_cb->pool_list[i] = i;
    326     }
    327 
    328     p_cb->curr_total_no_of_pools = GKI_NUM_FIXED_BUF_POOLS;
    329 
    330     return;
    331 }
    332 
    333 
    334 /*******************************************************************************
    335 **
    336 ** Function         GKI_init_q
    337 **
    338 ** Description      Called by an application to initialize a buffer queue.
    339 **
    340 ** Returns          void
    341 **
    342 *******************************************************************************/
    343 void GKI_init_q (BUFFER_Q *p_q)
    344 {
    345     p_q->p_first = p_q->p_last = NULL;
    346     p_q->count = 0;
    347 
    348     return;
    349 }
    350 
    351 
    352 /*******************************************************************************
    353 **
    354 ** Function         GKI_getbuf
    355 **
    356 ** Description      Called by an application to get a free buffer which
    357 **                  is of size greater or equal to the requested size.
    358 **
    359 **                  Note: This routine only takes buffers from public pools.
    360 **                        It will not use any buffers from pools
    361 **                        marked GKI_RESTRICTED_POOL.
    362 **
    363 ** Parameters       size - (input) number of bytes needed.
    364 **
    365 ** Returns          A pointer to the buffer, or NULL if none available
    366 **
    367 *******************************************************************************/
    368 void *GKI_getbuf (UINT16 size)
    369 {
    370     UINT8         i;
    371     FREE_QUEUE_T  *Q;
    372     BUFFER_HDR_T  *p_hdr;
    373     tGKI_COM_CB *p_cb = &gki_cb.com;
    374 
    375     if (size == 0)
    376     {
    377         GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "getbuf: Size is zero");
    378         return (NULL);
    379     }
    380 
    381     /* Find the first buffer pool that is public that can hold the desired size */
    382     for (i=0; i < p_cb->curr_total_no_of_pools; i++)
    383     {
    384         if ( size <= p_cb->freeq[p_cb->pool_list[i]].size )
    385             break;
    386     }
    387 
    388     if(i == p_cb->curr_total_no_of_pools)
    389     {
    390         GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "getbuf: Size is too big");
    391         return (NULL);
    392     }
    393 
    394     /* Make sure the buffers aren't disturbed til finished with allocation */
    395     GKI_disable();
    396 
    397     /* search the public buffer pools that are big enough to hold the size
    398      * until a free buffer is found */
    399     for ( ; i < p_cb->curr_total_no_of_pools; i++)
    400     {
    401         /* Only look at PUBLIC buffer pools (bypass RESTRICTED pools) */
    402         if (((UINT16)1 << p_cb->pool_list[i]) & p_cb->pool_access_mask)
    403             continue;
    404         if ( size <= p_cb->freeq[p_cb->pool_list[i]].size )
    405              Q = &p_cb->freeq[p_cb->pool_list[i]];
    406         else
    407              continue;
    408 
    409         if(Q->cur_cnt < Q->total)
    410         {
    411 // btla-specific ++
    412         #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
    413             if(Q->p_first == 0 && gki_alloc_free_queue(i) != TRUE)
    414             {
    415                 GKI_enable();
    416                 return NULL;
    417             }
    418         #endif
    419 // btla-specific --
    420             p_hdr = Q->p_first;
    421             Q->p_first = p_hdr->p_next;
    422 
    423             if (!Q->p_first)
    424                 Q->p_last = NULL;
    425 
    426             if(++Q->cur_cnt > Q->max_cnt)
    427                 Q->max_cnt = Q->cur_cnt;
    428 
    429             GKI_enable();
    430 
    431             p_hdr->task_id = GKI_get_taskid();
    432 
    433             p_hdr->status  = BUF_STATUS_UNLINKED;
    434             p_hdr->p_next  = NULL;
    435             p_hdr->Type    = 0;
    436 
    437             return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
    438         }
    439     }
    440 
    441     GKI_enable();
    442 
    443     GKI_exception (GKI_ERROR_OUT_OF_BUFFERS, "getbuf: out of buffers");
    444     return (NULL);
    445 }
    446 
    447 
    448 /*******************************************************************************
    449 **
    450 ** Function         GKI_getpoolbuf
    451 **
    452 ** Description      Called by an application to get a free buffer from
    453 **                  a specific buffer pool.
    454 **
    455 **                  Note: If there are no more buffers available from the pool,
    456 **                        the public buffers are searched for an available buffer.
    457 **
    458 ** Parameters       pool_id - (input) pool ID to get a buffer out of.
    459 **
    460 ** Returns          A pointer to the buffer, or NULL if none available
    461 **
    462 *******************************************************************************/
    463 void *GKI_getpoolbuf (UINT8 pool_id)
    464 {
    465     FREE_QUEUE_T  *Q;
    466     BUFFER_HDR_T  *p_hdr;
    467     tGKI_COM_CB *p_cb = &gki_cb.com;
    468 
    469     if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
    470     {
    471         GKI_exception(GKI_ERROR_GETPOOLBUF_BAD_QID, "getpoolbuf bad pool");
    472         return (NULL);
    473     }
    474 
    475     /* Make sure the buffers aren't disturbed til finished with allocation */
    476     GKI_disable();
    477 
    478     Q = &p_cb->freeq[pool_id];
    479     if(Q->cur_cnt < Q->total)
    480     {
    481 // btla-specific ++
    482 #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
    483         if(Q->p_first == 0 && gki_alloc_free_queue(pool_id) != TRUE)
    484         {
    485             GKI_enable();
    486             return NULL;
    487         }
    488 #endif
    489 // btla-specific --
    490         p_hdr = Q->p_first;
    491         Q->p_first = p_hdr->p_next;
    492 
    493         if (!Q->p_first)
    494             Q->p_last = NULL;
    495 
    496         if(++Q->cur_cnt > Q->max_cnt)
    497             Q->max_cnt = Q->cur_cnt;
    498 
    499         GKI_enable();
    500 
    501 
    502         p_hdr->task_id = GKI_get_taskid();
    503 
    504         p_hdr->status  = BUF_STATUS_UNLINKED;
    505         p_hdr->p_next  = NULL;
    506         p_hdr->Type    = 0;
    507 
    508         return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
    509     }
    510 
    511     /* If here, no buffers in the specified pool */
    512     GKI_enable();
    513 
    514     /* try for free buffers in public pools */
    515     return (GKI_getbuf(p_cb->freeq[pool_id].size));
    516 
    517 }
    518 
    519 /*******************************************************************************
    520 **
    521 ** Function         GKI_freebuf
    522 **
    523 ** Description      Called by an application to return a buffer to the free pool.
    524 **
    525 ** Parameters       p_buf - (input) address of the beginning of a buffer.
    526 **
    527 ** Returns          void
    528 **
    529 *******************************************************************************/
    530 void GKI_freebuf (void *p_buf)
    531 {
    532     FREE_QUEUE_T    *Q;
    533     BUFFER_HDR_T    *p_hdr;
    534 
    535 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
    536     if (!p_buf || gki_chk_buf_damage(p_buf))
    537     {
    538         GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Free - Buf Corrupted");
    539         return;
    540     }
    541 #endif
    542 
    543     p_hdr = (BUFFER_HDR_T *) ((UINT8 *)p_buf - BUFFER_HDR_SIZE);
    544 
    545     if (p_hdr->status != BUF_STATUS_UNLINKED)
    546     {
    547         GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf");
    548         return;
    549     }
    550 
    551     if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS)
    552     {
    553         GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId");
    554         return;
    555     }
    556 
    557     GKI_disable();
    558 
    559     /*
    560     ** Release the buffer
    561     */
    562     Q  = &gki_cb.com.freeq[p_hdr->q_id];
    563     if (Q->p_last)
    564         Q->p_last->p_next = p_hdr;
    565     else
    566         Q->p_first = p_hdr;
    567 
    568     Q->p_last      = p_hdr;
    569     p_hdr->p_next  = NULL;
    570     p_hdr->status  = BUF_STATUS_FREE;
    571     p_hdr->task_id = GKI_INVALID_TASK;
    572     if (Q->cur_cnt > 0)
    573         Q->cur_cnt--;
    574 
    575     GKI_enable();
    576 
    577     return;
    578 }
    579 
    580 
    581 /*******************************************************************************
    582 **
    583 ** Function         GKI_get_buf_size
    584 **
    585 ** Description      Called by an application to get the size of a buffer.
    586 **
    587 ** Parameters       p_buf - (input) address of the beginning of a buffer.
    588 **
    589 ** Returns          the size of the buffer
    590 **
    591 *******************************************************************************/
    592 UINT16 GKI_get_buf_size (void *p_buf)
    593 {
    594     BUFFER_HDR_T    *p_hdr;
    595 
    596     p_hdr = (BUFFER_HDR_T *)((UINT8 *) p_buf - BUFFER_HDR_SIZE);
    597 
    598     if ((UINT32)p_hdr & 1)
    599         return (0);
    600 
    601     if (p_hdr->q_id < GKI_NUM_TOTAL_BUF_POOLS)
    602     {
    603         return (gki_cb.com.freeq[p_hdr->q_id].size);
    604     }
    605 
    606     return (0);
    607 }
    608 
    609 /*******************************************************************************
    610 **
    611 ** Function         gki_chk_buf_damage
    612 **
    613 ** Description      Called internally by OSS to check for buffer corruption.
    614 **
    615 ** Returns          TRUE if there is a problem, else FALSE
    616 **
    617 *******************************************************************************/
    618 BOOLEAN gki_chk_buf_damage(void *p_buf)
    619 {
    620 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
    621 
    622     UINT32 *magic;
    623     magic  = (UINT32 *)((UINT8 *) p_buf + GKI_get_buf_size(p_buf));
    624 
    625     if ((UINT32)magic & 1)
    626         return (TRUE);
    627 
    628     if (*magic == MAGIC_NO)
    629         return (FALSE);
    630 
    631     return (TRUE);
    632 
    633 #else
    634 
    635     return (FALSE);
    636 
    637 #endif
    638 }
    639 
    640 /*******************************************************************************
    641 **
    642 ** Function         GKI_send_msg
    643 **
    644 ** Description      Called by applications to send a buffer to a task
    645 **
    646 ** Returns          Nothing
    647 **
    648 *******************************************************************************/
    649 void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)
    650 {
    651     BUFFER_HDR_T    *p_hdr;
    652     tGKI_COM_CB *p_cb = &gki_cb.com;
    653 
    654     /* If task non-existant or not started, drop buffer */
    655     if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
    656     {
    657         GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
    658         GKI_freebuf (msg);
    659         return;
    660     }
    661 
    662 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
    663     if (gki_chk_buf_damage(msg))
    664     {
    665         GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
    666         return;
    667     }
    668 #endif
    669 
    670     p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
    671 
    672     if (p_hdr->status != BUF_STATUS_UNLINKED)
    673     {
    674         GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
    675         return;
    676     }
    677 
    678     GKI_disable();
    679 
    680     if (p_cb->OSTaskQFirst[task_id][mbox])
    681         p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
    682     else
    683         p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
    684 
    685     p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
    686 
    687     p_hdr->p_next = NULL;
    688     p_hdr->status = BUF_STATUS_QUEUED;
    689     p_hdr->task_id = task_id;
    690 
    691 
    692     GKI_enable();
    693 
    694     GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));
    695 
    696     return;
    697 }
    698 
    699 /*******************************************************************************
    700 **
    701 ** Function         GKI_read_mbox
    702 **
    703 ** Description      Called by applications to read a buffer from one of
    704 **                  the task mailboxes.  A task can only read its own mailbox.
    705 **
    706 ** Parameters:      mbox  - (input) mailbox ID to read (0, 1, 2, or 3)
    707 **
    708 ** Returns          NULL if the mailbox was empty, else the address of a buffer
    709 **
    710 *******************************************************************************/
    711 void *GKI_read_mbox (UINT8 mbox)
    712 {
    713     UINT8           task_id = GKI_get_taskid();
    714     void            *p_buf = NULL;
    715     BUFFER_HDR_T    *p_hdr;
    716 
    717     if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX))
    718         return (NULL);
    719 
    720     GKI_disable();
    721 
    722     if (gki_cb.com.OSTaskQFirst[task_id][mbox])
    723     {
    724         p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];
    725         gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
    726 
    727         p_hdr->p_next = NULL;
    728         p_hdr->status = BUF_STATUS_UNLINKED;
    729 
    730         p_buf = (UINT8 *)p_hdr + BUFFER_HDR_SIZE;
    731     }
    732 
    733     GKI_enable();
    734 
    735     return (p_buf);
    736 }
    737 
    738 
    739 
    740 /*******************************************************************************
    741 **
    742 ** Function         GKI_enqueue
    743 **
    744 ** Description      Enqueue a buffer at the tail of the queue
    745 **
    746 ** Parameters:      p_q  -  (input) pointer to a queue.
    747 **                  p_buf - (input) address of the buffer to enqueue
    748 **
    749 ** Returns          void
    750 **
    751 *******************************************************************************/
    752 void GKI_enqueue (BUFFER_Q *p_q, void *p_buf)
    753 {
    754     BUFFER_HDR_T    *p_hdr;
    755 
    756 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
    757     if (gki_chk_buf_damage(p_buf))
    758     {
    759         GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
    760         return;
    761     }
    762 #endif
    763 
    764     p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
    765 
    766     if (p_hdr->status != BUF_STATUS_UNLINKED)
    767     {
    768         GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue - buf already linked");
    769         return;
    770     }
    771 
    772     GKI_disable();
    773 
    774     /* Since the queue is exposed (C vs C++), keep the pointers in exposed format */
    775     if (p_q->p_last)
    776     {
    777         BUFFER_HDR_T *p_last_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_last - BUFFER_HDR_SIZE);
    778         p_last_hdr->p_next = p_hdr;
    779     }
    780     else
    781         p_q->p_first = p_buf;
    782 
    783     p_q->p_last = p_buf;
    784     p_q->count++;
    785 
    786     p_hdr->p_next = NULL;
    787     p_hdr->status = BUF_STATUS_QUEUED;
    788 
    789     GKI_enable();
    790 
    791     return;
    792 }
    793 
    794 
    795 /*******************************************************************************
    796 **
    797 ** Function         GKI_enqueue_head
    798 **
    799 ** Description      Enqueue a buffer at the head of the queue
    800 **
    801 ** Parameters:      p_q  -  (input) pointer to a queue.
    802 **                  p_buf - (input) address of the buffer to enqueue
    803 **
    804 ** Returns          void
    805 **
    806 *******************************************************************************/
    807 void GKI_enqueue_head (BUFFER_Q *p_q, void *p_buf)
    808 {
    809     BUFFER_HDR_T    *p_hdr;
    810 
    811 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
    812     if (gki_chk_buf_damage(p_buf))
    813     {
    814         GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
    815         return;
    816     }
    817 #endif
    818 
    819     p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
    820 
    821     if (p_hdr->status != BUF_STATUS_UNLINKED)
    822     {
    823         GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue head - buf already linked");
    824         return;
    825     }
    826 
    827     GKI_disable();
    828 
    829     if (p_q->p_first)
    830     {
    831         p_hdr->p_next = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
    832         p_q->p_first = p_buf;
    833     }
    834     else
    835     {
    836         p_q->p_first = p_buf;
    837         p_q->p_last  = p_buf;
    838         p_hdr->p_next = NULL;
    839     }
    840     p_q->count++;
    841 
    842     p_hdr->status = BUF_STATUS_QUEUED;
    843 
    844     GKI_enable();
    845 
    846     return;
    847 }
    848 
    849 
    850 /*******************************************************************************
    851 **
    852 ** Function         GKI_dequeue
    853 **
    854 ** Description      Dequeues a buffer from the head of a queue
    855 **
    856 ** Parameters:      p_q  - (input) pointer to a queue.
    857 **
    858 ** Returns          NULL if queue is empty, else buffer
    859 **
    860 *******************************************************************************/
    861 void *GKI_dequeue (BUFFER_Q *p_q)
    862 {
    863     BUFFER_HDR_T    *p_hdr;
    864 
    865     GKI_disable();
    866 
    867     if (!p_q || !p_q->count)
    868     {
    869         GKI_enable();
    870         return (NULL);
    871     }
    872 
    873     p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
    874 
    875     /* Keep buffers such that GKI header is invisible
    876     */
    877     if (p_hdr->p_next)
    878         p_q->p_first = ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
    879     else
    880     {
    881         p_q->p_first = NULL;
    882         p_q->p_last  = NULL;
    883     }
    884 
    885     p_q->count--;
    886 
    887     p_hdr->p_next = NULL;
    888     p_hdr->status = BUF_STATUS_UNLINKED;
    889 
    890     GKI_enable();
    891 
    892     return ((UINT8 *)p_hdr + BUFFER_HDR_SIZE);
    893 }
    894 
    895 
    896 /*******************************************************************************
    897 **
    898 ** Function         GKI_remove_from_queue
    899 **
    900 ** Description      Dequeue a buffer from the middle of the queue
    901 **
    902 ** Parameters:      p_q  - (input) pointer to a queue.
    903 **                  p_buf - (input) address of the buffer to enqueue
    904 **
    905 ** Returns          NULL if queue is empty, else buffer
    906 **
    907 *******************************************************************************/
    908 void *GKI_remove_from_queue (BUFFER_Q *p_q, void *p_buf)
    909 {
    910     BUFFER_HDR_T    *p_prev;
    911     BUFFER_HDR_T    *p_buf_hdr;
    912 
    913     GKI_disable();
    914 
    915     if (p_buf == p_q->p_first)
    916     {
    917         GKI_enable();
    918         return (GKI_dequeue (p_q));
    919     }
    920 
    921     p_buf_hdr = (BUFFER_HDR_T *)((UINT8 *)p_buf - BUFFER_HDR_SIZE);
    922     p_prev    = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
    923 
    924     for ( ; p_prev; p_prev = p_prev->p_next)
    925     {
    926         /* If the previous points to this one, move the pointers around */
    927         if (p_prev->p_next == p_buf_hdr)
    928         {
    929             p_prev->p_next = p_buf_hdr->p_next;
    930 
    931             /* If we are removing the last guy in the queue, update p_last */
    932             if (p_buf == p_q->p_last)
    933                 p_q->p_last = p_prev + 1;
    934 
    935             /* One less in the queue */
    936             p_q->count--;
    937 
    938             /* The buffer is now unlinked */
    939             p_buf_hdr->p_next = NULL;
    940             p_buf_hdr->status = BUF_STATUS_UNLINKED;
    941 
    942             GKI_enable();
    943             return (p_buf);
    944         }
    945     }
    946 
    947     GKI_enable();
    948     return (NULL);
    949 }
    950 
    951 /*******************************************************************************
    952 **
    953 ** Function         GKI_getfirst
    954 **
    955 ** Description      Return a pointer to the first buffer in a queue
    956 **
    957 ** Parameters:      p_q  - (input) pointer to a queue.
    958 **
    959 ** Returns          NULL if queue is empty, else buffer address
    960 **
    961 *******************************************************************************/
    962 void *GKI_getfirst (BUFFER_Q *p_q)
    963 {
    964     return (p_q->p_first);
    965 }
    966 
    967 
    968 /*******************************************************************************
    969 **
    970 ** Function         GKI_getlast
    971 **
    972 ** Description      Return a pointer to the last buffer in a queue
    973 **
    974 ** Parameters:      p_q  - (input) pointer to a queue.
    975 **
    976 ** Returns          NULL if queue is empty, else buffer address
    977 **
    978 *******************************************************************************/
    979 void *GKI_getlast (BUFFER_Q *p_q)
    980 {
    981     return (p_q->p_last);
    982 }
    983 
    984 /*******************************************************************************
    985 **
    986 ** Function         GKI_getnext
    987 **
    988 ** Description      Return a pointer to the next buffer in a queue
    989 **
    990 ** Parameters:      p_buf  - (input) pointer to the buffer to find the next one from.
    991 **
    992 ** Returns          NULL if no more buffers in the queue, else next buffer address
    993 **
    994 *******************************************************************************/
    995 void *GKI_getnext (void *p_buf)
    996 {
    997     BUFFER_HDR_T    *p_hdr;
    998 
    999     p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
   1000 
   1001     if (p_hdr->p_next)
   1002         return ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
   1003     else
   1004         return (NULL);
   1005 }
   1006 
   1007 
   1008 
   1009 /*******************************************************************************
   1010 **
   1011 ** Function         GKI_queue_is_empty
   1012 **
   1013 ** Description      Check the status of a queue.
   1014 **
   1015 ** Parameters:      p_q  - (input) pointer to a queue.
   1016 **
   1017 ** Returns          TRUE if queue is empty, else FALSE
   1018 **
   1019 *******************************************************************************/
   1020 BOOLEAN GKI_queue_is_empty(BUFFER_Q *p_q)
   1021 {
   1022     return ((BOOLEAN) (p_q->count == 0));
   1023 }
   1024 
   1025 /*******************************************************************************
   1026 **
   1027 ** Function         gki_add_to_pool_list
   1028 **
   1029 ** Description      Adds pool to the pool list which is arranged in the
   1030 **                  order of size
   1031 **
   1032 ** Returns          void
   1033 **
   1034 *******************************************************************************/
   1035 static void gki_add_to_pool_list(UINT8 pool_id)
   1036 {
   1037 
   1038     INT32 i, j;
   1039     tGKI_COM_CB *p_cb = &gki_cb.com;
   1040 
   1041      /* Find the position where the specified pool should be inserted into the list */
   1042     for(i=0; i < p_cb->curr_total_no_of_pools; i++)
   1043     {
   1044 
   1045         if(p_cb->freeq[pool_id].size <= p_cb->freeq[ p_cb->pool_list[i] ].size)
   1046             break;
   1047     }
   1048 
   1049     /* Insert the new buffer pool ID into the list of pools */
   1050     for(j = p_cb->curr_total_no_of_pools; j > i; j--)
   1051     {
   1052         p_cb->pool_list[j] = p_cb->pool_list[j-1];
   1053     }
   1054 
   1055     p_cb->pool_list[i] = pool_id;
   1056 
   1057     return;
   1058 }
   1059 
   1060 /*******************************************************************************
   1061 **
   1062 ** Function         gki_remove_from_pool_list
   1063 **
   1064 ** Description      Removes pool from the pool list. Called when a pool is deleted
   1065 **
   1066 ** Returns          void
   1067 **
   1068 *******************************************************************************/
   1069 static void gki_remove_from_pool_list(UINT8 pool_id)
   1070 {
   1071     tGKI_COM_CB *p_cb = &gki_cb.com;
   1072     UINT8 i;
   1073 
   1074     for(i=0; i < p_cb->curr_total_no_of_pools; i++)
   1075     {
   1076         if(pool_id == p_cb->pool_list[i])
   1077             break;
   1078     }
   1079 
   1080     while (i < (p_cb->curr_total_no_of_pools - 1))
   1081     {
   1082         p_cb->pool_list[i] = p_cb->pool_list[i+1];
   1083         i++;
   1084     }
   1085 
   1086     return;
   1087 }
   1088 
   1089 /*******************************************************************************
   1090 **
   1091 ** Function         GKI_igetpoolbuf
   1092 **
   1093 ** Description      Called by an interrupt service routine to get a free buffer from
   1094 **                  a specific buffer pool.
   1095 **
   1096 ** Parameters       pool_id - (input) pool ID to get a buffer out of.
   1097 **
   1098 ** Returns          A pointer to the buffer, or NULL if none available
   1099 **
   1100 *******************************************************************************/
   1101 void *GKI_igetpoolbuf (UINT8 pool_id)
   1102 {
   1103     FREE_QUEUE_T  *Q;
   1104     BUFFER_HDR_T  *p_hdr;
   1105 
   1106     if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
   1107         return (NULL);
   1108 
   1109 
   1110     Q = &gki_cb.com.freeq[pool_id];
   1111     if(Q->cur_cnt < Q->total)
   1112     {
   1113         p_hdr = Q->p_first;
   1114         Q->p_first = p_hdr->p_next;
   1115 
   1116         if (!Q->p_first)
   1117             Q->p_last = NULL;
   1118 
   1119         if(++Q->cur_cnt > Q->max_cnt)
   1120             Q->max_cnt = Q->cur_cnt;
   1121 
   1122         p_hdr->task_id = GKI_get_taskid();
   1123 
   1124         p_hdr->status  = BUF_STATUS_UNLINKED;
   1125         p_hdr->p_next  = NULL;
   1126         p_hdr->Type    = 0;
   1127 
   1128         return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
   1129     }
   1130 
   1131     return (NULL);
   1132 }
   1133 
   1134 /*******************************************************************************
   1135 **
   1136 ** Function         GKI_poolcount
   1137 **
   1138 ** Description      Called by an application to get the total number of buffers
   1139 **                  in the specified buffer pool.
   1140 **
   1141 ** Parameters       pool_id - (input) pool ID to get the free count of.
   1142 **
   1143 ** Returns          the total number of buffers in the pool
   1144 **
   1145 *******************************************************************************/
   1146 UINT16 GKI_poolcount (UINT8 pool_id)
   1147 {
   1148     if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
   1149         return (0);
   1150 
   1151     return (gki_cb.com.freeq[pool_id].total);
   1152 }
   1153 
   1154 /*******************************************************************************
   1155 **
   1156 ** Function         GKI_poolfreecount
   1157 **
   1158 ** Description      Called by an application to get the number of free buffers
   1159 **                  in the specified buffer pool.
   1160 **
   1161 ** Parameters       pool_id - (input) pool ID to get the free count of.
   1162 **
   1163 ** Returns          the number of free buffers in the pool
   1164 **
   1165 *******************************************************************************/
   1166 UINT16 GKI_poolfreecount (UINT8 pool_id)
   1167 {
   1168     FREE_QUEUE_T  *Q;
   1169 
   1170     if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
   1171         return (0);
   1172 
   1173     Q  = &gki_cb.com.freeq[pool_id];
   1174 
   1175     return ((UINT16)(Q->total - Q->cur_cnt));
   1176 }
   1177 
   1178 /*******************************************************************************
   1179 **
   1180 ** Function         GKI_get_pool_bufsize
   1181 **
   1182 ** Description      Called by an application to get the size of buffers in a pool
   1183 **
   1184 ** Parameters       Pool ID.
   1185 **
   1186 ** Returns          the size of buffers in the pool
   1187 **
   1188 *******************************************************************************/
   1189 UINT16 GKI_get_pool_bufsize (UINT8 pool_id)
   1190 {
   1191     if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
   1192         return (gki_cb.com.freeq[pool_id].size);
   1193 
   1194     return (0);
   1195 }
   1196 
   1197 /*******************************************************************************
   1198 **
   1199 ** Function         GKI_poolutilization
   1200 **
   1201 ** Description      Called by an application to get the buffer utilization
   1202 **                  in the specified buffer pool.
   1203 **
   1204 ** Parameters       pool_id - (input) pool ID to get the free count of.
   1205 **
   1206 ** Returns          % of buffers used from 0 to 100
   1207 **
   1208 *******************************************************************************/
   1209 UINT16 GKI_poolutilization (UINT8 pool_id)
   1210 {
   1211     FREE_QUEUE_T  *Q;
   1212 
   1213     if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
   1214         return (100);
   1215 
   1216     Q  = &gki_cb.com.freeq[pool_id];
   1217 
   1218     if (Q->total == 0)
   1219         return (100);
   1220 
   1221     return ((Q->cur_cnt * 100) / Q->total);
   1222 }
   1223 
   1224