summaryrefslogtreecommitdiff
path: root/wctdm.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-07-16 15:21:18 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-07-16 15:21:18 +0000
commitcea3faf77f6dddf415e7118b5aa8bc1e369b112f (patch)
tree8956a0156dfefb9b8327aaba56b0266797d0e6a4 /wctdm.c
parent4d464bb861ef5d8896cffea1004775882c14a306 (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-xwctdm.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/wctdm.c b/wctdm.c
index c54d9d3..8608f1d 100755
--- a/wctdm.c
+++ b/wctdm.c
@@ -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;
}