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