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