From 6b6d0472418214f2203387c541fed59f8c393f34 Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Wed, 14 Dec 2011 19:02:53 +0000 Subject: [PATCH] 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 git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10380 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/wct4xxp/base.c | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) 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);