diff options
author | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2003-09-17 16:26:48 +0000 |
---|---|---|
committer | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2003-09-17 16:26:48 +0000 |
commit | 2aff1ceedf24d5ddf41e55569dee4056e9d6a248 (patch) | |
tree | 9f52aed295df98f5eee17faae8e9c5c36f873f32 /wctdm.c | |
parent | 0197f3e452d7599b80b2cc24dad1af7e2a3c72cd (diff) |
Auto reset if loopback is detected
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@243 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wctdm.c')
-rwxr-xr-x | wctdm.c | 75 |
1 files changed, 45 insertions, 30 deletions
@@ -1,5 +1,5 @@ /* - * Wilcard S100P FXS Interface Driver for Zapata Telephony interface + * Wilcard TDM400P FXS Interface Driver for Zapata Telephony interface * * Written by Mark Spencer <markster@linux-support.net> * Matthew Fredrickson <creslin@linux-support.net> @@ -187,6 +187,8 @@ static void wcfxs_release(struct wcfxs *wc); static int debug = 0; +static int wcfxs_init_proslic(struct wcfxs *wc, int card, int fast); + static inline void wcfxs_transmitprep(struct wcfxs *wc, unsigned char ints) { volatile unsigned int *writechunk; @@ -282,7 +284,7 @@ static void wcfxs_interrupt(int irq, void *dev_id, struct pt_regs *regs) } if (!(wc->intcount % 10000)) { /* Accept an alarm once per 10 seconds */ - for (x=0;x<4;x++) + for (x=0;x<4;x++) if (wc->palarms[x]) wc->palarms[x]--; } @@ -586,7 +588,7 @@ static int wcfxs_powerleak_test(struct wcfxs *wc, int card) return 0; } -static int wcfxs_powerup_proslic(struct wcfxs *wc, int card) +static int wcfxs_powerup_proslic(struct wcfxs *wc, int card, int fast) { unsigned char vbat; unsigned long origjiffies; @@ -603,6 +605,10 @@ static int wcfxs_powerup_proslic(struct wcfxs *wc, int card) /* Disable powerdown */ wcfxs_setreg(wc, card, 14, 0); + /* If fast, don't bother checking anymore */ + if (fast) + return 0; + while((vbat = wcfxs_getreg(wc, card, 82)) < 0xc0) { /* Wait no more than 500ms */ if ((jiffies - origjiffies) > HZ/2) { @@ -748,7 +754,7 @@ static int wcfxs_calibrate(struct wcfxs *wc, int card) return 0; } #endif -static int wcfxs_init_proslic(struct wcfxs *wc, int card) +static int wcfxs_init_proslic(struct wcfxs *wc, int card, int fast) { unsigned short tmp[5]; @@ -790,29 +796,31 @@ static int wcfxs_init_proslic(struct wcfxs *wc, int card) } /* Power up the DC-DC converter */ - if (wcfxs_powerup_proslic(wc, card)) { + if (wcfxs_powerup_proslic(wc, card, fast)) { printk("Unable to do INITIAL ProSLIC powerup on module %d\n", card); return -1; } - /* Check for power leaks */ - if (wcfxs_powerleak_test(wc, card)) { - printk("ProSLIC module %d failed leakage test. Check for short circuit\n", card); - } + if (!fast) { - /* Power up again */ - if (wcfxs_powerup_proslic(wc, card)) { - printk("Unable to do FINAL ProSLIC powerup on module %d\n", card); - return -1; - } + /* Check for power leaks */ + if (wcfxs_powerleak_test(wc, card)) { + printk("ProSLIC module %d failed leakage test. Check for short circuit\n", card); + } + /* Power up again */ + if (wcfxs_powerup_proslic(wc, card, fast)) { + printk("Unable to do FINAL ProSLIC powerup on module %d\n", card); + return -1; + } #ifndef NO_CALIBRATION - /* Perform calibration */ - if (wcfxs_manual_calibrate(wc, card)) { - printk("ProSlic died on Calibration (try -DNO_CALIBRATION in Makefile).\n"); - return -1; - } + /* Perform calibration */ + if (wcfxs_manual_calibrate(wc, card)) { + printk("ProSlic died on Calibration (try -DNO_CALIBRATION in Makefile).\n"); + return -1; + } #endif + } /* Calibration complete, restore original values */ for (x=0;x<5;x++) { wcfxs_setreg_indirect(wc, card, x + 35, tmp[x]); @@ -879,16 +887,23 @@ 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); - if (wc->lasttxhook[card] == 4) - wc->lasttxhook[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); + /* Check loopback */ + res = wcfxs_getreg(wc, card, 8); + if (res) { + printk("Ouch, part reset, quickly restoring reality (%d)\n", card); + wcfxs_init_proslic(wc, card, 1); + } else { + 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); + if (wc->lasttxhook[card] == 4) + wc->lasttxhook[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); @@ -1162,7 +1177,7 @@ static int wcfxs_hardware_init(struct wcfxs *wc) while(jiffies - oldjiffies < (HZ / 4) + 1); for (x=0;x<wc->cards;x++) { - if (!wcfxs_init_proslic(wc, x)) { + if (!wcfxs_init_proslic(wc, x, 0)) { printk("Module %d: Initialized\n", x); wc->cardflag |= (1 << x); } else |