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 if ( size <= p_cb->freeq[p_cb->pool_list[i]].size ) 405 Q = &p_cb->freeq[p_cb->pool_list[i]]; 406 else 407 continue; 408 409 if(Q->cur_cnt < Q->total) 410 { 411// btla-specific ++ 412 #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS 413 if(Q->p_first == 0 && gki_alloc_free_queue(i) != TRUE) 414 return NULL; 415 #endif 416// btla-specific -- 417 p_hdr = Q->p_first; 418 Q->p_first = p_hdr->p_next; 419 420 if (!Q->p_first) 421 Q->p_last = NULL; 422 423 if(++Q->cur_cnt > Q->max_cnt) 424 Q->max_cnt = Q->cur_cnt; 425 426 GKI_enable(); 427 428 p_hdr->task_id = GKI_get_taskid(); 429 430 p_hdr->status = BUF_STATUS_UNLINKED; 431 p_hdr->p_next = NULL; 432 p_hdr->Type = 0; 433 434 return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE)); 435 } 436 } 437 438 GKI_enable(); 439 440 GKI_exception (GKI_ERROR_OUT_OF_BUFFERS, "getbuf: out of buffers"); 441 return (NULL); 442} 443 444 445/******************************************************************************* 446** 447** Function GKI_getpoolbuf 448** 449** Description Called by an application to get a free buffer from 450** a specific buffer pool. 451** 452** Note: If there are no more buffers available from the pool, 453** the public buffers are searched for an available buffer. 454** 455** Parameters pool_id - (input) pool ID to get a buffer out of. 456** 457** Returns A pointer to the buffer, or NULL if none available 458** 459*******************************************************************************/ 460void *GKI_getpoolbuf (UINT8 pool_id) 461{ 462 FREE_QUEUE_T *Q; 463 BUFFER_HDR_T *p_hdr; 464 tGKI_COM_CB *p_cb = &gki_cb.com; 465 466 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) 467 { 468 GKI_exception(GKI_ERROR_GETPOOLBUF_BAD_QID, "getpoolbuf bad pool"); 469 return (NULL); 470 } 471 472 /* Make sure the buffers aren't disturbed til finished with allocation */ 473 GKI_disable(); 474 475 Q = &p_cb->freeq[pool_id]; 476 if(Q->cur_cnt < Q->total) 477 { 478// btla-specific ++ 479#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS 480 if(Q->p_first == 0 && gki_alloc_free_queue(pool_id) != TRUE) 481 return NULL; 482#endif 483// btla-specific -- 484 p_hdr = Q->p_first; 485 Q->p_first = p_hdr->p_next; 486 487 if (!Q->p_first) 488 Q->p_last = NULL; 489 490 if(++Q->cur_cnt > Q->max_cnt) 491 Q->max_cnt = Q->cur_cnt; 492 493 GKI_enable(); 494 495 496 p_hdr->task_id = GKI_get_taskid(); 497 498 p_hdr->status = BUF_STATUS_UNLINKED; 499 p_hdr->p_next = NULL; 500 p_hdr->Type = 0; 501 502 return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE)); 503 } 504 505 /* If here, no buffers in the specified pool */ 506 GKI_enable(); 507 508 /* try for free buffers in public pools */ 509 return (GKI_getbuf(p_cb->freeq[pool_id].size)); 510 511} 512 513/******************************************************************************* 514** 515** Function GKI_freebuf 516** 517** Description Called by an application to return a buffer to the free pool. 518** 519** Parameters p_buf - (input) address of the beginning of a buffer. 520** 521** Returns void 522** 523*******************************************************************************/ 524void GKI_freebuf (void *p_buf) 525{ 526 FREE_QUEUE_T *Q; 527 BUFFER_HDR_T *p_hdr; 528 529#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE) 530 if (!p_buf || gki_chk_buf_damage(p_buf)) 531 { 532 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Free - Buf Corrupted"); 533 return; 534 } 535#endif 536 537 p_hdr = (BUFFER_HDR_T *) ((UINT8 *)p_buf - BUFFER_HDR_SIZE); 538 539 if (p_hdr->status != BUF_STATUS_UNLINKED) 540 { 541 GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf"); 542 return; 543 } 544 545 if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS) 546 { 547 GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId"); 548 return; 549 } 550 551 GKI_disable(); 552 553 /* 554 ** Release the buffer 555 */ 556 Q = &gki_cb.com.freeq[p_hdr->q_id]; 557 if (Q->p_last) 558 Q->p_last->p_next = p_hdr; 559 else 560 Q->p_first = p_hdr; 561 562 Q->p_last = p_hdr; 563 p_hdr->p_next = NULL; 564 p_hdr->status = BUF_STATUS_FREE; 565 p_hdr->task_id = GKI_INVALID_TASK; 566 if (Q->cur_cnt > 0) 567 Q->cur_cnt--; 568 569 GKI_enable(); 570 571 return; 572} 573 574 575/******************************************************************************* 576** 577** Function GKI_get_buf_size 578** 579** Description Called by an application to get the size of a buffer. 580** 581** Parameters p_buf - (input) address of the beginning of a buffer. 582** 583** Returns the size of the buffer 584** 585*******************************************************************************/ 586UINT16 GKI_get_buf_size (void *p_buf) 587{ 588 BUFFER_HDR_T *p_hdr; 589 590 p_hdr = (BUFFER_HDR_T *)((UINT8 *) p_buf - BUFFER_HDR_SIZE); 591 592 if ((UINT32)p_hdr & 1) 593 return (0); 594 595 if (p_hdr->q_id < GKI_NUM_TOTAL_BUF_POOLS) 596 { 597 return (gki_cb.com.freeq[p_hdr->q_id].size); 598 } 599 600 return (0); 601} 602 603/******************************************************************************* 604** 605** Function gki_chk_buf_damage 606** 607** Description Called internally by OSS to check for buffer corruption. 608** 609** Returns TRUE if there is a problem, else FALSE 610** 611*******************************************************************************/ 612BOOLEAN gki_chk_buf_damage(void *p_buf) 613{ 614#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE) 615 616 UINT32 *magic; 617 magic = (UINT32 *)((UINT8 *) p_buf + GKI_get_buf_size(p_buf)); 618 619 if ((UINT32)magic & 1) 620 return (TRUE); 621 622 if (*magic == MAGIC_NO) 623 return (FALSE); 624 625 return (TRUE); 626 627#else 628 629 return (FALSE); 630 631#endif 632} 633 634/******************************************************************************* 635** 636** Function GKI_send_msg 637** 638** Description Called by applications to send a buffer to a task 639** 640** Returns Nothing 641** 642*******************************************************************************/ 643void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg) 644{ 645 BUFFER_HDR_T *p_hdr; 646 tGKI_COM_CB *p_cb = &gki_cb.com; 647 648 /* If task non-existant or not started, drop buffer */ 649 if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD)) 650 { 651 GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest"); 652 GKI_freebuf (msg); 653 return; 654 } 655 656#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE) 657 if (gki_chk_buf_damage(msg)) 658 { 659 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted"); 660 return; 661 } 662#endif 663 664 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE); 665 666 if (p_hdr->status != BUF_STATUS_UNLINKED) 667 { 668 GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked"); 669 return; 670 } 671 672 GKI_disable(); 673 674 if (p_cb->OSTaskQFirst[task_id][mbox]) 675 p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr; 676 else 677 p_cb->OSTaskQFirst[task_id][mbox] = p_hdr; 678 679 p_cb->OSTaskQLast[task_id][mbox] = p_hdr; 680 681 p_hdr->p_next = NULL; 682 p_hdr->status = BUF_STATUS_QUEUED; 683 p_hdr->task_id = task_id; 684 685 686 GKI_enable(); 687 688 GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox)); 689 690 return; 691} 692 693/******************************************************************************* 694** 695** Function GKI_read_mbox 696** 697** Description Called by applications to read a buffer from one of 698** the task mailboxes. A task can only read its own mailbox. 699** 700** Parameters: mbox - (input) mailbox ID to read (0, 1, 2, or 3) 701** 702** Returns NULL if the mailbox was empty, else the address of a buffer 703** 704*******************************************************************************/ 705void *GKI_read_mbox (UINT8 mbox) 706{ 707 UINT8 task_id = GKI_get_taskid(); 708 void *p_buf = NULL; 709 BUFFER_HDR_T *p_hdr; 710 711 if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX)) 712 return (NULL); 713 714 GKI_disable(); 715 716 if (gki_cb.com.OSTaskQFirst[task_id][mbox]) 717 { 718 p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox]; 719 gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next; 720 721 p_hdr->p_next = NULL; 722 p_hdr->status = BUF_STATUS_UNLINKED; 723 724 p_buf = (UINT8 *)p_hdr + BUFFER_HDR_SIZE; 725 } 726 727 GKI_enable(); 728 729 return (p_buf); 730} 731 732 733 734/******************************************************************************* 735** 736** Function GKI_enqueue 737** 738** Description Enqueue a buffer at the tail of the queue 739** 740** Parameters: p_q - (input) pointer to a queue. 741** p_buf - (input) address of the buffer to enqueue 742** 743** Returns void 744** 745*******************************************************************************/ 746void GKI_enqueue (BUFFER_Q *p_q, void *p_buf) 747{ 748 BUFFER_HDR_T *p_hdr; 749 750#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE) 751 if (gki_chk_buf_damage(p_buf)) 752 { 753 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted"); 754 return; 755 } 756#endif 757 758 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE); 759 760 if (p_hdr->status != BUF_STATUS_UNLINKED) 761 { 762 GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue - buf already linked"); 763 return; 764 } 765 766 GKI_disable(); 767 768 /* Since the queue is exposed (C vs C++), keep the pointers in exposed format */ 769 if (p_q->p_last) 770 { 771 BUFFER_HDR_T *p_last_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_last - BUFFER_HDR_SIZE); 772 p_last_hdr->p_next = p_hdr; 773 } 774 else 775 p_q->p_first = p_buf; 776 777 p_q->p_last = p_buf; 778 p_q->count++; 779 780 p_hdr->p_next = NULL; 781 p_hdr->status = BUF_STATUS_QUEUED; 782 783 GKI_enable(); 784 785 return; 786} 787 788 789/******************************************************************************* 790** 791** Function GKI_enqueue_head 792** 793** Description Enqueue a buffer at the head of the queue 794** 795** Parameters: p_q - (input) pointer to a queue. 796** p_buf - (input) address of the buffer to enqueue 797** 798** Returns void 799** 800*******************************************************************************/ 801void GKI_enqueue_head (BUFFER_Q *p_q, void *p_buf) 802{ 803 BUFFER_HDR_T *p_hdr; 804 805#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE) 806 if (gki_chk_buf_damage(p_buf)) 807 { 808 GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted"); 809 return; 810 } 811#endif 812 813 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE); 814 815 if (p_hdr->status != BUF_STATUS_UNLINKED) 816 { 817 GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue head - buf already linked"); 818 return; 819 } 820 821 GKI_disable(); 822 823 if (p_q->p_first) 824 { 825 p_hdr->p_next = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE); 826 p_q->p_first = p_buf; 827 } 828 else 829 { 830 p_q->p_first = p_buf; 831 p_q->p_last = p_buf; 832 p_hdr->p_next = NULL; 833 } 834 p_q->count++; 835 836 p_hdr->status = BUF_STATUS_QUEUED; 837 838 GKI_enable(); 839 840 return; 841} 842 843 844/******************************************************************************* 845** 846** Function GKI_dequeue 847** 848** Description Dequeues a buffer from the head of a queue 849** 850** Parameters: p_q - (input) pointer to a queue. 851** 852** Returns NULL if queue is empty, else buffer 853** 854*******************************************************************************/ 855void *GKI_dequeue (BUFFER_Q *p_q) 856{ 857 BUFFER_HDR_T *p_hdr; 858 859 GKI_disable(); 860 861 if (!p_q || !p_q->count) 862 { 863 GKI_enable(); 864 return (NULL); 865 } 866 867 p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE); 868 869 /* Keep buffers such that GKI header is invisible 870 */ 871 if (p_hdr->p_next) 872 p_q->p_first = ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE); 873 else 874 { 875 p_q->p_first = NULL; 876 p_q->p_last = NULL; 877 } 878 879 p_q->count--; 880 881 p_hdr->p_next = NULL; 882 p_hdr->status = BUF_STATUS_UNLINKED; 883 884 GKI_enable(); 885 886 return ((UINT8 *)p_hdr + BUFFER_HDR_SIZE); 887} 888 889 890/******************************************************************************* 891** 892** Function GKI_remove_from_queue 893** 894** Description Dequeue a buffer from the middle of the queue 895** 896** Parameters: p_q - (input) pointer to a queue. 897** p_buf - (input) address of the buffer to enqueue 898** 899** Returns NULL if queue is empty, else buffer 900** 901*******************************************************************************/ 902void *GKI_remove_from_queue (BUFFER_Q *p_q, void *p_buf) 903{ 904 BUFFER_HDR_T *p_prev; 905 BUFFER_HDR_T *p_buf_hdr; 906 907 GKI_disable(); 908 909 if (p_buf == p_q->p_first) 910 { 911 GKI_enable(); 912 return (GKI_dequeue (p_q)); 913 } 914 915 p_buf_hdr = (BUFFER_HDR_T *)((UINT8 *)p_buf - BUFFER_HDR_SIZE); 916 p_prev = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE); 917 918 for ( ; p_prev; p_prev = p_prev->p_next) 919 { 920 /* If the previous points to this one, move the pointers around */ 921 if (p_prev->p_next == p_buf_hdr) 922 { 923 p_prev->p_next = p_buf_hdr->p_next; 924 925 /* If we are removing the last guy in the queue, update p_last */ 926 if (p_buf == p_q->p_last) 927 p_q->p_last = p_prev + 1; 928 929 /* One less in the queue */ 930 p_q->count--; 931 932 /* The buffer is now unlinked */ 933 p_buf_hdr->p_next = NULL; 934 p_buf_hdr->status = BUF_STATUS_UNLINKED; 935 936 GKI_enable(); 937 return (p_buf); 938 } 939 } 940 941 GKI_enable(); 942 return (NULL); 943} 944 945/******************************************************************************* 946** 947** Function GKI_getfirst 948** 949** Description Return a pointer to the first buffer in a queue 950** 951** Parameters: p_q - (input) pointer to a queue. 952** 953** Returns NULL if queue is empty, else buffer address 954** 955*******************************************************************************/ 956void *GKI_getfirst (BUFFER_Q *p_q) 957{ 958 return (p_q->p_first); 959} 960 961 962/******************************************************************************* 963** 964** Function GKI_getlast 965** 966** Description Return a pointer to the last buffer in a queue 967** 968** Parameters: p_q - (input) pointer to a queue. 969** 970** Returns NULL if queue is empty, else buffer address 971** 972*******************************************************************************/ 973void *GKI_getlast (BUFFER_Q *p_q) 974{ 975 return (p_q->p_last); 976} 977 978/******************************************************************************* 979** 980** Function GKI_getnext 981** 982** Description Return a pointer to the next buffer in a queue 983** 984** Parameters: p_buf - (input) pointer to the buffer to find the next one from. 985** 986** Returns NULL if no more buffers in the queue, else next buffer address 987** 988*******************************************************************************/ 989void *GKI_getnext (void *p_buf) 990{ 991 BUFFER_HDR_T *p_hdr; 992 993 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE); 994 995 if (p_hdr->p_next) 996 return ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE); 997 else 998 return (NULL); 999} 1000 1001 1002 1003/******************************************************************************* 1004** 1005** Function GKI_queue_is_empty 1006** 1007** Description Check the status of a queue. 1008** 1009** Parameters: p_q - (input) pointer to a queue. 1010** 1011** Returns TRUE if queue is empty, else FALSE 1012** 1013*******************************************************************************/ 1014BOOLEAN GKI_queue_is_empty(BUFFER_Q *p_q) 1015{ 1016 return ((BOOLEAN) (p_q->count == 0)); 1017} 1018 1019/******************************************************************************* 1020** 1021** Function gki_add_to_pool_list 1022** 1023** Description Adds pool to the pool list which is arranged in the 1024** order of size 1025** 1026** Returns void 1027** 1028*******************************************************************************/ 1029static void gki_add_to_pool_list(UINT8 pool_id) 1030{ 1031 1032 INT32 i, j; 1033 tGKI_COM_CB *p_cb = &gki_cb.com; 1034 1035 /* Find the position where the specified pool should be inserted into the list */ 1036 for(i=0; i < p_cb->curr_total_no_of_pools; i++) 1037 { 1038 1039 if(p_cb->freeq[pool_id].size <= p_cb->freeq[ p_cb->pool_list[i] ].size) 1040 break; 1041 } 1042 1043 /* Insert the new buffer pool ID into the list of pools */ 1044 for(j = p_cb->curr_total_no_of_pools; j > i; j--) 1045 { 1046 p_cb->pool_list[j] = p_cb->pool_list[j-1]; 1047 } 1048 1049 p_cb->pool_list[i] = pool_id; 1050 1051 return; 1052} 1053 1054/******************************************************************************* 1055** 1056** Function gki_remove_from_pool_list 1057** 1058** Description Removes pool from the pool list. Called when a pool is deleted 1059** 1060** Returns void 1061** 1062*******************************************************************************/ 1063static void gki_remove_from_pool_list(UINT8 pool_id) 1064{ 1065 tGKI_COM_CB *p_cb = &gki_cb.com; 1066 UINT8 i; 1067 1068 for(i=0; i < p_cb->curr_total_no_of_pools; i++) 1069 { 1070 if(pool_id == p_cb->pool_list[i]) 1071 break; 1072 } 1073 1074 while (i < (p_cb->curr_total_no_of_pools - 1)) 1075 { 1076 p_cb->pool_list[i] = p_cb->pool_list[i+1]; 1077 i++; 1078 } 1079 1080 return; 1081} 1082 1083/******************************************************************************* 1084** 1085** Function GKI_igetpoolbuf 1086** 1087** Description Called by an interrupt service routine to get a free buffer from 1088** a specific buffer pool. 1089** 1090** Parameters pool_id - (input) pool ID to get a buffer out of. 1091** 1092** Returns A pointer to the buffer, or NULL if none available 1093** 1094*******************************************************************************/ 1095void *GKI_igetpoolbuf (UINT8 pool_id) 1096{ 1097 FREE_QUEUE_T *Q; 1098 BUFFER_HDR_T *p_hdr; 1099 1100 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) 1101 return (NULL); 1102 1103 1104 Q = &gki_cb.com.freeq[pool_id]; 1105 if(Q->cur_cnt < Q->total) 1106 { 1107 p_hdr = Q->p_first; 1108 Q->p_first = p_hdr->p_next; 1109 1110 if (!Q->p_first) 1111 Q->p_last = NULL; 1112 1113 if(++Q->cur_cnt > Q->max_cnt) 1114 Q->max_cnt = Q->cur_cnt; 1115 1116 p_hdr->task_id = GKI_get_taskid(); 1117 1118 p_hdr->status = BUF_STATUS_UNLINKED; 1119 p_hdr->p_next = NULL; 1120 p_hdr->Type = 0; 1121 1122 return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE)); 1123 } 1124 1125 return (NULL); 1126} 1127 1128/******************************************************************************* 1129** 1130** Function GKI_poolcount 1131** 1132** Description Called by an application to get the total number of buffers 1133** in the specified buffer pool. 1134** 1135** Parameters pool_id - (input) pool ID to get the free count of. 1136** 1137** Returns the total number of buffers in the pool 1138** 1139*******************************************************************************/ 1140UINT16 GKI_poolcount (UINT8 pool_id) 1141{ 1142 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) 1143 return (0); 1144 1145 return (gki_cb.com.freeq[pool_id].total); 1146} 1147 1148/******************************************************************************* 1149** 1150** Function GKI_poolfreecount 1151** 1152** Description Called by an application to get the number of free buffers 1153** in the specified buffer pool. 1154** 1155** Parameters pool_id - (input) pool ID to get the free count of. 1156** 1157** Returns the number of free buffers in the pool 1158** 1159*******************************************************************************/ 1160UINT16 GKI_poolfreecount (UINT8 pool_id) 1161{ 1162 FREE_QUEUE_T *Q; 1163 1164 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) 1165 return (0); 1166 1167 Q = &gki_cb.com.freeq[pool_id]; 1168 1169 return ((UINT16)(Q->total - Q->cur_cnt)); 1170} 1171 1172/******************************************************************************* 1173** 1174** Function GKI_get_pool_bufsize 1175** 1176** Description Called by an application to get the size of buffers in a pool 1177** 1178** Parameters Pool ID. 1179** 1180** Returns the size of buffers in the pool 1181** 1182*******************************************************************************/ 1183UINT16 GKI_get_pool_bufsize (UINT8 pool_id) 1184{ 1185 if (pool_id < GKI_NUM_TOTAL_BUF_POOLS) 1186 return (gki_cb.com.freeq[pool_id].size); 1187 1188 return (0); 1189} 1190 1191/******************************************************************************* 1192** 1193** Function GKI_poolutilization 1194** 1195** Description Called by an application to get the buffer utilization 1196** in the specified buffer pool. 1197** 1198** Parameters pool_id - (input) pool ID to get the free count of. 1199** 1200** Returns % of buffers used from 0 to 100 1201** 1202*******************************************************************************/ 1203UINT16 GKI_poolutilization (UINT8 pool_id) 1204{ 1205 FREE_QUEUE_T *Q; 1206 1207 if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) 1208 return (100); 1209 1210 Q = &gki_cb.com.freeq[pool_id]; 1211 1212 if (Q->total == 0) 1213 return (100); 1214 1215 return ((Q->cur_cnt * 100) / Q->total); 1216} 1217 1218