summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2011-12-14 19:02:53 +0000
committerShaun Ruffell <sruffell@digium.com>2011-12-14 19:02:53 +0000
commita0266a7a37a4306d7c3a6ebe80d1d9efab65c1a5 (patch)
treea10a6d46b6b2b8b638217567f6b11c6f92ca7195
parente36b34aa8ce6de4e37dbfb020e7fe9d5ce068bb7 (diff)
wct4xxp: Fail startup if not generating interrupts.
I've seen some platforms that do not properly route the interrupt from the card to the host CPU. In these cases the card potentially could appear to be greened up even though no data is flowing over the spans. This change allows dahdi_cfg to return an error when this occurs, and also ensures that all the spans are in RED alarm. For example, dahdi_cfg output when the card is not generating interrupts: # dahdi_cfg DAHDI startup failed: Input/output error And the kernel log will contain a string like: wct4xxp 0000:02:08.0: Interrupts not detected. Signed-off-by: Shaun Ruffell <sruffell@digium.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10380 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/wct4xxp/base.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/dahdi/wct4xxp/base.c b/drivers/dahdi/wct4xxp/base.c
index c47577a..c91ce59 100644
--- a/drivers/dahdi/wct4xxp/base.c
+++ b/drivers/dahdi/wct4xxp/base.c
@@ -2786,6 +2786,39 @@ static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig)
wc->numspans, unit + 1, framing, line, crc4);
}
+/**
+ * t4_check_for_interrupts - Return 0 if the card is generating interrupts.
+ * @wc: The card to check.
+ *
+ * If the card is not generating interrupts, this function will also place all
+ * the spans on the card into red alarm.
+ *
+ */
+static int t4_check_for_interrupts(struct t4 *wc)
+{
+ unsigned int starting_intcount = wc->intcount;
+ unsigned long stop_time = jiffies + HZ*2;
+ unsigned long flags;
+ int x;
+
+ msleep(20);
+ spin_lock_irqsave(&wc->reglock, flags);
+ while (starting_intcount == wc->intcount) {
+ spin_unlock_irqrestore(&wc->reglock, flags);
+ if (time_after(jiffies, stop_time)) {
+ for (x = 0; x < wc->numspans; x++)
+ wc->tspans[x]->span.alarms = DAHDI_ALARM_RED;
+ dev_err(&wc->dev->dev, "Interrupts not detected.\n");
+ return -EIO;
+ }
+ msleep(100);
+ spin_lock_irqsave(&wc->reglock, flags);
+ }
+ spin_unlock_irqrestore(&wc->reglock, flags);
+
+ return 0;
+}
+
static int t4_startup(struct file *file, struct dahdi_span *span)
{
#ifdef SUPPORT_GEN1
@@ -2908,6 +2941,11 @@ static int t4_startup(struct file *file, struct dahdi_span *span)
"Source\n", span->spanno);
}
+ if (!alreadyrunning) {
+ if (t4_check_for_interrupts(wc))
+ return -EIO;
+ }
+
if (debug)
dev_info(&wc->dev->dev, "Completed startup!\n");
clear_bit(T4_IGNORE_LATENCY, &wc->checkflag);