--- ../../orig/bristuff-0.4.0-test6/cwain/cwain.c	2008-02-19 22:53:42.000000000 +0100
+++ cwain.c	2008-02-19 22:36:47.000000000 +0100
@@ -25,7 +25,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <zaptel.h>
+#include "zaptel.h"
 #include "cwain.h"
 
 #ifdef LINUX26
@@ -238,9 +238,14 @@
     cwain_outb(cwaintmp,cwain_R_CTRL,0x0); 
 
     /* no blinky blink */
-    cwain_outb(cwaintmp,cwain_R_GPIO_SEL,0x20 | 0x10);
+    cwain_outb(cwaintmp,cwain_R_GPIO_SEL,
+	       0x20 | 0x10 | (cwaintmp->have_wd ? 0x2 : 0x0));
     cwain_outb(cwaintmp,cwain_R_GPIO_EN1,0x0f);
     cwain_outb(cwaintmp,cwain_R_GPIO_OUT1,0x0f);
+    if (cwaintmp->have_wd) {
+	    cwain_outb(cwaintmp, cwain_R_GPIO_EN0, 
+		       cwain_V_GPIO_EN2 | cwain_V_GPIO_EN3);
+    }
 
     /* IRQs off */
     cwain_outb(cwaintmp,cwain_R_IRQMSK_MISC,0x0); 
@@ -1374,6 +1379,83 @@
 }
 
 
+/*
+ * control the watchdog
+ */
+static void
+beronet_watchdog(struct zt_cwain_card *hc)
+{
+	if (hc->have_wd) {
+		hc->wdbyte = (hc->wdbyte == cwain_V_GPIO_OUT2) ?
+			cwain_V_GPIO_OUT3 : cwain_V_GPIO_OUT2;
+
+		/* printk("Sending Watchdog Kill %x\n",hc->wdbyte); */
+		cwain_outb(hc->span[0], cwain_R_GPIO_EN0, 
+			   cwain_V_GPIO_EN2 | cwain_V_GPIO_EN3);
+		cwain_outb(hc->span[0], cwain_R_GPIO_OUT0, hc->wdbyte);
+
+		cwain_outb(hc->span[1], cwain_R_GPIO_EN0, 
+			   cwain_V_GPIO_EN2 | cwain_V_GPIO_EN3);
+		cwain_outb(hc->span[1], cwain_R_GPIO_OUT0, hc->wdbyte);
+	}
+}
+
+static struct timer_list watchdogtimer;
+
+static void beronet_watchdog_check(unsigned long ignored)
+{
+	unsigned long flags;
+	struct zt_cwain_card *hc = cwain_card_list;
+
+	local_irq_save(flags);
+
+	while (hc) {
+		beronet_watchdog(hc);
+		hc = hc->next;
+	}
+
+	local_irq_restore(flags);
+
+	mod_timer(&watchdogtimer, jiffies + 20);
+}
+
+static int beronet_need_watchdog(void)
+{
+	struct zt_cwain_card *hc = cwain_card_list;
+	int need_wd = 0;
+
+	while (hc) {
+		if (hc->have_wd) {
+			need_wd = 1;
+			break;
+		}
+		hc = hc->next;
+	}
+
+	return need_wd;
+}
+
+static void beronet_watchdog_init(void)
+{
+	if (beronet_need_watchdog()) {
+		printk("Setting up beronet watchdog timer\n");
+		init_timer(&watchdogtimer);
+		watchdogtimer.expires = 0;
+		watchdogtimer.data =0;
+		watchdogtimer.function = beronet_watchdog_check;
+		/* Run every couple of jiffy or so */
+		mod_timer(&watchdogtimer, jiffies + 20);
+	}
+}
+
+static void beronet_watchdog_cleanup(void)
+{
+	if (beronet_need_watchdog()) {
+		del_timer(&watchdogtimer);
+	}
+}
+
+
 ZAP_IRQ_HANDLER(cwain_interrupt) {
     struct zt_cwain_card *cwaintmp = dev_id;
     unsigned char status, status2, status_tmp, irq_misc, irq_misc2 = 0;
@@ -1933,6 +2015,9 @@
 		break;
 	    case 0xb565:
 		sprintf(cwaintmp->span.desc,"BeroNet BN2E1 (+) (dual HFC-E1 w/failover) PCI ISDN Card %d (cardID %d) (1 E1 port)",cwaintmp->cardno,cwaintmp->cardID);
+		cwaincard->have_wd = 1;
+		cwaintmp->have_wd = 1;
+		cwaincard->wdbyte = cwain_V_GPIO_OUT2;
 		break;
 	    default:
 		return -1;
@@ -2218,6 +2303,7 @@
     } else {
 	printk(KERN_INFO "cwain: %d cwain card(s) in this box, %d E1 ports total, hw_hdcl = %d, dacs =%d, require_ext_clock = %d, ZT_CHUNKSIZE = %d, timer = %d.\n", cwain_card_count, cwain_span_count, hw_hdlc, dacs, require_ext_clock, ZT_CHUNKSIZE, cwain_TIMER_INT);
     }
+    beronet_watchdog_init();
     return 0;
 }
 
@@ -2226,6 +2312,8 @@
     struct zt_cwain *tmpspan,*spanlist;
     int i=0;
     int j=0;
+
+    beronet_watchdog_cleanup();
     
     tmplist = cwain_card_list;
     tmpcard = NULL;
--- ../../orig/bristuff-0.4.0-test6/cwain/cwain.h	2008-01-02 10:25:24.000000000 +0100
+++ cwain.h	2008-02-19 21:47:28.000000000 +0100
@@ -33,6 +33,7 @@
     
     /* blinky blink */
     unsigned char leds[4];
+    unsigned char have_wd;
 
     /* B chan buffers */
     unsigned char rxbuf[31][ZT_CHUNKSIZE];
@@ -81,6 +82,8 @@
     int syncsrc;
     int syncs[2];
     int master[2];
+    int wdbyte;
+    unsigned char have_wd;
     
     unsigned int irq;   
     unsigned int pcibus;
@@ -249,3 +252,10 @@
 #define CLKDEL_TE	0xe	/* CLKDEL in TE mode */
 #define CLKDEL_NT	0xc	/* CLKDEL in NT mode */
 
+
+#define cwain_V_GPIO_OUT2		0x04
+#define cwain_V_GPIO_OUT3		0x08
+#define cwain_V_GPIO_EN0		0x01
+#define cwain_V_GPIO_EN1		0x02
+#define cwain_V_GPIO_EN2		0x04
+#define cwain_V_GPIO_EN3		0x08
