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