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