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