headers: remove sched.h from interrupt.h
[safe/jmp/linux-2.6] / drivers / isdn / hisax / arcofi.c
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  
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         u_char val;
34         
35         add_arcofi_timer(cs);
36         cs->dc.isac.mon_txp = 0;
37         cs->dc.isac.mon_txc = cs->dc.isac.arcofi_list->len;
38         memcpy(cs->dc.isac.mon_tx, cs->dc.isac.arcofi_list->msg, cs->dc.isac.mon_txc);
39         switch(cs->dc.isac.arcofi_bc) {
40                 case 0: break;
41                 case 1: cs->dc.isac.mon_tx[1] |= 0x40;
42                         break;
43                 default: break;
44         }
45         cs->dc.isac.mocr &= 0x0f;
46         cs->dc.isac.mocr |= 0xa0;
47         cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
48         val = cs->readisac(cs, ISAC_MOSR);
49         cs->writeisac(cs, ISAC_MOX1, cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]);
50         cs->dc.isac.mocr |= 0x10;
51         cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
52 }
53
54 int
55 arcofi_fsm(struct IsdnCardState *cs, int event, void *data) {
56         if (cs->debug & L1_DEB_MONITOR) {
57                 debugl1(cs, "arcofi state %d event %d", cs->dc.isac.arcofi_state, event);
58         }
59         if (event == ARCOFI_TIMEOUT) {
60                 cs->dc.isac.arcofi_state = ARCOFI_NOP;
61                 test_and_set_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags);
62                 wake_up(&cs->dc.isac.arcofi_wait);
63                 return(1);
64         }
65         switch (cs->dc.isac.arcofi_state) {
66                 case ARCOFI_NOP:
67                         if (event == ARCOFI_START) {
68                                 cs->dc.isac.arcofi_list = data;
69                                 cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT;
70                                 send_arcofi(cs);
71                         }
72                         break;
73                 case ARCOFI_TRANSMIT:
74                         if (event == ARCOFI_TX_END) {
75                                 if (cs->dc.isac.arcofi_list->receive) {
76                                         add_arcofi_timer(cs);
77                                         cs->dc.isac.arcofi_state = ARCOFI_RECEIVE;
78                                 } else {
79                                         if (cs->dc.isac.arcofi_list->next) {
80                                                 cs->dc.isac.arcofi_list =
81                                                         cs->dc.isac.arcofi_list->next;
82                                                 send_arcofi(cs);
83                                         } else {
84                                                 if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
85                                                         del_timer(&cs->dc.isac.arcofitimer);
86                                                 }
87                                                 cs->dc.isac.arcofi_state = ARCOFI_NOP;
88                                                 wake_up(&cs->dc.isac.arcofi_wait);
89                                         }
90                                 }
91                         }
92                         break;
93                 case ARCOFI_RECEIVE:
94                         if (event == ARCOFI_RX_END) {
95                                 if (cs->dc.isac.arcofi_list->next) {
96                                         cs->dc.isac.arcofi_list =
97                                                 cs->dc.isac.arcofi_list->next;
98                                         cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT;
99                                         send_arcofi(cs);
100                                 } else {
101                                         if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
102                                                 del_timer(&cs->dc.isac.arcofitimer);
103                                         }
104                                         cs->dc.isac.arcofi_state = ARCOFI_NOP;
105                                         wake_up(&cs->dc.isac.arcofi_wait);
106                                 }
107                         }
108                         break;
109                 default:
110                         debugl1(cs, "Arcofi unknown state %x", cs->dc.isac.arcofi_state);
111                         return(2);
112         }
113         return(0);
114 }
115
116 static void
117 arcofi_timer(struct IsdnCardState *cs) {
118         arcofi_fsm(cs, ARCOFI_TIMEOUT, NULL);
119 }
120
121 void
122 clear_arcofi(struct IsdnCardState *cs) {
123         if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
124                 del_timer(&cs->dc.isac.arcofitimer);
125         }
126 }
127
128 void
129 init_arcofi(struct IsdnCardState *cs) {
130         cs->dc.isac.arcofitimer.function = (void *) arcofi_timer;
131         cs->dc.isac.arcofitimer.data = (long) cs;
132         init_timer(&cs->dc.isac.arcofitimer);
133         init_waitqueue_head(&cs->dc.isac.arcofi_wait);
134         test_and_set_bit(HW_ARCOFI, &cs->HW_Flags);
135 }