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