diff options
author | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2003-07-16 15:21:18 +0000 |
---|---|---|
committer | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2003-07-16 15:21:18 +0000 |
commit | cea3faf77f6dddf415e7118b5aa8bc1e369b112f (patch) | |
tree | 8956a0156dfefb9b8327aaba56b0266797d0e6a4 /wctdm.c | |
parent | 4d464bb861ef5d8896cffea1004775882c14a306 (diff) |
Reset automatically after power alarms
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@214 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wctdm.c')
-rwxr-xr-x | wctdm.c | 37 |
1 files changed, 28 insertions, 9 deletions
@@ -136,6 +136,8 @@ static alpha indirect_regs[] = #define NUM_CARDS 4 +#define MAX_ALARMS 10 + struct wcfxs { struct pci_dev *dev; char *variety; @@ -159,7 +161,9 @@ struct wcfxs { int lastrxhook[NUM_CARDS]; int debounce[NUM_CARDS]; - int idletxhookstate; /* IDLE changing hook state */ + int idletxhookstate[NUM_CARDS]; /* IDLE changing hook state */ + int lasttxhook[NUM_CARDS]; + int palarms[NUM_CARDS]; unsigned long ioaddr; dma_addr_t readdma; dma_addr_t writedma; @@ -275,6 +279,12 @@ static void wcfxs_interrupt(int irq, void *dev_id, struct pt_regs *regs) if ((x < wc->cards) && (wc->cardflag & (1 << x))) { wcfxs_check_hook(wc, x); } + if (!(wc->intcount % 10000)) { + /* Accept an alarm once per 10 seconds */ + for (x=0;x<4;x++) + if (wc->palarms[x]) + wc->palarms[x]--; + } wcfxs_receiveprep(wc, ints); wcfxs_transmitprep(wc, ints); } @@ -670,7 +680,7 @@ static int wcfxs_init_proslic(struct wcfxs *wc, int card) int x; /* By default, always send on hook */ - wc->idletxhookstate = 2; + wc->idletxhookstate [card] = 2; /* Sanity check the ProSLIC */ if (wcfxs_proslic_insane(wc, card)) @@ -794,6 +804,16 @@ static inline void wcfxs_check_hook(struct wcfxs *wc, int card) /* For some reason we have to debounce the hook detector. */ + res = wcfxs_getreg(wc, card, 64); + if (!res && (res != wc->lasttxhook[card])) { + if (wc->palarms[card]++ < MAX_ALARMS) { + printk("Power alarm on module %d, resetting!\n", card + 1); + wcfxs_setreg(wc, card, 64, wc->lasttxhook[card]); + } else { + if (wc->palarms[card] == MAX_ALARMS) + printk("Too many power alarms on card %d, NOT resetting!\n", card + 1); + } + } res = wcfxs_getreg(wc, card, 68); hook = (res & 1); if (hook != wc->lastrxhook[card]) { @@ -915,27 +935,26 @@ static int wcfxs_hooksig(struct zt_chan *chan, zt_txsig_t txsig) { struct wcfxs *wc = chan->pvt; int reg=0; - unsigned char txhook = 0; switch(txsig) { case ZT_TXSIG_ONHOOK: switch(chan->sig) { case ZT_SIG_FXOKS: case ZT_SIG_FXOLS: - txhook = wc->idletxhookstate; + wc->lasttxhook[chan->chanpos-1] = wc->idletxhookstate[chan->chanpos-1]; break; case ZT_SIG_FXOGS: - txhook = 3; + wc->lasttxhook[chan->chanpos-1] = 3; break; } break; case ZT_TXSIG_OFFHOOK: - txhook = wc->idletxhookstate; + wc->lasttxhook[chan->chanpos-1] = wc->idletxhookstate[chan->chanpos-1]; break; case ZT_TXSIG_START: - txhook = 4; + wc->lasttxhook[chan->chanpos-1] = 4; break; case ZT_TXSIG_KEWL: - txhook = 0; + wc->lasttxhook[chan->chanpos-1] = 0; break; default: printk("wcfxs: Can't set tx state to %d\n", txsig); @@ -944,7 +963,7 @@ static int wcfxs_hooksig(struct zt_chan *chan, zt_txsig_t txsig) printk("Setting hook state to %d (%02x)\n", txsig, reg); #if 1 - wcfxs_setreg(wc, chan->chanpos - 1, 64, txhook); + wcfxs_setreg(wc, chan->chanpos - 1, 64, wc->lasttxhook[chan->chanpos-1]); #endif return 0; } |