summaryrefslogtreecommitdiff
path: root/zaptel.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-05-15 01:30:02 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-05-15 01:30:02 +0000
commit5b864019c5aeccf32d5ab83a856360e46e1436d9 (patch)
tree8180720fcf1be92ca1f006be535baed4f3b75861 /zaptel.c
parent58d72a7794acc5d64a4d0580fca22aae04c149ca (diff)
Initial "watchdog" support
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@180 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'zaptel.c')
-rwxr-xr-xzaptel.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/zaptel.c b/zaptel.c
index df3615d..c2a073a 100755
--- a/zaptel.c
+++ b/zaptel.c
@@ -5401,6 +5401,9 @@ int zt_receive(struct zt_span *span)
unsigned long flags;
#if 1
+#ifdef CONFIG_ZAPTEL_WATCHDOG
+ span->watchcounter--;
+#endif
for (x=0;x<span->channels;x++) {
if (span->chans[x].master == &span->chans[x]) {
spin_lock_irqsave(&span->chans[x].lock, flags);
@@ -5553,6 +5556,59 @@ static struct file_operations zt_fops = {
fasync: NULL,
};
+#ifdef CONFIG_ZAPTEL_WATCHDOG
+static struct timer_list watchdogtimer;
+
+static void watchdog_check(unsigned long ignored)
+{
+ int x;
+ long flags;
+ local_irq_save(flags);
+ for (x=0;x<maxspans;x++) {
+ if (spans[x]) {
+ if (spans[x]->watchcounter == ZT_WATCHDOG_INIT) {
+ /* Whoops, dead card */
+ if ((spans[x]->watchstate == ZT_WATCHSTATE_OK) ||
+ (spans[x]->watchstate == ZT_WATCHSTATE_UNKNOWN)) {
+ spans[x]->watchstate = ZT_WATCHSTATE_RECOVERING;
+ if (spans[x]->watchdog) {
+ printk("Kicking span %s\n", spans[x]->name);
+ spans[x]->watchdog(spans[x], ZT_WATCHDOG_NOINTS);
+ } else {
+ printk("Span %s is dead with no revival\n", spans[x]->name);
+ spans[x]->watchstate = ZT_WATCHSTATE_FAILED;
+ }
+ }
+ } else {
+ if (spans[x]->watchstate != ZT_WATCHSTATE_OK)
+ printk("Span %s is alive!\n", spans[x]->name);
+ spans[x]->watchstate = ZT_WATCHSTATE_OK;
+ }
+ spans[x]->watchcounter = ZT_WATCHDOG_INIT;
+ }
+ }
+ local_irq_restore(flags);
+ mod_timer(&watchdogtimer, jiffies + 1);
+}
+
+static int __init watchdog_init(void)
+{
+ init_timer(&watchdogtimer);
+ watchdogtimer.expires = 0;
+ watchdogtimer.data =0;
+ watchdogtimer.function = watchdog_check;
+ /* Run every couple of jiffy or so */
+ mod_timer(&watchdogtimer, jiffies + 1);
+ return 0;
+}
+
+static void watchdog_cleanup(void)
+{
+ del_timer(&watchdogtimer);
+}
+
+#endif
+
static int __init zt_init(void) {
int res = 0;
@@ -5582,6 +5638,9 @@ static int __init zt_init(void) {
fasthdlc_precalc();
rotate_sums();
rwlock_init(&chan_lock);
+#ifdef CONFIG_ZAPTEL_WATCHDOG
+ watchdog_init();
+#endif
return res;
}
@@ -5605,6 +5664,9 @@ static void __exit zt_cleanup(void) {
#else
unregister_chrdev(ZT_MAJOR, "zaptel");
#endif
+#ifdef CONFIG_ZAPTEL_WATCHDOG
+ watchdog_cleanup();
+#endif
}
module_init(zt_init);