arcofi.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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