• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 1999-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 #include "gki_int.h"
19 
20 #ifndef BT_ERROR_TRACE_0
21 #define BT_ERROR_TRACE_0(l, m)
22 #endif
23 
24 /* Make sure that this has been defined in target.h */
25 #ifndef GKI_NUM_TIMERS
26 #error NO TIMERS: Must define at least 1 timer in the system!
27 #endif
28 
29 /* Largest signed positive timer count */
30 #define GKI_NO_NEW_TMRS_STARTED (0x7fffffffL)
31 /* Marks an unused timer list entry (initial value) */
32 #define GKI_UNUSED_LIST_ENTRY (0x80000000L)
33 #define GKI_MAX_INT32 (0x7fffffffL)
34 
35 /*******************************************************************************
36 **
37 ** Function         gki_timers_init
38 **
39 ** Description      This internal function is called once at startup to
40 *initialize
41 **                  all the timer structures.
42 **
43 ** Returns          void
44 **
45 *******************************************************************************/
gki_timers_init(void)46 void gki_timers_init(void) {
47   uint8_t tt;
48 
49   gki_cb.com.OSTicksTilExp =
50       0; /* Remaining time (of OSTimeCurTimeout) before next timer expires */
51   gki_cb.com.OSNumOrigTicks = 0;
52 #if (GKI_DELAY_STOP_SYS_TICK > 0)
53   gki_cb.com.OSTicksTilStop = 0; /* clear inactivity delay timer */
54 #endif
55 
56   for (tt = 0; tt < GKI_MAX_TASKS; tt++) {
57     gki_cb.com.OSWaitTmr[tt] = 0;
58 
59 #if (GKI_NUM_TIMERS > 0)
60     gki_cb.com.OSTaskTmr0[tt] = 0;
61     gki_cb.com.OSTaskTmr0R[tt] = 0;
62 #endif
63 
64 #if (GKI_NUM_TIMERS > 1)
65     gki_cb.com.OSTaskTmr1[tt] = 0;
66     gki_cb.com.OSTaskTmr1R[tt] = 0;
67 #endif
68 
69 #if (GKI_NUM_TIMERS > 2)
70     gki_cb.com.OSTaskTmr2[tt] = 0;
71     gki_cb.com.OSTaskTmr2R[tt] = 0;
72 #endif
73 
74 #if (GKI_NUM_TIMERS > 3)
75     gki_cb.com.OSTaskTmr3[tt] = 0;
76     gki_cb.com.OSTaskTmr3R[tt] = 0;
77 #endif
78   }
79 
80   for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
81     gki_cb.com.timer_queues[tt] = NULL;
82   }
83 
84   gki_cb.com.p_tick_cb = NULL;
85   gki_cb.com.system_tick_running = false;
86 
87   return;
88 }
89 
90 /*******************************************************************************
91 **
92 ** Function         gki_timers_is_timer_running
93 **
94 ** Description      This internal function is called to test if any gki timer
95 *are running
96 **
97 **
98 ** Returns          TRUE if at least one time is running in the system, FALSE
99 *else.
100 **
101 *******************************************************************************/
gki_timers_is_timer_running(void)102 bool gki_timers_is_timer_running(void) {
103   uint8_t tt;
104   for (tt = 0; tt < GKI_MAX_TASKS; tt++) {
105 #if (GKI_NUM_TIMERS > 0)
106     if (gki_cb.com.OSTaskTmr0[tt]) {
107       return true;
108     }
109 #endif
110 
111 #if (GKI_NUM_TIMERS > 1)
112     if (gki_cb.com.OSTaskTmr1[tt]) {
113       return true;
114     }
115 #endif
116 
117 #if (GKI_NUM_TIMERS > 2)
118     if (gki_cb.com.OSTaskTmr2[tt]) {
119       return true;
120     }
121 #endif
122 
123 #if (GKI_NUM_TIMERS > 3)
124     if (gki_cb.com.OSTaskTmr3[tt]) {
125       return true;
126     }
127 #endif
128   }
129 
130   return false;
131 }
132 
133 /*******************************************************************************
134 **
135 ** Function         GKI_get_tick_count
136 **
137 ** Description      This function returns the current system ticks
138 **
139 ** Returns          The current number of system ticks
140 **
141 *******************************************************************************/
GKI_get_tick_count(void)142 uint32_t GKI_get_tick_count(void) { return gki_cb.com.OSTicks; }
143 
144 /*******************************************************************************
145 **
146 ** Function         GKI_ready_to_sleep
147 **
148 ** Description      This function returns the number of system ticks until the
149 **                  next timer will expire.  It is typically called by a power
150 **                  savings manager to find out how long it can have the system
151 **                  sleep before it needs to service the next entry.
152 **
153 ** Parameters:      None
154 **
155 ** Returns          Number of ticks til the next timer expires
156 **                  Note: the value is a signed  value.  This value should be
157 **                      compared to x > 0, to avoid misinterpreting negative
158 *tick
159 **                      values.
160 **
161 *******************************************************************************/
GKI_ready_to_sleep(void)162 int32_t GKI_ready_to_sleep(void) { return (gki_cb.com.OSTicksTilExp); }
163 
164 /*******************************************************************************
165 **
166 ** Function         GKI_start_timer
167 **
168 ** Description      An application can call this function to start one of
169 **                  it's four general purpose timers. Any of the four timers
170 **                  can be 1-shot or continuous. If a timer is already running,
171 **                  it will be reset to the new parameters.
172 **
173 ** Parameters       tnum            - (input) timer number to be started
174 *(TIMER_0,
175 **                                              TIMER_1, TIMER_2, or TIMER_3)
176 **                  ticks           - (input) the number of system ticks til the
177 **                                              timer expires.
178 **                  is_continuous   - (input) TRUE if timer restarts
179 *automatically,
180 **                                              else FALSE if it is a
181 *'one-shot'.
182 **
183 ** Returns          void
184 **
185 *******************************************************************************/
GKI_start_timer(uint8_t tnum,int32_t ticks,bool is_continuous)186 void GKI_start_timer(uint8_t tnum, int32_t ticks, bool is_continuous) {
187   int32_t reload;
188   int32_t orig_ticks;
189   uint8_t task_id = GKI_get_taskid();
190   bool bad_timer = false;
191 
192   if (ticks <= 0) ticks = 1;
193 
194   orig_ticks = ticks; /* save the ticks in case adjustment is necessary */
195 
196   /* If continuous timer, set reload, else set it to 0 */
197   if (is_continuous)
198     reload = ticks;
199   else
200     reload = 0;
201 
202   GKI_disable();
203 
204   if (gki_timers_is_timer_running() == false) {
205 #if (GKI_DELAY_STOP_SYS_TICK > 0)
206     /* if inactivity delay timer is not running, start system tick */
207     if (gki_cb.com.OSTicksTilStop == 0) {
208 #endif
209       if (gki_cb.com.p_tick_cb) {
210         /* start system tick */
211         gki_cb.com.system_tick_running = true;
212         (gki_cb.com.p_tick_cb)(true);
213       }
214 #if (GKI_DELAY_STOP_SYS_TICK > 0)
215     } else {
216       /* clear inactivity delay timer */
217       gki_cb.com.OSTicksTilStop = 0;
218     }
219 #endif
220   }
221   /* Add the time since the last task timer update.
222   ** Note that this works when no timers are active since
223   ** both OSNumOrigTicks and OSTicksTilExp are 0.
224   */
225   if (GKI_MAX_INT32 - (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) >
226       ticks) {
227     ticks += gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp;
228   } else
229     ticks = GKI_MAX_INT32;
230 
231   switch (tnum) {
232 #if (GKI_NUM_TIMERS > 0)
233     case TIMER_0:
234       gki_cb.com.OSTaskTmr0R[task_id] = reload;
235       gki_cb.com.OSTaskTmr0[task_id] = ticks;
236       break;
237 #endif
238 
239 #if (GKI_NUM_TIMERS > 1)
240     case TIMER_1:
241       gki_cb.com.OSTaskTmr1R[task_id] = reload;
242       gki_cb.com.OSTaskTmr1[task_id] = ticks;
243       break;
244 #endif
245 
246 #if (GKI_NUM_TIMERS > 2)
247     case TIMER_2:
248       gki_cb.com.OSTaskTmr2R[task_id] = reload;
249       gki_cb.com.OSTaskTmr2[task_id] = ticks;
250       break;
251 #endif
252 
253 #if (GKI_NUM_TIMERS > 3)
254     case TIMER_3:
255       gki_cb.com.OSTaskTmr3R[task_id] = reload;
256       gki_cb.com.OSTaskTmr3[task_id] = ticks;
257       break;
258 #endif
259     default:
260       bad_timer = true; /* Timer number is bad, so do not use */
261   }
262 
263   /* Update the expiration timeout if a legitimate timer */
264   if (!bad_timer) {
265     /* Only update the timeout value if it is less than any other newly started
266      * timers */
267     gki_adjust_timer_count(orig_ticks);
268   }
269 
270   GKI_enable();
271 }
272 
273 /*******************************************************************************
274 **
275 ** Function         GKI_stop_timer
276 **
277 ** Description      An application can call this function to stop one of
278 **                  it's four general purpose timers. There is no harm in
279 **                  stopping a timer that is already stopped.
280 **
281 ** Parameters       tnum            - (input) timer number to be started
282 *(TIMER_0,
283 **                                              TIMER_1, TIMER_2, or TIMER_3)
284 ** Returns          void
285 **
286 *******************************************************************************/
GKI_stop_timer(uint8_t tnum)287 void GKI_stop_timer(uint8_t tnum) {
288   uint8_t task_id = GKI_get_taskid();
289 
290   GKI_disable();
291 
292   switch (tnum) {
293 #if (GKI_NUM_TIMERS > 0)
294     case TIMER_0:
295       gki_cb.com.OSTaskTmr0R[task_id] = 0;
296       gki_cb.com.OSTaskTmr0[task_id] = 0;
297       break;
298 #endif
299 
300 #if (GKI_NUM_TIMERS > 1)
301     case TIMER_1:
302       gki_cb.com.OSTaskTmr1R[task_id] = 0;
303       gki_cb.com.OSTaskTmr1[task_id] = 0;
304       break;
305 #endif
306 
307 #if (GKI_NUM_TIMERS > 2)
308     case TIMER_2:
309       gki_cb.com.OSTaskTmr2R[task_id] = 0;
310       gki_cb.com.OSTaskTmr2[task_id] = 0;
311       break;
312 #endif
313 
314 #if (GKI_NUM_TIMERS > 3)
315     case TIMER_3:
316       gki_cb.com.OSTaskTmr3R[task_id] = 0;
317       gki_cb.com.OSTaskTmr3[task_id] = 0;
318       break;
319 #endif
320   }
321 
322   if (gki_timers_is_timer_running() == false) {
323     if (gki_cb.com.p_tick_cb) {
324 #if (GKI_DELAY_STOP_SYS_TICK > 0)
325       /* if inactivity delay timer is not running */
326       if ((gki_cb.com.system_tick_running) &&
327           (gki_cb.com.OSTicksTilStop == 0)) {
328         /* set inactivity delay timer */
329         /* when timer expires, system tick will be stopped */
330         gki_cb.com.OSTicksTilStop = GKI_DELAY_STOP_SYS_TICK;
331       }
332 #else
333       gki_cb.com.system_tick_running = false;
334       (gki_cb.com.p_tick_cb)(false); /* stop system tick */
335 #endif
336     }
337   }
338 
339   GKI_enable();
340 }
341 
342 /*******************************************************************************
343 **
344 ** Function         GKI_timer_update
345 **
346 ** Description      This function is called by an OS to drive the GKI's timers.
347 **                  It is typically called at every system tick to
348 **                  update the timers for all tasks, and check for timeouts.
349 **
350 **                  Note: It has been designed to also allow for variable tick
351 *updates
352 **                      so that systems with strict power savings requirements
353 *can
354 **                      have the update occur at variable intervals.
355 **
356 ** Parameters:      ticks_since_last_update - (input) This is the number of
357 *TICKS that have
358 **                          occurred since the last time GKI_timer_update was
359 *called.
360 **
361 ** Returns          void
362 **
363 *******************************************************************************/
GKI_timer_update(int32_t ticks_since_last_update)364 void GKI_timer_update(int32_t ticks_since_last_update) {
365   uint8_t task_id;
366   long next_expiration; /* Holds the next soonest expiration time after this
367                            update */
368 
369   /* Increment the number of ticks used for time stamps */
370   gki_cb.com.OSTicks += ticks_since_last_update;
371 
372   /* If any timers are running in any tasks, decrement the remaining time til
373    * the timer updates need to take place (next expiration occurs)
374    */
375   gki_cb.com.OSTicksTilExp -= ticks_since_last_update;
376 
377   /* Don't allow timer interrupt nesting */
378   if (gki_cb.com.timer_nesting) return;
379 
380   gki_cb.com.timer_nesting = 1;
381 
382 #if (GKI_DELAY_STOP_SYS_TICK > 0)
383   /* if inactivity delay timer is set and expired */
384   if (gki_cb.com.OSTicksTilStop) {
385     if (gki_cb.com.OSTicksTilStop <= (uint32_t)ticks_since_last_update) {
386       if (gki_cb.com.p_tick_cb) {
387         gki_cb.com.system_tick_running = false;
388         (gki_cb.com.p_tick_cb)(false); /* stop system tick */
389       }
390       gki_cb.com.OSTicksTilStop = 0; /* clear inactivity delay timer */
391       gki_cb.com.timer_nesting = 0;
392       return;
393     } else
394       gki_cb.com.OSTicksTilStop -= ticks_since_last_update;
395   }
396 #endif
397 
398   /* No need to update the ticks if no timeout has occurred */
399   if (gki_cb.com.OSTicksTilExp > 0) {
400     gki_cb.com.timer_nesting = 0;
401     return;
402   }
403 
404   GKI_disable();
405 
406   next_expiration = GKI_NO_NEW_TMRS_STARTED;
407 
408   /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase
409      gki_cb.com.OSNumOrigTicks
410      to account for the difference so timer updates below are decremented by the
411      full number
412      of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function
413      so changing this
414      value only affects the timer updates below
415    */
416   gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp;
417 
418   /* Check for OS Task Timers */
419   for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) {
420     if (gki_cb.com.OSRdyTbl[task_id] == TASK_DEAD) {
421       // task is shutdown do not try to service timers
422       continue;
423     }
424 
425     if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */
426     {
427       gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks;
428       if (gki_cb.com.OSWaitTmr[task_id] <= 0) {
429         /* Timer Expired */
430         gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
431       }
432     }
433 
434 #if (GKI_NUM_TIMERS > 0)
435     /* If any timer is running, decrement */
436     if (gki_cb.com.OSTaskTmr0[task_id] > 0) {
437       gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
438 
439       if (gki_cb.com.OSTaskTmr0[task_id] <= 0) {
440 /* Set Timer 0 Expired event mask and reload timer */
441 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE)
442         GKI_isend_event(task_id, TIMER_0_EVT_MASK);
443 #else
444         GKI_send_event(task_id, TIMER_0_EVT_MASK);
445 #endif
446         gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
447       }
448     }
449 
450     /* Check to see if this timer is the next one to expire */
451     if (gki_cb.com.OSTaskTmr0[task_id] > 0 &&
452         gki_cb.com.OSTaskTmr0[task_id] < next_expiration)
453       next_expiration = gki_cb.com.OSTaskTmr0[task_id];
454 #endif
455 
456 #if (GKI_NUM_TIMERS > 1)
457     /* If any timer is running, decrement */
458     if (gki_cb.com.OSTaskTmr1[task_id] > 0) {
459       gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks;
460 
461       if (gki_cb.com.OSTaskTmr1[task_id] <= 0) {
462 /* Set Timer 1 Expired event mask and reload timer */
463 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE)
464         GKI_isend_event(task_id, TIMER_1_EVT_MASK);
465 #else
466         GKI_send_event(task_id, TIMER_1_EVT_MASK);
467 #endif
468         gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id];
469       }
470     }
471 
472     /* Check to see if this timer is the next one to expire */
473     if (gki_cb.com.OSTaskTmr1[task_id] > 0 &&
474         gki_cb.com.OSTaskTmr1[task_id] < next_expiration)
475       next_expiration = gki_cb.com.OSTaskTmr1[task_id];
476 #endif
477 
478 #if (GKI_NUM_TIMERS > 2)
479     /* If any timer is running, decrement */
480     if (gki_cb.com.OSTaskTmr2[task_id] > 0) {
481       gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks;
482 
483       if (gki_cb.com.OSTaskTmr2[task_id] <= 0) {
484 /* Set Timer 2 Expired event mask and reload timer */
485 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE)
486         GKI_isend_event(task_id, TIMER_2_EVT_MASK);
487 #else
488         GKI_send_event(task_id, TIMER_2_EVT_MASK);
489 #endif
490         gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id];
491       }
492     }
493 
494     /* Check to see if this timer is the next one to expire */
495     if (gki_cb.com.OSTaskTmr2[task_id] > 0 &&
496         gki_cb.com.OSTaskTmr2[task_id] < next_expiration)
497       next_expiration = gki_cb.com.OSTaskTmr2[task_id];
498 #endif
499 
500 #if (GKI_NUM_TIMERS > 3)
501     /* If any timer is running, decrement */
502     if (gki_cb.com.OSTaskTmr3[task_id] > 0) {
503       gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks;
504 
505       if (gki_cb.com.OSTaskTmr3[task_id] <= 0) {
506 /* Set Timer 3 Expired event mask and reload timer */
507 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE)
508         GKI_isend_event(task_id, TIMER_3_EVT_MASK);
509 #else
510         GKI_send_event(task_id, TIMER_3_EVT_MASK);
511 #endif
512         gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id];
513       }
514     }
515 
516     /* Check to see if this timer is the next one to expire */
517     if (gki_cb.com.OSTaskTmr3[task_id] > 0 &&
518         gki_cb.com.OSTaskTmr3[task_id] < next_expiration)
519       next_expiration = gki_cb.com.OSTaskTmr3[task_id];
520 #endif
521   }
522 
523   /* Set the next timer experation value if there is one to start */
524   if (next_expiration < GKI_NO_NEW_TMRS_STARTED) {
525     gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration;
526   } else {
527     gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0;
528   }
529 
530   gki_cb.com.timer_nesting = 0;
531 
532   GKI_enable();
533 
534   return;
535 }
536 
537 /*******************************************************************************
538 **
539 ** Function         GKI_timer_queue_empty
540 **
541 ** Description      This function is called by applications to see whether the
542 *timer
543 **                  queue is empty
544 **
545 ** Parameters
546 **
547 ** Returns          bool
548 **
549 *******************************************************************************/
GKI_timer_queue_empty(void)550 bool GKI_timer_queue_empty(void) {
551   uint8_t tt;
552 
553   for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
554     if (gki_cb.com.timer_queues[tt]) return false;
555   }
556 
557   return true;
558 }
559 
560 /*******************************************************************************
561 **
562 ** Function         GKI_timer_queue_register_callback
563 **
564 ** Description      This function is called by applications to register system
565 *tick
566 **                  start/stop callback for time queues
567 **
568 **
569 ** Parameters       p_callback - (input) pointer to the system tick callback
570 **
571 ** Returns          bool
572 **
573 *******************************************************************************/
GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK * p_callback)574 void GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK* p_callback) {
575   gki_cb.com.p_tick_cb = p_callback;
576 
577   return;
578 }
579 
580 /*******************************************************************************
581 **
582 ** Function         GKI_init_timer_list
583 **
584 ** Description      This function is called by applications when they
585 **                  want to initialize a timer list.
586 **
587 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue
588 *object
589 **
590 ** Returns          void
591 **
592 *******************************************************************************/
GKI_init_timer_list(TIMER_LIST_Q * p_timer_listq)593 void GKI_init_timer_list(TIMER_LIST_Q* p_timer_listq) {
594   p_timer_listq->p_first = NULL;
595   p_timer_listq->p_last = NULL;
596   p_timer_listq->last_ticks = 0;
597 
598   return;
599 }
600 
601 /*******************************************************************************
602 **
603 ** Function         GKI_init_timer_list_entry
604 **
605 ** Description      This function is called by the applications when they
606 **                  want to initialize a timer list entry. This must be
607 **                  done prior to first use of the entry.
608 **
609 ** Parameters       p_tle           - (input) pointer to a timer list queue
610 *entry
611 **
612 ** Returns          void
613 **
614 *******************************************************************************/
GKI_init_timer_list_entry(TIMER_LIST_ENT * p_tle)615 void GKI_init_timer_list_entry(TIMER_LIST_ENT* p_tle) {
616   p_tle->p_next = NULL;
617   p_tle->p_prev = NULL;
618   p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
619   p_tle->in_use = false;
620 }
621 
622 /*******************************************************************************
623 **
624 ** Function         GKI_update_timer_list
625 **
626 ** Description      This function is called by the applications when they
627 **                  want to update a timer list. This should be at every
628 **                  timer list unit tick, e.g. once per sec, once per minute
629 *etc.
630 **
631 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue
632 *object
633 **                  num_units_since_last_update - (input) number of units since
634 *the last update
635 **                                  (allows for variable unit update)
636 **
637 **      NOTE: The following timer list update routines should not be used for
638 *exact time
639 **            critical purposes.  The timer tasks should be used when exact
640 *timing is needed.
641 **
642 ** Returns          the number of timers that have expired
643 **
644 *******************************************************************************/
GKI_update_timer_list(TIMER_LIST_Q * p_timer_listq,int32_t num_units_since_last_update)645 uint16_t GKI_update_timer_list(TIMER_LIST_Q* p_timer_listq,
646                                int32_t num_units_since_last_update) {
647   TIMER_LIST_ENT* p_tle;
648   uint16_t num_time_out = 0;
649   int32_t rem_ticks;
650   int32_t temp_ticks;
651 
652   p_tle = p_timer_listq->p_first;
653 
654   /* First, get the guys who have previously timed out */
655   /* Note that the tick value of the timers should always be '0' */
656   while ((p_tle) && (p_tle->ticks <= 0)) {
657     num_time_out++;
658     p_tle = p_tle->p_next;
659   }
660 
661   /* Timer entriy tick values are relative to the preceeding entry */
662   rem_ticks = num_units_since_last_update;
663 
664   /* Now, adjust remaining timer entries */
665   while ((p_tle != NULL) && (rem_ticks > 0)) {
666     temp_ticks = p_tle->ticks;
667     p_tle->ticks -= rem_ticks;
668 
669     /* See if this timer has just timed out */
670     if (p_tle->ticks <= 0) {
671       /* We set the number of ticks to '0' so that the legacy code
672        * that assumes a '0' or nonzero value will still work as coded. */
673       p_tle->ticks = 0;
674 
675       num_time_out++;
676     }
677 
678     rem_ticks -= temp_ticks; /* Decrement the remaining ticks to process */
679     p_tle = p_tle->p_next;
680   }
681 
682   if (p_timer_listq->last_ticks > 0) {
683     p_timer_listq->last_ticks -= num_units_since_last_update;
684 
685     /* If the last timer has expired set last_ticks to 0 so that other list
686     * update
687     * functions will calculate correctly
688     */
689     if (p_timer_listq->last_ticks < 0) p_timer_listq->last_ticks = 0;
690   }
691 
692   return (num_time_out);
693 }
694 
695 /*******************************************************************************
696 **
697 ** Function         GKI_get_remaining_ticks
698 **
699 ** Description      This function is called by an application to get remaining
700 **                  ticks to expire
701 **
702 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue
703 *object
704 **                  p_target_tle    - (input) pointer to a timer list queue
705 *entry
706 **
707 ** Returns          0 if timer is not used or timer is not in the list
708 **                  remaining ticks if success
709 **
710 *******************************************************************************/
GKI_get_remaining_ticks(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_target_tle)711 uint32_t GKI_get_remaining_ticks(TIMER_LIST_Q* p_timer_listq,
712                                  TIMER_LIST_ENT* p_target_tle) {
713   TIMER_LIST_ENT* p_tle;
714   uint32_t rem_ticks = 0;
715 
716   if (p_target_tle->in_use) {
717     p_tle = p_timer_listq->p_first;
718 
719     /* adding up all of ticks in previous entries */
720     while ((p_tle) && (p_tle != p_target_tle)) {
721       rem_ticks += p_tle->ticks;
722       p_tle = p_tle->p_next;
723     }
724 
725     /* if found target entry */
726     if (p_tle == p_target_tle) {
727       rem_ticks += p_tle->ticks;
728     } else {
729       BT_ERROR_TRACE_0(TRACE_LAYER_GKI,
730                        "GKI_get_remaining_ticks: No timer entry in the list");
731       return (0);
732     }
733   } else {
734     BT_ERROR_TRACE_0(TRACE_LAYER_GKI,
735                      "GKI_get_remaining_ticks: timer entry is not active");
736   }
737 
738   return (rem_ticks);
739 }
740 
741 /*******************************************************************************
742 **
743 ** Function         GKI_add_to_timer_list
744 **
745 ** Description      This function is called by an application to add a timer
746 **                  entry to a timer list.
747 **
748 **                  Note: A timer value of '0' will effectively insert an
749 *already
750 **                      expired event.  Negative tick values will be ignored.
751 **
752 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue
753 *object
754 **                  p_tle           - (input) pointer to a timer list queue
755 *entry
756 **
757 ** Returns          void
758 **
759 *******************************************************************************/
GKI_add_to_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)760 void GKI_add_to_timer_list(TIMER_LIST_Q* p_timer_listq, TIMER_LIST_ENT* p_tle) {
761   uint32_t nr_ticks_total;
762   uint8_t tt;
763   TIMER_LIST_ENT* p_temp;
764   if (p_tle == NULL || p_timer_listq == NULL) {
765     GKI_TRACE_3("%s: invalid argument %x, %x****************************<<",
766                 __func__, p_timer_listq, p_tle);
767     return;
768   }
769 
770   /* Only process valid tick values */
771   if (p_tle->ticks >= 0) {
772     /* If this entry is the last in the list */
773     if (p_tle->ticks >= p_timer_listq->last_ticks) {
774       /* If this entry is the only entry in the list */
775       if (p_timer_listq->p_first == NULL)
776         p_timer_listq->p_first = p_tle;
777       else {
778         /* Insert the entry onto the end of the list */
779         if (p_timer_listq->p_last != NULL)
780           p_timer_listq->p_last->p_next = p_tle;
781 
782         p_tle->p_prev = p_timer_listq->p_last;
783       }
784 
785       p_tle->p_next = NULL;
786       p_timer_listq->p_last = p_tle;
787       nr_ticks_total = p_tle->ticks;
788       p_tle->ticks -= p_timer_listq->last_ticks;
789 
790       p_timer_listq->last_ticks = nr_ticks_total;
791     } else /* This entry needs to be inserted before the last entry */
792     {
793       /* Find the entry that the new one needs to be inserted in front of */
794       p_temp = p_timer_listq->p_first;
795       while (p_tle->ticks > p_temp->ticks) {
796         /* Update the tick value if looking at an unexpired entry */
797         if (p_temp->ticks > 0) p_tle->ticks -= p_temp->ticks;
798 
799         p_temp = p_temp->p_next;
800       }
801 
802       /* The new entry is the first in the list */
803       if (p_temp == p_timer_listq->p_first) {
804         p_tle->p_next = p_timer_listq->p_first;
805         p_timer_listq->p_first->p_prev = p_tle;
806         p_timer_listq->p_first = p_tle;
807       } else {
808         p_temp->p_prev->p_next = p_tle;
809         p_tle->p_prev = p_temp->p_prev;
810         p_temp->p_prev = p_tle;
811         p_tle->p_next = p_temp;
812       }
813       p_temp->ticks -= p_tle->ticks;
814     }
815 
816     p_tle->in_use = true;
817 
818     /* if we already add this timer queue to the array */
819     for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
820       if (gki_cb.com.timer_queues[tt] == p_timer_listq) return;
821     }
822     /* add this timer queue to the array */
823     for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
824       if (gki_cb.com.timer_queues[tt] == NULL) break;
825     }
826     if (tt < GKI_MAX_TIMER_QUEUES) {
827       gki_cb.com.timer_queues[tt] = p_timer_listq;
828     }
829   }
830 
831   return;
832 }
833 
834 /*******************************************************************************
835 **
836 ** Function         GKI_remove_from_timer_list
837 **
838 ** Description      This function is called by an application to remove a timer
839 **                  entry from a timer list.
840 **
841 ** Parameters       p_timer_listq   - (input) pointer to the timer list queue
842 *object
843 **                  p_tle           - (input) pointer to a timer list queue
844 *entry
845 **
846 ** Returns          void
847 **
848 *******************************************************************************/
GKI_remove_from_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)849 void GKI_remove_from_timer_list(TIMER_LIST_Q* p_timer_listq,
850                                 TIMER_LIST_ENT* p_tle) {
851   uint8_t tt;
852 
853   /* Verify that the entry is valid */
854   if (p_tle == NULL || p_tle->in_use == false ||
855       p_timer_listq->p_first == NULL) {
856     return;
857   }
858 
859   /* Add the ticks remaining in this timer (if any) to the next guy in the list.
860   ** Note: Expired timers have a tick value of '0'.
861   */
862   if (p_tle->p_next != NULL) {
863     p_tle->p_next->ticks += p_tle->ticks;
864   } else {
865     p_timer_listq->last_ticks -= p_tle->ticks;
866   }
867 
868   /* Unlink timer from the list.
869   */
870   if (p_timer_listq->p_first == p_tle) {
871     p_timer_listq->p_first = p_tle->p_next;
872 
873     if (p_timer_listq->p_first != NULL) p_timer_listq->p_first->p_prev = NULL;
874 
875     if (p_timer_listq->p_last == p_tle) p_timer_listq->p_last = NULL;
876   } else {
877     if (p_timer_listq->p_last == p_tle) {
878       p_timer_listq->p_last = p_tle->p_prev;
879 
880       if (p_timer_listq->p_last != NULL) p_timer_listq->p_last->p_next = NULL;
881     } else {
882       if (p_tle->p_next != NULL && p_tle->p_next->p_prev == p_tle)
883         p_tle->p_next->p_prev = p_tle->p_prev;
884       else {
885         /* Error case - chain messed up ?? */
886         return;
887       }
888 
889       if (p_tle->p_prev != NULL && p_tle->p_prev->p_next == p_tle)
890         p_tle->p_prev->p_next = p_tle->p_next;
891       else {
892         /* Error case - chain messed up ?? */
893         return;
894       }
895     }
896   }
897 
898   p_tle->p_next = p_tle->p_prev = NULL;
899   p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
900   p_tle->in_use = false;
901 
902   /* if timer queue is empty */
903   if (p_timer_listq->p_first == NULL && p_timer_listq->p_last == NULL) {
904     for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
905       if (gki_cb.com.timer_queues[tt] == p_timer_listq) {
906         gki_cb.com.timer_queues[tt] = NULL;
907         break;
908       }
909     }
910   }
911 
912   return;
913 }
914 
915 /*******************************************************************************
916 **
917 ** Function         gki_adjust_timer_count
918 **
919 ** Description      This function is called whenever a new timer or GKI_wait
920 *occurs
921 **                  to adjust (if necessary) the current time til the first
922 *expiration.
923 **                  This only needs to make an adjustment if the new timer (in
924 *ticks) is
925 **                  less than the number of ticks remaining on the current
926 *timer.
927 **
928 ** Parameters:      ticks - (input) number of system ticks of the new timer
929 *entry
930 **
931 **                  NOTE:  This routine MUST be called while interrupts are
932 *disabled to
933 **                          avoid updates while adjusting the timer variables.
934 **
935 ** Returns          void
936 **
937 *******************************************************************************/
gki_adjust_timer_count(int32_t ticks)938 void gki_adjust_timer_count(int32_t ticks) {
939   if (ticks > 0) {
940     /* See if the new timer expires before the current first expiration */
941     if (gki_cb.com.OSNumOrigTicks == 0 ||
942         (ticks < gki_cb.com.OSTicksTilExp && gki_cb.com.OSTicksTilExp > 0)) {
943       gki_cb.com.OSNumOrigTicks =
944           (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) + ticks;
945       gki_cb.com.OSTicksTilExp = ticks;
946     }
947   }
948 
949   return;
950 }
951