summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2011-03-19 18:26:51 -0500
committerShaun Ruffell <sruffell@digium.com>2011-04-15 14:19:02 -0500
commit9ccf86f865cf0b046e7d3476ac84b08b7bf7efbd (patch)
tree52d9779bff3f3e80daff7b3eaf8a8dce92da6838
parentd37c549827021232df2c8f3e90f75401eef54d9b (diff)
wctdm24xxp: oppending_ms shouldn't assume being checked at 1ms intervals.
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c24
-rw-r--r--drivers/dahdi/wctdm24xxp/wctdm24xxp.h2
2 files changed, 19 insertions, 7 deletions
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c
index 012b5b8..637cda2 100644
--- a/drivers/dahdi/wctdm24xxp/base.c
+++ b/drivers/dahdi/wctdm24xxp/base.c
@@ -1526,7 +1526,14 @@ wctdm_proslic_verify_indirect_regs(struct wctdm *wc, struct wctdm_module *mod)
return 0;
}
-/* 1ms interrupt */
+/**
+ * wctdm_proslic_check_oppending -
+ *
+ * Ensures that a write to the line feed register on the SLIC has been
+ * processed. If it hasn't after the timeout value, then it will resend the
+ * command and wait for another timeout period.
+ *
+ */
static void
wctdm_proslic_check_oppending(struct wctdm *wc, struct wctdm_module *const mod)
{
@@ -1546,7 +1553,6 @@ wctdm_proslic_check_oppending(struct wctdm *wc, struct wctdm_module *const mod)
if ((fxs->linefeed_control_shadow & SLIC_LF_SETMASK) ==
(fxs->lasttxhook & SLIC_LF_SETMASK)) {
fxs->lasttxhook &= SLIC_LF_SETMASK;
- fxs->oppending_ms = 0;
if (debug & DEBUG_CARD) {
dev_info(&wc->vb.pdev->dev,
"SLIC_LF OK: card=%d shadow=%02x "
@@ -1554,7 +1560,12 @@ wctdm_proslic_check_oppending(struct wctdm *wc, struct wctdm_module *const mod)
fxs->linefeed_control_shadow,
fxs->lasttxhook, wc->framecount);
}
- } else if (fxs->oppending_ms && (--fxs->oppending_ms == 0)) {
+ spin_unlock(&fxs->lasttxhooklock);
+ } else if (time_after(wc->framecount, fxs->oppending_timeout)) {
+ /* Check again in 100 ms */
+ fxs->oppending_timeout = wc->framecount + 100;
+ spin_unlock(&fxs->lasttxhooklock);
+
wctdm_setreg_intr(wc, mod, LINE_STATE, fxs->lasttxhook);
if (debug & DEBUG_CARD) {
dev_info(&wc->vb.pdev->dev,
@@ -1563,10 +1574,9 @@ wctdm_proslic_check_oppending(struct wctdm *wc, struct wctdm_module *const mod)
fxs->linefeed_control_shadow,
fxs->lasttxhook, wc->framecount);
}
- } else { /* Start 100ms Timeout */
- fxs->oppending_ms = 100;
+ } else {
+ spin_unlock(&fxs->lasttxhooklock);
}
- spin_unlock(&fxs->lasttxhooklock);
}
/* 256ms interrupt */
@@ -1635,6 +1645,7 @@ wctdm_proslic_recheck_sanity(struct wctdm *wc, struct wctdm_module *const mod)
}
fxs->lasttxhook |= SLIC_LF_OPPENDING;
mod->sethook = CMD_WR(LINE_STATE, fxs->lasttxhook);
+ fxs->oppending_timeout = wc->framecount + 100;
spin_unlock_irqrestore(&fxs->lasttxhooklock, flags);
/* Update shadow register to avoid extra power alarms
@@ -2065,6 +2076,7 @@ wctdm_fxs_hooksig(struct wctdm *wc, struct wctdm_module *const mod,
if (x != fxs->lasttxhook) {
fxs->lasttxhook = x | SLIC_LF_OPPENDING;
mod->sethook = CMD_WR(LINE_STATE, fxs->lasttxhook);
+ fxs->oppending_timeout = wc->framecount + 100;
spin_unlock_irqrestore(&fxs->lasttxhooklock, flags);
if (debug & DEBUG_CARD) {
diff --git a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
index 909dd26..5049d5a 100644
--- a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
+++ b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
@@ -179,7 +179,6 @@ struct fxs {
* voicebus ISR.
*/
int lasttxhook;
- int oppending_ms;
u8 linefeed_control_shadow;
u8 hook_state_shadow;
spinlock_t lasttxhooklock;
@@ -191,6 +190,7 @@ struct fxs {
struct calregs calregs;
unsigned long check_alarm;
unsigned long check_proslic;
+ unsigned long oppending_timeout;
};
struct qrv {