timer.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /* $Id: timer.c,v 1.3.6.1 2001/09/23 22:24:59 kai Exp $
  2. *
  3. * Copyright (C) 1996 SpellCaster Telecommunications Inc.
  4. *
  5. * This software may be used and distributed according to the terms
  6. * of the GNU General Public License, incorporated herein by reference.
  7. *
  8. * For more information, please contact gpl-info@spellcast.com or write:
  9. *
  10. * SpellCaster Telecommunications Inc.
  11. * 5621 Finch Avenue East, Unit #3
  12. * Scarborough, Ontario Canada
  13. * M1B 2T9
  14. * +1 (416) 297-8565
  15. * +1 (416) 297-6433 Facsimile
  16. */
  17. #include "includes.h"
  18. #include "hardware.h"
  19. #include "message.h"
  20. #include "card.h"
  21. /*
  22. * Write the proper values into the I/O ports following a reset
  23. */
  24. static void setup_ports(int card)
  25. {
  26. outb((sc_adapter[card]->rambase >> 12), sc_adapter[card]->ioport[EXP_BASE]);
  27. /* And the IRQ */
  28. outb((sc_adapter[card]->interrupt | 0x80),
  29. sc_adapter[card]->ioport[IRQ_SELECT]);
  30. }
  31. /*
  32. * Timed function to check the status of a previous reset
  33. * Must be very fast as this function runs in the context of
  34. * an interrupt handler.
  35. *
  36. * Setup the ioports for the board that were cleared by the reset.
  37. * Then, check to see if the signate has been set. Next, set the
  38. * signature to a known value and issue a startproc if needed.
  39. */
  40. void sc_check_reset(unsigned long data)
  41. {
  42. unsigned long flags;
  43. unsigned long sig;
  44. int card = (unsigned int) data;
  45. pr_debug("%s: check_timer timer called\n",
  46. sc_adapter[card]->devicename);
  47. /* Setup the io ports */
  48. setup_ports(card);
  49. spin_lock_irqsave(&sc_adapter[card]->lock, flags);
  50. outb(sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport],
  51. (sc_adapter[card]->shmem_magic >> 14) | 0x80);
  52. sig = (unsigned long) *((unsigned long *)(sc_adapter[card]->rambase + SIG_OFFSET));
  53. /* check the signature */
  54. if (sig == SIGNATURE) {
  55. flushreadfifo(card);
  56. spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
  57. /* See if we need to do a startproc */
  58. if (sc_adapter[card]->StartOnReset)
  59. startproc(card);
  60. } else {
  61. pr_debug("%s: No signature yet, waiting another %lu jiffies.\n",
  62. sc_adapter[card]->devicename, CHECKRESET_TIME);
  63. mod_timer(&sc_adapter[card]->reset_timer, jiffies + CHECKRESET_TIME);
  64. spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
  65. }
  66. }
  67. /*
  68. * Timed function to check the status of a previous reset
  69. * Must be very fast as this function runs in the context of
  70. * an interrupt handler.
  71. *
  72. * Send check sc_adapter->phystat to see if the channels are up
  73. * If they are, tell ISDN4Linux that the board is up. If not,
  74. * tell IADN4Linux that it is up. Always reset the timer to
  75. * fire again (endless loop).
  76. */
  77. void check_phystat(unsigned long data)
  78. {
  79. unsigned long flags;
  80. int card = (unsigned int) data;
  81. pr_debug("%s: Checking status...\n", sc_adapter[card]->devicename);
  82. /*
  83. * check the results of the last PhyStat and change only if
  84. * has changed drastically
  85. */
  86. if (sc_adapter[card]->nphystat && !sc_adapter[card]->phystat) { /* All is well */
  87. pr_debug("PhyStat transition to RUN\n");
  88. pr_info("%s: Switch contacted, transmitter enabled\n",
  89. sc_adapter[card]->devicename);
  90. indicate_status(card, ISDN_STAT_RUN, 0, NULL);
  91. }
  92. else if (!sc_adapter[card]->nphystat && sc_adapter[card]->phystat) { /* All is not well */
  93. pr_debug("PhyStat transition to STOP\n");
  94. pr_info("%s: Switch connection lost, transmitter disabled\n",
  95. sc_adapter[card]->devicename);
  96. indicate_status(card, ISDN_STAT_STOP, 0, NULL);
  97. }
  98. sc_adapter[card]->phystat = sc_adapter[card]->nphystat;
  99. /* Reinitialize the timer */
  100. spin_lock_irqsave(&sc_adapter[card]->lock, flags);
  101. mod_timer(&sc_adapter[card]->stat_timer, jiffies + CHECKSTAT_TIME);
  102. spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
  103. /* Send a new cePhyStatus message */
  104. sendmessage(card, CEPID, ceReqTypePhy, ceReqClass2,
  105. ceReqPhyStatus, 0, 0, NULL);
  106. }