Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/isdn/hisax/arcofi.c
15115 views
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) {
116
arcofi_fsm(cs, ARCOFI_TIMEOUT, NULL);
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
}
134
135