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