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 *******************************************************************************/
gki_init_free_queue(uint8_t id,uint16_t size,uint16_t total,void * p_mem)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)
gki_alloc_free_queue(uint8_t id)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 *******************************************************************************/
gki_buffer_init(void)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 *******************************************************************************/
GKI_init_q(BUFFER_Q * p_q)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)
GKI_getbuf_debug(uint16_t size,const char * _function_,int _line_)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)
GKI_getpoolbuf_debug(uint8_t pool_id,const char * _function_,int _line_)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 *******************************************************************************/
GKI_freebuf(void * p_buf)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 *******************************************************************************/
GKI_get_buf_size(void * p_buf)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 *******************************************************************************/
gki_chk_buf_damage(void * p_buf)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 *******************************************************************************/
GKI_send_msg(uint8_t task_id,uint8_t mbox,void * msg)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 *******************************************************************************/
GKI_read_mbox(uint8_t mbox)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 *******************************************************************************/
GKI_enqueue(BUFFER_Q * p_q,void * p_buf)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 *******************************************************************************/
GKI_enqueue_head(BUFFER_Q * p_q,void * p_buf)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 *******************************************************************************/
GKI_dequeue(BUFFER_Q * p_q)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 *******************************************************************************/
GKI_remove_from_queue(BUFFER_Q * p_q,void * p_buf)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 *******************************************************************************/
GKI_getfirst(BUFFER_Q * p_q)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 *******************************************************************************/
GKI_getlast(BUFFER_Q * p_q)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 *******************************************************************************/
GKI_getnext(void * p_buf)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 *******************************************************************************/
GKI_queue_is_empty(BUFFER_Q * p_q)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 *******************************************************************************/
GKI_find_buf_start(void * p_user_area)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 *******************************************************************************/
GKI_set_pool_permission(uint8_t pool_id,uint8_t permission)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 *******************************************************************************/
gki_add_to_pool_list(uint8_t pool_id)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 *******************************************************************************/
gki_remove_from_pool_list(uint8_t pool_id)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 *******************************************************************************/
GKI_igetpoolbuf(uint8_t pool_id)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 *******************************************************************************/
GKI_poolcount(uint8_t pool_id)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 *******************************************************************************/
GKI_poolfreecount(uint8_t pool_id)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 *******************************************************************************/
GKI_change_buf_owner(void * p_buf,uint8_t task_id)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 *******************************************************************************/
GKI_isend_msg(uint8_t task_id,uint8_t mbox,void * msg)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 *******************************************************************************/
GKI_create_pool(uint16_t size,uint16_t count,uint8_t permission,void * p_mem_pool)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 *******************************************************************************/
GKI_delete_pool(uint8_t pool_id)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 *******************************************************************************/
GKI_get_pool_bufsize(uint8_t pool_id)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 *******************************************************************************/
GKI_poolutilization(uint8_t pool_id)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