RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / isdn / hisax / arcofi.c
blob57c5e5da35ac08b055405a1c349b691c8d9c3563
1 /* $Id: arcofi.c,v 1.14.2.3 2004/01/13 14:31:24 Exp $
3 * Ansteuerung ARCOFI 2165
5 * Author Karsten Keil
6 * Copyright by Karsten Keil <keil@isdn4linux.de>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
13 #include <linux/sched.h>
14 #include "hisax.h"
15 #include "isdnl1.h"
16 #include "isac.h"
17 #include "arcofi.h"
19 #define ARCOFI_TIMER_VALUE 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);
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);
31 static void
32 send_arcofi(struct IsdnCardState *cs) {
33 u_char val;
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;
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);
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);
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);
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);
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);
87 cs->dc.isac.arcofi_state = ARCOFI_NOP;
88 wake_up(&cs->dc.isac.arcofi_wait);
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);
104 cs->dc.isac.arcofi_state = ARCOFI_NOP;
105 wake_up(&cs->dc.isac.arcofi_wait);
108 break;
109 default:
110 debugl1(cs, "Arcofi unknown state %x", cs->dc.isac.arcofi_state);
111 return(2);
113 return(0);
116 static void
117 arcofi_timer(struct IsdnCardState *cs) {
118 arcofi_fsm(cs, ARCOFI_TIMEOUT, NULL);
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);
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);