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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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