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