arcofi.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /* $Id: arcofi.c,v 1.14.2.3 2004/01/13 14:31:24 keil Exp $
  2. *
  3. * Ansteuerung ARCOFI 2165
  4. *
  5. * Author Karsten Keil
  6. * Copyright by Karsten Keil <keil@isdn4linux.de>
  7. *
  8. * This software may be used and distributed according to the terms
  9. * of the GNU General Public License, incorporated herein by reference.
  10. *
  11. */
  12. #include <linux/sched.h>
  13. #include "hisax.h"
  14. #include "isdnl1.h"
  15. #include "isac.h"
  16. #include "arcofi.h"
  17. #define ARCOFI_TIMER_VALUE 20
  18. static void
  19. add_arcofi_timer(struct IsdnCardState *cs) {
  20. if (test_and_set_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
  21. del_timer(&cs->dc.isac.arcofitimer);
  22. }
  23. init_timer(&cs->dc.isac.arcofitimer);
  24. cs->dc.isac.arcofitimer.expires = jiffies + ((ARCOFI_TIMER_VALUE * HZ)/1000);
  25. add_timer(&cs->dc.isac.arcofitimer);
  26. }
  27. static void
  28. send_arcofi(struct IsdnCardState *cs) {
  29. u_char val;
  30. add_arcofi_timer(cs);
  31. cs->dc.isac.mon_txp = 0;
  32. cs->dc.isac.mon_txc = cs->dc.isac.arcofi_list->len;
  33. memcpy(cs->dc.isac.mon_tx, cs->dc.isac.arcofi_list->msg, cs->dc.isac.mon_txc);
  34. switch(cs->dc.isac.arcofi_bc) {
  35. case 0: break;
  36. case 1: cs->dc.isac.mon_tx[1] |= 0x40;
  37. break;
  38. default: break;
  39. }
  40. cs->dc.isac.mocr &= 0x0f;
  41. cs->dc.isac.mocr |= 0xa0;
  42. cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
  43. val = cs->readisac(cs, ISAC_MOSR);
  44. cs->writeisac(cs, ISAC_MOX1, cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]);
  45. cs->dc.isac.mocr |= 0x10;
  46. cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
  47. }
  48. int
  49. arcofi_fsm(struct IsdnCardState *cs, int event, void *data) {
  50. if (cs->debug & L1_DEB_MONITOR) {
  51. debugl1(cs, "arcofi state %d event %d", cs->dc.isac.arcofi_state, event);
  52. }
  53. if (event == ARCOFI_TIMEOUT) {
  54. cs->dc.isac.arcofi_state = ARCOFI_NOP;
  55. test_and_set_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags);
  56. wake_up(&cs->dc.isac.arcofi_wait);
  57. return(1);
  58. }
  59. switch (cs->dc.isac.arcofi_state) {
  60. case ARCOFI_NOP:
  61. if (event == ARCOFI_START) {
  62. cs->dc.isac.arcofi_list = data;
  63. cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT;
  64. send_arcofi(cs);
  65. }
  66. break;
  67. case ARCOFI_TRANSMIT:
  68. if (event == ARCOFI_TX_END) {
  69. if (cs->dc.isac.arcofi_list->receive) {
  70. add_arcofi_timer(cs);
  71. cs->dc.isac.arcofi_state = ARCOFI_RECEIVE;
  72. } else {
  73. if (cs->dc.isac.arcofi_list->next) {
  74. cs->dc.isac.arcofi_list =
  75. cs->dc.isac.arcofi_list->next;
  76. send_arcofi(cs);
  77. } else {
  78. if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
  79. del_timer(&cs->dc.isac.arcofitimer);
  80. }
  81. cs->dc.isac.arcofi_state = ARCOFI_NOP;
  82. wake_up(&cs->dc.isac.arcofi_wait);
  83. }
  84. }
  85. }
  86. break;
  87. case ARCOFI_RECEIVE:
  88. if (event == ARCOFI_RX_END) {
  89. if (cs->dc.isac.arcofi_list->next) {
  90. cs->dc.isac.arcofi_list =
  91. cs->dc.isac.arcofi_list->next;
  92. cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT;
  93. send_arcofi(cs);
  94. } else {
  95. if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
  96. del_timer(&cs->dc.isac.arcofitimer);
  97. }
  98. cs->dc.isac.arcofi_state = ARCOFI_NOP;
  99. wake_up(&cs->dc.isac.arcofi_wait);
  100. }
  101. }
  102. break;
  103. default:
  104. debugl1(cs, "Arcofi unknown state %x", cs->dc.isac.arcofi_state);
  105. return(2);
  106. }
  107. return(0);
  108. }
  109. static void
  110. arcofi_timer(struct IsdnCardState *cs) {
  111. arcofi_fsm(cs, ARCOFI_TIMEOUT, NULL);
  112. }
  113. void
  114. clear_arcofi(struct IsdnCardState *cs) {
  115. if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
  116. del_timer(&cs->dc.isac.arcofitimer);
  117. }
  118. }
  119. void
  120. init_arcofi(struct IsdnCardState *cs) {
  121. cs->dc.isac.arcofitimer.function = (void *) arcofi_timer;
  122. cs->dc.isac.arcofitimer.data = (long) cs;
  123. init_timer(&cs->dc.isac.arcofitimer);
  124. init_waitqueue_head(&cs->dc.isac.arcofi_wait);
  125. test_and_set_bit(HW_ARCOFI, &cs->HW_Flags);
  126. }