timer.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. extern board *sc_adapter[];
  22. extern void flushreadfifo(int);
  23. extern int startproc(int);
  24. extern int indicate_status(int, int, unsigned long, char *);
  25. extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
  26. unsigned int, unsigned int, unsigned int, unsigned int *);
  27. /*
  28. * Write the proper values into the I/O ports following a reset
  29. */
  30. static void setup_ports(int card)
  31. {
  32. outb((sc_adapter[card]->rambase >> 12), sc_adapter[card]->ioport[EXP_BASE]);
  33. /* And the IRQ */
  34. outb((sc_adapter[card]->interrupt | 0x80),
  35. sc_adapter[card]->ioport[IRQ_SELECT]);
  36. }
  37. /*
  38. * Timed function to check the status of a previous reset
  39. * Must be very fast as this function runs in the context of
  40. * an interrupt handler.
  41. *
  42. * Setup the ioports for the board that were cleared by the reset.
  43. * Then, check to see if the signate has been set. Next, set the
  44. * signature to a known value and issue a startproc if needed.
  45. */
  46. void check_reset(unsigned long data)
  47. {
  48. unsigned long flags;
  49. unsigned long sig;
  50. int card = (unsigned int) data;
  51. pr_debug("%s: check_timer timer called\n",
  52. sc_adapter[card]->devicename);
  53. /* Setup the io ports */
  54. setup_ports(card);
  55. spin_lock_irqsave(&sc_adapter[card]->lock, flags);
  56. outb(sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport],
  57. (sc_adapter[card]->shmem_magic>>14) | 0x80);
  58. sig = (unsigned long) *((unsigned long *)(sc_adapter[card]->rambase + SIG_OFFSET));
  59. /* check the signature */
  60. if(sig == SIGNATURE) {
  61. flushreadfifo(card);
  62. spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
  63. /* See if we need to do a startproc */
  64. if (sc_adapter[card]->StartOnReset)
  65. startproc(card);
  66. } else {
  67. pr_debug("%s: No signature yet, waiting another %d jiffies.\n",
  68. sc_adapter[card]->devicename, CHECKRESET_TIME);
  69. mod_timer(&sc_adapter[card]->reset_timer, jiffies+CHECKRESET_TIME);
  70. spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
  71. }
  72. }
  73. /*
  74. * Timed function to check the status of a previous reset
  75. * Must be very fast as this function runs in the context of
  76. * an interrupt handler.
  77. *
  78. * Send check sc_adapter->phystat to see if the channels are up
  79. * If they are, tell ISDN4Linux that the board is up. If not,
  80. * tell IADN4Linux that it is up. Always reset the timer to
  81. * fire again (endless loop).
  82. */
  83. void check_phystat(unsigned long data)
  84. {
  85. unsigned long flags;
  86. int card = (unsigned int) data;
  87. pr_debug("%s: Checking status...\n", sc_adapter[card]->devicename);
  88. /*
  89. * check the results of the last PhyStat and change only if
  90. * has changed drastically
  91. */
  92. if (sc_adapter[card]->nphystat && !sc_adapter[card]->phystat) { /* All is well */
  93. pr_debug("PhyStat transition to RUN\n");
  94. pr_info("%s: Switch contacted, transmitter enabled\n",
  95. sc_adapter[card]->devicename);
  96. indicate_status(card, ISDN_STAT_RUN, 0, NULL);
  97. }
  98. else if (!sc_adapter[card]->nphystat && sc_adapter[card]->phystat) { /* All is not well */
  99. pr_debug("PhyStat transition to STOP\n");
  100. pr_info("%s: Switch connection lost, transmitter disabled\n",
  101. sc_adapter[card]->devicename);
  102. indicate_status(card, ISDN_STAT_STOP, 0, NULL);
  103. }
  104. sc_adapter[card]->phystat = sc_adapter[card]->nphystat;
  105. /* Reinitialize the timer */
  106. spin_lock_irqsave(&sc_adapter[card]->lock, flags);
  107. mod_timer(&sc_adapter[card]->stat_timer, jiffies+CHECKSTAT_TIME);
  108. spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
  109. /* Send a new cePhyStatus message */
  110. sendmessage(card, CEPID,ceReqTypePhy,ceReqClass2,
  111. ceReqPhyStatus,0,0,NULL);
  112. }