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