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