Blame view
drivers/isdn/hisax/arcofi.c
3.59 KB
1da177e4c
|
1 2 3 4 5 6 7 8 9 10 11 12 |
/* $Id: arcofi.c,v 1.14.2.3 2004/01/13 14:31:24 keil Exp $ * * Ansteuerung ARCOFI 2165 * * Author Karsten Keil * Copyright by Karsten Keil <keil@isdn4linux.de> * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * */ |
d43c36dc6
|
13 |
#include <linux/sched.h> |
1da177e4c
|
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#include "hisax.h" #include "isdnl1.h" #include "isac.h" #include "arcofi.h" #define ARCOFI_TIMER_VALUE 20 static void add_arcofi_timer(struct IsdnCardState *cs) { if (test_and_set_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) { del_timer(&cs->dc.isac.arcofitimer); } init_timer(&cs->dc.isac.arcofitimer); cs->dc.isac.arcofitimer.expires = jiffies + ((ARCOFI_TIMER_VALUE * HZ)/1000); add_timer(&cs->dc.isac.arcofitimer); } static void send_arcofi(struct IsdnCardState *cs) { |
1da177e4c
|
33 34 35 36 37 38 39 40 41 42 43 44 45 |
add_arcofi_timer(cs); cs->dc.isac.mon_txp = 0; cs->dc.isac.mon_txc = cs->dc.isac.arcofi_list->len; memcpy(cs->dc.isac.mon_tx, cs->dc.isac.arcofi_list->msg, cs->dc.isac.mon_txc); switch(cs->dc.isac.arcofi_bc) { case 0: break; case 1: cs->dc.isac.mon_tx[1] |= 0x40; break; default: break; } cs->dc.isac.mocr &= 0x0f; cs->dc.isac.mocr |= 0xa0; cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); |
011bc1ef4
|
46 |
(void) cs->readisac(cs, ISAC_MOSR); |
1da177e4c
|
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
cs->writeisac(cs, ISAC_MOX1, cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]); cs->dc.isac.mocr |= 0x10; cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); } int arcofi_fsm(struct IsdnCardState *cs, int event, void *data) { if (cs->debug & L1_DEB_MONITOR) { debugl1(cs, "arcofi state %d event %d", cs->dc.isac.arcofi_state, event); } if (event == ARCOFI_TIMEOUT) { cs->dc.isac.arcofi_state = ARCOFI_NOP; test_and_set_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags); wake_up(&cs->dc.isac.arcofi_wait); return(1); } switch (cs->dc.isac.arcofi_state) { case ARCOFI_NOP: if (event == ARCOFI_START) { cs->dc.isac.arcofi_list = data; cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT; send_arcofi(cs); } break; case ARCOFI_TRANSMIT: if (event == ARCOFI_TX_END) { if (cs->dc.isac.arcofi_list->receive) { add_arcofi_timer(cs); cs->dc.isac.arcofi_state = ARCOFI_RECEIVE; } else { if (cs->dc.isac.arcofi_list->next) { cs->dc.isac.arcofi_list = cs->dc.isac.arcofi_list->next; send_arcofi(cs); } else { if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) { del_timer(&cs->dc.isac.arcofitimer); } cs->dc.isac.arcofi_state = ARCOFI_NOP; wake_up(&cs->dc.isac.arcofi_wait); } } } break; case ARCOFI_RECEIVE: if (event == ARCOFI_RX_END) { if (cs->dc.isac.arcofi_list->next) { cs->dc.isac.arcofi_list = cs->dc.isac.arcofi_list->next; cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT; send_arcofi(cs); } else { if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) { del_timer(&cs->dc.isac.arcofitimer); } cs->dc.isac.arcofi_state = ARCOFI_NOP; wake_up(&cs->dc.isac.arcofi_wait); } } break; default: debugl1(cs, "Arcofi unknown state %x", cs->dc.isac.arcofi_state); return(2); } return(0); } static void arcofi_timer(struct IsdnCardState *cs) { arcofi_fsm(cs, ARCOFI_TIMEOUT, NULL); } void clear_arcofi(struct IsdnCardState *cs) { if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) { del_timer(&cs->dc.isac.arcofitimer); } } void init_arcofi(struct IsdnCardState *cs) { cs->dc.isac.arcofitimer.function = (void *) arcofi_timer; cs->dc.isac.arcofitimer.data = (long) cs; init_timer(&cs->dc.isac.arcofitimer); init_waitqueue_head(&cs->dc.isac.arcofi_wait); test_and_set_bit(HW_ARCOFI, &cs->HW_Flags); } |