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