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