summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-09-26 20:11:36 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-09-26 20:11:36 +0000
commit8080751796851bae724ce85b5525ae47b6245be7 (patch)
tree33137d049ad4c39ca45a562300614165ca16f688
parent168430325c517708cb791efb6e8656d31265c3f6 (diff)
Fix issue with CPU spiking
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@777 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-xwctdm.c90
1 files changed, 58 insertions, 32 deletions
diff --git a/wctdm.c b/wctdm.c
index 7dcb9f7..6e35189 100755
--- a/wctdm.c
+++ b/wctdm.c
@@ -255,9 +255,9 @@ static struct fxo_mode {
(the interrupt cycles around the four modules), so the periods are
specified in _4 millisecond_ increments
*/
-#define RING_DEBOUNCE 16 /* Ringer Debounce (64 ms) */
-#define DEFAULT_BATT_DEBOUNCE 16 /* Battery debounce (64 ms) */
-#define POLARITY_DEBOUNCE 16 /* Polarity debounce (64 ms) */
+#define RING_DEBOUNCE 4 /* Ringer Debounce (64 ms) */
+#define DEFAULT_BATT_DEBOUNCE 4 /* Battery debounce (64 ms) */
+#define POLARITY_DEBOUNCE 4 /* Polarity debounce (64 ms) */
#define DEFAULT_BATT_THRESH 3 /* Anything under this is "no battery" */
#define OHT_TIMER 6000 /* How long after RING to retain OHT */
@@ -338,6 +338,8 @@ struct wctdm {
/* Receive hook state and debouncing */
int modtype[NUM_CARDS];
+ unsigned char reg0shadow[NUM_CARDS];
+ unsigned char reg1shadow[NUM_CARDS];
unsigned long ioaddr;
dma_addr_t readdma;
@@ -803,13 +805,13 @@ static inline void wctdm_proslic_recheck_sanity(struct wctdm *wc, int card)
{
int res;
/* Check loopback */
- res = wctdm_getreg(wc, card, 8);
- if (res) {
- printk("Ouch, part reset, quickly restoring reality (%d)\n", card);
- wctdm_init_proslic(wc, card, 1, 0, 1);
- } else {
- res = wctdm_getreg(wc, card, 64);
- if (!res && (res != wc->mod[card].fxs.lasttxhook)) {
+ res = wc->reg1shadow[card];
+ if (!res && (res != wc->mod[card].fxs.lasttxhook)) {
+ res = wctdm_getreg(wc, card, 8);
+ if (res) {
+ printk("Ouch, part reset, quickly restoring reality (%d)\n", card);
+ wctdm_init_proslic(wc, card, 1, 0, 1);
+ } else {
if (wc->mod[card].fxs.palarms++ < MAX_ALARMS) {
printk("Power alarm on module %d, resetting!\n", card + 1);
if (wc->mod[card].fxs.lasttxhook == 4)
@@ -831,7 +833,7 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
signed char b;
int poopy = 0;
/* Try to track issues that plague slot one FXO's */
- b = wctdm_getreg(wc, card, 5);
+ b = wc->reg0shadow[card];
if ((b & 0x2) || !(b & 0x8)) {
/* Not good -- don't look at anything else */
if (debug)
@@ -850,9 +852,9 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
return;
#ifndef AUDIO_RINGCHECK
if (!wc->mod[card].fxo.offhook) {
- res = wctdm_getreg(wc, card, 5);
+ res = wc->reg0shadow[card];
if ((res & 0x60) && wc->mod[card].fxo.battery) {
- wc->mod[card].fxo.ringdebounce += (ZT_CHUNKSIZE * 4);
+ wc->mod[card].fxo.ringdebounce += (ZT_CHUNKSIZE * 16);
if (wc->mod[card].fxo.ringdebounce >= ZT_CHUNKSIZE * 64) {
if (!wc->mod[card].fxo.wasringing) {
wc->mod[card].fxo.wasringing = 1;
@@ -863,10 +865,10 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
wc->mod[card].fxo.ringdebounce = ZT_CHUNKSIZE * 64;
}
} else {
- wc->mod[card].fxo.ringdebounce -= ZT_CHUNKSIZE;
+ wc->mod[card].fxo.ringdebounce -= ZT_CHUNKSIZE * 4;
if (wc->mod[card].fxo.ringdebounce <= 0) {
if (wc->mod[card].fxo.wasringing) {
- wc->mod[card].fxo.wasringing =0;
+ wc->mod[card].fxo.wasringing = 0;
zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);
if (debug)
printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1);
@@ -877,7 +879,7 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
}
}
#endif
- b = wctdm_getreg(wc, card, 29);
+ b = wc->reg1shadow[card];
#if 0
{
static int count = 0;
@@ -955,13 +957,13 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
wc->mod[card].fxo.polaritydebounce--;
if (wc->mod[card].fxo.polaritydebounce < 1) {
if (wc->mod[card].fxo.lastpol != wc->mod[card].fxo.polarity) {
- if (debug)
- printk("%lu Polarity reversed (%d -> %d)\n", jiffies,
- wc->mod[card].fxo.polarity,
- wc->mod[card].fxo.lastpol);
- if (wc->mod[card].fxo.polarity)
- zt_qevent_lock(&wc->chans[card], ZT_EVENT_POLARITY);
- wc->mod[card].fxo.polarity = wc->mod[card].fxo.lastpol;
+ if (debug)
+ printk("%lu Polarity reversed (%d -> %d)\n", jiffies,
+ wc->mod[card].fxo.polarity,
+ wc->mod[card].fxo.lastpol);
+ if (wc->mod[card].fxo.polarity)
+ zt_qevent_lock(&wc->chans[card], ZT_EVENT_POLARITY);
+ wc->mod[card].fxo.polarity = wc->mod[card].fxo.lastpol;
}
}
}
@@ -975,7 +977,7 @@ static inline void wctdm_proslic_check_hook(struct wctdm *wc, int card)
/* For some reason we have to debounce the
hook detector. */
- res = wctdm_getreg(wc, card, 68);
+ res = wc->reg0shadow[card];
hook = (res & 1);
if (hook != wc->mod[card].fxs.lastrxhook) {
/* Reset the debounce (must be multiple of 4ms) */
@@ -985,7 +987,7 @@ static inline void wctdm_proslic_check_hook(struct wctdm *wc, int card)
#endif
} else {
if (wc->mod[card].fxs.debounce > 0) {
- wc->mod[card].fxs.debounce-= 4 * ZT_CHUNKSIZE;
+ wc->mod[card].fxs.debounce-= 16 * ZT_CHUNKSIZE;
#if 0
printk("Sustaining hook %d, %d\n", hook, wc->mod[card].fxs.debounce);
#endif
@@ -1029,6 +1031,7 @@ static void wctdm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
struct wctdm *wc = dev_id;
unsigned char ints;
int x;
+ int mode;
ints = inb(wc->ioaddr + WC_INTSTAT);
outb(ints, wc->ioaddr + WC_INTSTAT);
@@ -1094,14 +1097,37 @@ static void wctdm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (ints & 0x0f) {
wc->intcount++;
- x = wc->intcount % 4;
+ x = wc->intcount & 0x3;
+ mode = wc->intcount & 0xc;
if (wc->cardflag & (1 << x)) {
- if (wc->modtype[x] == MOD_TYPE_FXS) {
- wctdm_proslic_check_hook(wc, x);
- if (!(wc->intcount & 0xfc))
- wctdm_proslic_recheck_sanity(wc, x);
- } else if (wc->modtype[x] == MOD_TYPE_FXO) {
- wctdm_voicedaa_check_hook(wc, x);
+ switch(mode) {
+ case 0:
+ /* Rest */
+ break;
+ case 4:
+ /* Read first shadow reg */
+ if (wc->modtype[x] == MOD_TYPE_FXS)
+ wc->reg0shadow[x] = wctdm_getreg(wc, x, 68);
+ else if (wc->modtype[x] == MOD_TYPE_FXO)
+ wc->reg0shadow[x] = wctdm_getreg(wc, x, 5);
+ break;
+ case 8:
+ /* Read second shadow reg */
+ if (wc->modtype[x] == MOD_TYPE_FXS)
+ wc->reg1shadow[x] = wctdm_getreg(wc, x, 64);
+ else if (wc->modtype[x] == MOD_TYPE_FXO)
+ wc->reg1shadow[x] = wctdm_getreg(wc, x, 29);
+ break;
+ case 12:
+ /* Perform processing */
+ if (wc->modtype[x] == MOD_TYPE_FXS) {
+ wctdm_proslic_check_hook(wc, x);
+ if (!(wc->intcount & 0xf0))
+ wctdm_proslic_recheck_sanity(wc, x);
+ } else if (wc->modtype[x] == MOD_TYPE_FXO) {
+ wctdm_voicedaa_check_hook(wc, x);
+ }
+ break;
}
}
if (!(wc->intcount % 10000)) {