[Pkg-voip-commits] r7003 - in /dahdi-linux/trunk: debian/changelog debian/copyright debian/rules drivers/dahdi/opvxa1200.c

tzafrir-guest at alioth.debian.org tzafrir-guest at alioth.debian.org
Thu Apr 16 07:38:04 UTC 2009


Author: tzafrir-guest
Date: Thu Apr 16 07:38:03 2009
New Revision: 7003

URL: http://svn.debian.org/wsvn/pkg-voip/?sc=1&rev=7003
Log:
* Actually build OpenVox drivers.
* opvxa1200.c: rev. 1.4.12.4 (battery fixes and such)

Modified:
    dahdi-linux/trunk/debian/changelog
    dahdi-linux/trunk/debian/copyright
    dahdi-linux/trunk/debian/rules
    dahdi-linux/trunk/drivers/dahdi/opvxa1200.c

Modified: dahdi-linux/trunk/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-voip/dahdi-linux/trunk/debian/changelog?rev=7003&op=diff
==============================================================================
--- dahdi-linux/trunk/debian/changelog (original)
+++ dahdi-linux/trunk/debian/changelog Thu Apr 16 07:38:03 2009
@@ -1,8 +1,10 @@
 dahdi-linux (1:2.1.0.4~dfsg-2) UNRELEASED; urgency=low
 
   * NOT RELEASED YET
-
- -- Mark Purcell <msp at debian.org>  Sun, 29 Mar 2009 18:02:18 +1100
+  * Actually build OpenVox drivers.
+  * opvxa1200.c: rev. 1.4.12.4 (battery fixes and such)
+
+ -- Tzafrir Cohen <tzafrir.cohen at xorcom.com>  Thu, 16 Apr 2009 10:12:35 +0300
 
 dahdi-linux (1:2.1.0.4~dfsg-1) experimental; urgency=low
 

Modified: dahdi-linux/trunk/debian/copyright
URL: http://svn.debian.org/wsvn/pkg-voip/dahdi-linux/trunk/debian/copyright?rev=7003&op=diff
==============================================================================
--- dahdi-linux/trunk/debian/copyright (original)
+++ dahdi-linux/trunk/debian/copyright Thu Apr 16 07:38:03 2009
@@ -7,6 +7,8 @@
   http://www.junghanns.net/download/
 florz' patch for the zaphfc driver was downloaded from
   http://zaphfc.florz.dyndns.org/
+OpenVox drivers were downloaded from
+  http://www.openvox.cn/download/drivers/dahdi/
 
 Upstream source has been modified to comply with the Debian Free 
 Software Guildlines (DFSG), by the removal of the firmware files:

Modified: dahdi-linux/trunk/debian/rules
URL: http://svn.debian.org/wsvn/pkg-voip/dahdi-linux/trunk/debian/rules?rev=7003&op=diff
==============================================================================
--- dahdi-linux/trunk/debian/rules (original)
+++ dahdi-linux/trunk/debian/rules Thu Apr 16 07:38:03 2009
@@ -45,7 +45,6 @@
 
 EXTRA_MODS=opvxa1200
 
-EXTRA_MODS=
 ifneq (,$(filter-out powerpc m68k armeb mips,$(shell dpkg-architecture -qDEB_HOST_ARCH)))
 EXTRA_MODS += wcopenpci zaphfc
 endif

Modified: dahdi-linux/trunk/drivers/dahdi/opvxa1200.c
URL: http://svn.debian.org/wsvn/pkg-voip/dahdi-linux/trunk/drivers/dahdi/opvxa1200.c?rev=7003&op=diff
==============================================================================
--- dahdi-linux/trunk/drivers/dahdi/opvxa1200.c (original)
+++ dahdi-linux/trunk/drivers/dahdi/opvxa1200.c Thu Apr 16 07:38:03 2009
@@ -67,8 +67,23 @@
  *      Power alarm debug stuff removed.
  * 
  * Rev 2.0 DAHDI 2008/10/17
+ *
+ * Rev 2.0.1 add new pci id 0x9599
+ * Re 2.0.2 12/01/2009  
+       add fixedtimepolarity: set time(ms) when send polarity after 1st ring happen. 
+ *				Sometimes the dtmf cid is sent just after first ring off, and the system do not have 
+ *				enough time to start detect 1st dtmf.
+ *				0 means send polarity at the end of 1st ring.
+ *				x means send ploarity after x ms of 1st ring begin.
  * 
- */
+ * Rev 2.0.3 12/01/2009 
+ *        Add touch_softlockup_watchdog() in wctdm_hardware_init, to avoid cpu softlockup system message for FXS.
+ *
+ *
+ * Rev 1.4.12.4  17/04/2009 James.zhu
+ *       Changed wctdm_voicedaa_check_hook() to detect FXO battery and solved the problem with dial(dahdi/go/XXXXXXXXXX)
+ *       add alarm detection for FXO
+ */ 
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -218,19 +233,8 @@
 #define FLAG_EMPTY	0
 #define FLAG_WRITE	1
 #define FLAG_READ	2
-
-
 #define DEFAULT_RING_DEBOUNCE		64		/* Ringer Debounce (64 ms) */
-
-/* the constants below control the 'debounce' periods enforced by the
-   check_hook routines; these routines are called once every 4 interrupts
-   (the interrupt cycles around the four modules), so the periods are
-   specified in _4 millisecond_ increments
-*/
-#define DEFAULT_BATT_DEBOUNCE	4		/* Battery debounce (64 ms) */
-#define POLARITY_DEBOUNCE 	4		/* Polarity debounce (64 ms) */
-#define DEFAULT_BATT_THRESH	3		/* Anything under this is "no battery" */
-
+#define POLARITY_DEBOUNCE 	64  	/* Polarity debounce (64 ms) */
 #define OHT_TIMER		6000	/* How long after RING to retain OHT */
 
 #define FLAG_3215	(1 << 0)
@@ -274,6 +278,11 @@
 	PROSLIC_POWER_WARNED,
 };
 
+enum battery_state {
+	BATTERY_UNKNOWN = 0,
+	BATTERY_PRESENT,
+	BATTERY_LOST,
+};
 struct wctdm {
 	struct pci_dev *dev;
 	char *variety;
@@ -292,7 +301,7 @@
 	spinlock_t lock;
 
 	union {
-		struct {
+		struct fxo {
 #ifdef AUDIO_RINGCHECK
 			unsigned int pegtimer;
 			int pegcount;
@@ -304,14 +313,14 @@
 #endif			
 			int ringdebounce;
 			int offhook;
-			int battdebounce;
-			int nobatttimer;
-			int battery;
+		    unsigned int battdebounce;
+			unsigned int battalarm;
+			enum battery_state battery;
 		        int lastpol;
 		        int polarity;
 		        int polaritydebounce;
 		} fxo;
-		struct {
+		struct fxs {
 			int oldrxhook;
 			int debouncehook;
 			int lastrxhook;
@@ -357,6 +366,7 @@
 	int	 cid_history_ptr[MAX_NUM_CARDS];
 	int  cid_history_clone_cnt[MAX_NUM_CARDS];
 	enum cid_hook_state cid_state[MAX_NUM_CARDS];
+ int 	cid_ring_on_time[MAX_NUM_CARDS];
 };
 
 char* A1200P_Name = "A1200P";
@@ -374,8 +384,9 @@
 
 static void wctdm_release(struct wctdm *wc);
 
-static int battdebounce = DEFAULT_BATT_DEBOUNCE;
-static int battthresh = DEFAULT_BATT_THRESH;
+static unsigned int battdebounce;
+static unsigned int battalarm;
+static unsigned int battthresh;
 static int ringdebounce = DEFAULT_RING_DEBOUNCE;
 static int fwringdetect = 0;
 static int debug = 0;
@@ -400,6 +411,7 @@
 static int cidbuflen = 3000;	/* in msec, default 3000 */
 static int cidtimeout = 6*1000;	/* in msec, default 6000 */
 static int fxofullscale = 0;	/* fxo full scale tx/rx, register 30, acim */
+static int fixedtimepolarity=0;	/* time delay in ms when send polarity after rise edge of 1st ring.*/
 
 static int wctdm_init_proslic(struct wctdm *wc, int card, int fast , int manual, int sane);
 
@@ -479,13 +491,13 @@
 		/* Look for pegging to indicate ringing */
 		sample = DAHDI_XLAW(wc->chans[card].readchunk[x], (&(wc->chans[card])));
 		if ((sample > 10000) && (wc->mod[card].fxo.peg != 1)) {
-			if (debug > 1) printk("High peg!\n");
+			if (debug > 1) printk(KERN_DEBUG "High peg!\n");
 			if ((wc->mod[card].fxo.pegtimer < PEGTIME) && (wc->mod[card].fxo.pegtimer > MINPEGTIME))
 				wc->mod[card].fxo.pegcount++;
 			wc->mod[card].fxo.pegtimer = 0;
 			wc->mod[card].fxo.peg = 1;
 		} else if ((sample < -10000) && (wc->mod[card].fxo.peg != -1)) {
-			if (debug > 1) printk("Low peg!\n");
+			if (debug > 1) printk(KERN_DEBUG "Low peg!\n");
 			if ((wc->mod[card].fxo.pegtimer < (PEGTIME >> 2)) && (wc->mod[card].fxo.pegtimer > (MINPEGTIME >> 2)))
 				wc->mod[card].fxo.pegcount++;
 			wc->mod[card].fxo.pegtimer = 0;
@@ -503,7 +515,7 @@
 		if (!wc->mod[card].fxo.ring && (wc->mod[card].fxo.pegcount > PEGCOUNT)) {
 			/* It's ringing */
 			if (debug)
-				printk("RING on %d/%d!\n", wc->span.spanno, card + 1);
+				printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
 			if (!wc->mod[card].fxo.offhook)
 				dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_RING);
 			wc->mod[card].fxo.ring = 1;
@@ -511,7 +523,7 @@
 		if (wc->mod[card].fxo.ring && !wc->mod[card].fxo.pegcount) {
 			/* No more ring */
 			if (debug)
-				printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1);
+				printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
 			dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK);
 			wc->mod[card].fxo.ring = 0;
 		}
@@ -852,7 +864,7 @@
 
 	 }
 
-    if(count > (MAX-1)) printk(" ##### Loop error (%02x) #####\n", data);
+    if(count > (MAX-1)) printk(KERN_NOTICE " ##### Loop error (%02x) #####\n", data);
 
 	return 0;
 }
@@ -915,7 +927,7 @@
 		p = "failed to wait\n";
 	spin_unlock_irqrestore(&wc->lock, flags);
 	if (p)
-		printk(p);
+		printk(KERN_NOTICE "%s", p);
 	return res;
 }
 
@@ -941,14 +953,14 @@
 	for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++) 
 	{
 		if((j = wctdm_proslic_getreg_indirect(wc, card, (unsigned char) indirect_regs[i].address)) < 0) {
-			printk("Failed to read indirect register %d\n", i);
+			printk(KERN_NOTICE "Failed to read indirect register %d\n", i);
 			return -1;
 		}
 		initial= indirect_regs[i].initial;
 
 		if ( j != initial && (!(wc->flags[card] & FLAG_3215) || (indirect_regs[i].altaddr != 255)))
 		{
-			 printk("!!!!!!! %s  iREG %X = %X  should be %X\n",
+			 printk(KERN_NOTICE "!!!!!!! %s  iREG %X = %X  should be %X\n",
 				indirect_regs[i].name,indirect_regs[i].address,j,initial );
 			 passed = 0;
 		}	
@@ -956,9 +968,9 @@
 
     if (passed) {
 		if (debug)
-			printk("Init Indirect Registers completed successfully.\n");
+			printk(KERN_DEBUG "Init Indirect Registers completed successfully.\n");
     } else {
-		printk(" !!!!! Init Indirect Registers UNSUCCESSFULLY.\n");
+		printk(KERN_NOTICE " !!!!! Init Indirect Registers UNSUCCESSFULLY.\n");
 		return -1;
     }
     return 0;
@@ -976,79 +988,96 @@
 	if (!res && (res != wc->mod[card].fxs.lasttxhook)) {
 		res = wctdm_getreg(wc, card, 8);
 		if (res) {
-			printk("Ouch, part reset, quickly restoring reality (%d)\n", card);
+			printk(KERN_NOTICE "Ouch, part reset, quickly restoring reality (%d)\n", card);
 			wctdm_init_proslic(wc, card, 1, 0, 1);
 		} else {
 			if (wc->mod[card].fxs.palarms++ < MAX_ALARMS) {
-				printk("Power alarm on module %d, resetting!\n", card + 1);
+				printk(KERN_NOTICE "Power alarm on module %d, resetting!\n", card + 1);
 				if (wc->mod[card].fxs.lasttxhook == 4)
 					wc->mod[card].fxs.lasttxhook = 1;
 				wctdm_setreg(wc, card, 64, wc->mod[card].fxs.lasttxhook);
 			} else {
 				if (wc->mod[card].fxs.palarms == MAX_ALARMS)
-					printk("Too many power alarms on card %d, NOT resetting!\n", card + 1);
+					printk(KERN_NOTICE "Too many power alarms on card %d, NOT resetting!\n", card + 1);
 			}
 		}
 	}
 }
-
 static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
 {
+#define MS_PER_CHECK_HOOK 16
+
 #ifndef AUDIO_RINGCHECK
 	unsigned char res;
 #endif	
 	signed char b;
-	int poopy = 0;
+	int errors = 0;
+	struct fxo *fxo = &wc->mod[card].fxo;
+
 	/* Try to track issues that plague slot one FXO's */
 	b = wc->reg0shadow[card];
 	if ((b & 0x2) || !(b & 0x8)) {
 		/* Not good -- don't look at anything else */
 		if (debug)
-			printk("Poopy (%02x) on card %d!\n", b, card + 1); 
-		poopy++;
+			printk(KERN_DEBUG "Error (%02x) on card %d!\n", b, card + 1); 
+		errors++;
 	}
 	b &= 0x9b;
-	if (wc->mod[card].fxo.offhook) {
+	if (fxo->offhook) {
 		if (b != 0x9)
 			wctdm_setreg(wc, card, 5, 0x9);
 	} else {
 		if (b != 0x8)
 			wctdm_setreg(wc, card, 5, 0x8);
 	}
-	if (poopy)
+	if (errors)
 		return;
-#ifndef AUDIO_RINGCHECK
-	if (!wc->mod[card].fxo.offhook) {
+	if (!fxo->offhook) {
+ if(fixedtimepolarity)
+			if ( wc->cid_state[card] == CID_STATE_RING_ON && wc->cid_ring_on_time[card]>0)
+				if(wc->cid_ring_on_time[card]>=fixedtimepolarity )
+				{
+					dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
+					wc->cid_ring_on_time[card] = -1;	/* the polarity already sent */	
+				}
+				else
+					wc->cid_ring_on_time[card] += 16;
 		if (fwringdetect) {
 			res = wc->reg0shadow[card] & 0x60;
-			if (wc->mod[card].fxo.ringdebounce--) {
-				if (res && (res != wc->mod[card].fxo.lastrdtx) && (wc->mod[card].fxo.battery == 1)) {
-					if (!wc->mod[card].fxo.wasringing) {
-						wc->mod[card].fxo.wasringing = 1;
+			if (fxo->ringdebounce) {
+				--fxo->ringdebounce;
+				if (res && (res != fxo->lastrdtx) &&
+				    (fxo->battery == BATTERY_PRESENT)) {
+					if (!fxo->wasringing) {
+						fxo->wasringing = 1;
 						if (debug)
-							printk("RING on %d/%d!\n", wc->span.spanno, card + 1);
-						if(cidbeforering)
+          printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
+	if(cidbeforering)
 						{
 							if(wc->cid_state[card] == CID_STATE_IDLE)
+							{
 								wc->cid_state[card] = CID_STATE_RING_ON;
+								wc->cid_ring_on_time[card] = 1;	/* check every 16ms */
+							}
 							else
 								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
 						}
-						else
-							dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
+						else 							
+        dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
 					}
-					wc->mod[card].fxo.lastrdtx = res;
-					wc->mod[card].fxo.ringdebounce = 10;
+					fxo->lastrdtx = res;
+					fxo->ringdebounce = 10;
 				} else if (!res) {
-					if ((wc->mod[card].fxo.ringdebounce == 0) && wc->mod[card].fxo.wasringing) {
-						wc->mod[card].fxo.wasringing = 0;
-						if (debug)
-							printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1);
-						if(cidbeforering)
+					if ((fxo->ringdebounce == 0) && fxo->wasringing) {
+				fxo->wasringing = 0;
+				if (debug)
+				printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
+	if(cidbeforering)
 						{
 							if(wc->cid_state[card] == CID_STATE_RING_ON)
 							{
-								dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
+								if(fixedtimepolarity==0)
+									dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
 								wc->cid_state[card] = CID_STATE_RING_OFF;
 							}
 							else 
@@ -1059,44 +1088,49 @@
 							}
 						}
 						else
-							dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
-					}
+
+						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
 				}
-			} else if (res && (wc->mod[card].fxo.battery == 1)) {
-				wc->mod[card].fxo.lastrdtx = res;
-				wc->mod[card].fxo.ringdebounce = 10;
+				}
+			} else if (res && (fxo->battery == BATTERY_PRESENT)) {
+				fxo->lastrdtx = res;
+				fxo->ringdebounce = 10;
 			}
 		} else {
 			res = wc->reg0shadow[card];
-			if ((res & 0x60) && (wc->mod[card].fxo.battery == 1)) {
-				wc->mod[card].fxo.ringdebounce += (DAHDI_CHUNKSIZE * 16);
-				if (wc->mod[card].fxo.ringdebounce >= DAHDI_CHUNKSIZE * ringdebounce) {
-					if (!wc->mod[card].fxo.wasringing) {
-						wc->mod[card].fxo.wasringing = 1;
-						if(cidbeforering)
+			if ((res & 0x60) && (fxo->battery == BATTERY_PRESENT)) {
+				fxo->ringdebounce += (DAHDI_CHUNKSIZE * 16);
+				if (fxo->ringdebounce >= DAHDI_CHUNKSIZE * ringdebounce) {
+					if (!fxo->wasringing) {
+						fxo->wasringing = 1;
+ if(cidbeforering)
 						{
 							if(wc->cid_state[card] == CID_STATE_IDLE)
+							{	
 								wc->cid_state[card] = CID_STATE_RING_ON;
+								wc->cid_ring_on_time[card] = 1;		/* check every 16ms */
+							}
 							else
 								dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
 						}
-						else
-							dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
+						else      
+						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
 						if (debug)
-							printk("RING on %d/%d!\n", wc->span.spanno, card + 1);
+							printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
 					}
-					wc->mod[card].fxo.ringdebounce = DAHDI_CHUNKSIZE * ringdebounce;
+					fxo->ringdebounce = DAHDI_CHUNKSIZE * ringdebounce;
 				}
 			} else {
-				wc->mod[card].fxo.ringdebounce -= DAHDI_CHUNKSIZE * 4;
-				if (wc->mod[card].fxo.ringdebounce <= 0) {
-					if (wc->mod[card].fxo.wasringing) {
-						wc->mod[card].fxo.wasringing = 0;
-						if(cidbeforering)
+				fxo->ringdebounce -= DAHDI_CHUNKSIZE * 4;
+				if (fxo->ringdebounce <= 0) {
+					if (fxo->wasringing) {
+						fxo->wasringing = 0;
+	if(cidbeforering)
 						{
 							if(wc->cid_state[card] == CID_STATE_RING_ON)
 							{
-								dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
+								if(fixedtimepolarity==0)
+									dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
 								wc->cid_state[card] = CID_STATE_RING_OFF;
 							}
 							else 
@@ -1107,106 +1141,137 @@
 							}
 						}
 						else
-							dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
+						dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
 						if (debug)
-							printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1);
+							printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
 					}
-					wc->mod[card].fxo.ringdebounce = 0;
+					fxo->ringdebounce = 0;
 				}
 			}
 		}
 	}
+
+	b = wc->reg1shadow[card];
+	if (abs(b) < battthresh) {
+		/* possible existing states:
+		   battery lost, no debounce timer
+		   battery lost, debounce timer (going to battery present)
+		   battery present or unknown, no debounce timer
+		   battery present or unknown, debounce timer (going to battery lost)
+		*/
+
+		if (fxo->battery == BATTERY_LOST) {
+			if (fxo->battdebounce) {
+				/* we were going to BATTERY_PRESENT, but battery was lost again,
+				   so clear the debounce timer */
+				fxo->battdebounce = 0;
+			}
+		} else {
+			if (fxo->battdebounce) {
+				/* going to BATTERY_LOST, see if we are there yet */
+				if (--fxo->battdebounce == 0) {
+					fxo->battery = BATTERY_LOST;
+					if (debug)
+						printk(KERN_DEBUG "NO BATTERY on %d/%d!\n", wc->span.spanno, card + 1);
+#ifdef	JAPAN
+					if (!wc->ohdebounce && wc->offhook) {
+						dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_ONHOOK);
+						if (debug)
+							printk(KERN_DEBUG "Signalled On Hook\n");
+#ifdef	ZERO_BATT_RING
+						wc->onhook++;
 #endif
-	b = wc->reg1shadow[card];
-#if 0 
-	{
-		static int count = 0;
-		if (!(count++ % 100)) {
-			printk("Card %d: Voltage: %d  Debounce %d\n", card + 1, 
-			       b, wc->mod[card].fxo.battdebounce);
-		}
-	}
-#endif	
-	if (abs(b) < battthresh) {
-		wc->mod[card].fxo.nobatttimer++;
-#if 0
-		if (wc->mod[card].fxo.battery == 1)
-			printk("Battery loss: %d (%d debounce)\n", b, wc->mod[card].fxo.battdebounce);
+					}
+#else
+					dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_ONHOOK);
+					/* set the alarm timer, taking into account that part of its time
+					   period has already passed while debouncing occurred */
+					fxo->battalarm = (battalarm - battdebounce) / MS_PER_CHECK_HOOK;
 #endif
-		if (wc->mod[card].fxo.battery && !wc->mod[card].fxo.battdebounce) {
-			if (debug)
-				printk("NO BATTERY on %d/%d!\n", wc->span.spanno, card + 1);
-			wc->mod[card].fxo.battery =  0;
-#ifdef	JAPAN
-			if ((!wc->ohdebounce) && wc->offhook) {
-				dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_ONHOOK);
+				}
+			} else {
+				/* start the debounce timer to verify that battery has been lost */
+				fxo->battdebounce = battdebounce / MS_PER_CHECK_HOOK;
+			}
+		}
+	} else {
+		/* possible existing states:
+		   battery lost or unknown, no debounce timer
+		   battery lost or unknown, debounce timer (going to battery present)
+		   battery present, no debounce timer
+		   battery present, debounce timer (going to battery lost)
+		*/
+
+		if (fxo->battery == BATTERY_PRESENT) {
+			if (fxo->battdebounce) {
+				/* we were going to BATTERY_LOST, but battery appeared again,
+				   so clear the debounce timer */
+				fxo->battdebounce = 0;
+			}
+		} else {
+			if (fxo->battdebounce) {
+				/* going to BATTERY_PRESENT, see if we are there yet */
+				if (--fxo->battdebounce == 0) {
+					fxo->battery = BATTERY_PRESENT;
+					if (debug)
+						printk(KERN_DEBUG "BATTERY on %d/%d (%s)!\n", wc->span.spanno, card + 1, 
+						       (b < 0) ? "-" : "+");			    
+#ifdef	ZERO_BATT_RING
+					if (wc->onhook) {
+						wc->onhook = 0;
+						dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK);
+						if (debug)
+							printk(KERN_DEBUG "Signalled Off Hook\n");
+					}
+#else
+					dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
+#endif
+					/* set the alarm timer, taking into account that part of its time
+					   period has already passed while debouncing occurred */
+					fxo->battalarm = (battalarm - battdebounce) / MS_PER_CHECK_HOOK;
+				}
+			} else {
+				/* start the debounce timer to verify that battery has appeared */
+				fxo->battdebounce = battdebounce / MS_PER_CHECK_HOOK;
+			}
+		}
+	}
+
+	if (fxo->lastpol >= 0) {
+		if (b < 0) {
+			fxo->lastpol = -1;
+			fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK;
+		}
+	} 
+	if (fxo->lastpol <= 0) {
+		if (b > 0) {
+			fxo->lastpol = 1;
+			fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK;
+		}
+	}
+
+	if (fxo->battalarm) {
+		if (--fxo->battalarm == 0) {
+			/* the alarm timer has expired, so update the battery alarm state
+			   for this channel */
+			dahdi_alarm_channel(wc->chans[card], fxo->battery == BATTERY_LOST ? DAHDI_ALARM_RED : DAHDI_ALARM_NONE);
+		}
+	}
+
+	if (fxo->polaritydebounce) {
+		if (--fxo->polaritydebounce == 0) {
+		    if (fxo->lastpol != fxo->polarity) {
 				if (debug)
-					printk("Signalled On Hook\n");
-#ifdef	ZERO_BATT_RING
-				wc->onhook++;
-#endif
-			}
-#else
-			dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_ONHOOK);
-			dahdi_alarm_channel(wc->chans[card], DAHDI_ALARM_NONE);
-#endif
-			wc->mod[card].fxo.battdebounce = battdebounce;
-		} else if (!wc->mod[card].fxo.battery)
-			wc->mod[card].fxo.battdebounce = battdebounce;
-	} else if (abs(b) > battthresh) {
-		if ((wc->mod[card].fxo.battery < 1)&& !wc->mod[card].fxo.battdebounce) {
-			if (debug)
-				printk("BATTERY on %d/%d (%s)!\n", wc->span.spanno, card + 1, 
-					(b < 0) ? "-" : "+");			    
-#ifdef	ZERO_BATT_RING
-			if (wc->onhook) {
-				wc->onhook = 0;
-				dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK);
-				if (debug)
-					printk("Signalled Off Hook\n");
-			}
-#else
-			dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
-			dahdi_alarm_channel(wc->chans[card], DAHDI_ALARM_NONE);
-#endif
-			wc->mod[card].fxo.battery = 1;
-			wc->mod[card].fxo.nobatttimer = 0;
-			wc->mod[card].fxo.battdebounce = battdebounce;
-		} else if (wc->mod[card].fxo.battery == 1)
-			wc->mod[card].fxo.battdebounce = battdebounce;
-
-		if (wc->mod[card].fxo.lastpol >= 0) {
-		    if (b < 0) {
-			wc->mod[card].fxo.lastpol = -1;
-			wc->mod[card].fxo.polaritydebounce = POLARITY_DEBOUNCE;
+					printk(KERN_DEBUG "%lu Polarity reversed (%d -> %d)\n", jiffies, 
+				       fxo->polarity, 
+				       fxo->lastpol);
+				if (fxo->polarity)
+					dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
+				fxo->polarity = fxo->lastpol;
 		    }
-		} 
-		if (wc->mod[card].fxo.lastpol <= 0) {
-		    if (b > 0) {
-			wc->mod[card].fxo.lastpol = 1;
-			wc->mod[card].fxo.polaritydebounce = POLARITY_DEBOUNCE;
-		    }
-		}
-	} else {
-		/* It's something else... */
-		wc->mod[card].fxo.battdebounce = battdebounce;
-	}
-	if (wc->mod[card].fxo.battdebounce)
-		wc->mod[card].fxo.battdebounce--;
-	if (wc->mod[card].fxo.polaritydebounce) {
-	        wc->mod[card].fxo.polaritydebounce--;
-		if (wc->mod[card].fxo.polaritydebounce < 1) {
-		    if (wc->mod[card].fxo.lastpol != wc->mod[card].fxo.polarity) {
-				if (debug)
-					printk("%lu Polarity reversed (%d -> %d)\n", jiffies, 
-				       wc->mod[card].fxo.polarity, 
-				       wc->mod[card].fxo.lastpol);
-				if (wc->mod[card].fxo.polarity)
-				    dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
-				wc->mod[card].fxo.polarity = wc->mod[card].fxo.lastpol;
-		    }
-		}
-	}
+		}
+	}
+#undef MS_PER_CHECK_HOOK
 }
 
 static inline void wctdm_proslic_check_hook(struct wctdm *wc, int card)
@@ -1223,17 +1288,17 @@
 		/* Reset the debounce (must be multiple of 4ms) */
 		wc->mod[card].fxs.debounce = 8 * (4 * 8);
 #if 0
-		printk("Resetting debounce card %d hook %d, %d\n", card, hook, wc->mod[card].fxs.debounce);
+		printk(KERN_DEBUG "Resetting debounce card %d hook %d, %d\n", card, hook, wc->mod[card].fxs.debounce);
 #endif
 	} else {
 		if (wc->mod[card].fxs.debounce > 0) {
 			wc->mod[card].fxs.debounce-= 16 * DAHDI_CHUNKSIZE;
 #if 0
-			printk("Sustaining hook %d, %d\n", hook, wc->mod[card].fxs.debounce);
+			printk(KERN_DEBUG "Sustaining hook %d, %d\n", hook, wc->mod[card].fxs.debounce);
 #endif
 			if (!wc->mod[card].fxs.debounce) {
 #if 0
-				printk("Counted down debounce, newhook: %d...\n", hook);
+				printk(KERN_DEBUG "Counted down debounce, newhook: %d...\n", hook);
 #endif
 				wc->mod[card].fxs.debouncehook = hook;
 			}
@@ -1242,7 +1307,7 @@
 #if 1
 				if (debug)
 #endif				
-					printk("opvxa1200: Card %d Going off hook\n", card);
+					printk(KERN_DEBUG "opvxa1200: Card %d Going off hook\n", card);
 				dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
 				if (robust)
 					wctdm_init_proslic(wc, card, 1, 0, 1);
@@ -1253,7 +1318,7 @@
 #if 1
 				if (debug)
 #endif				
-					printk("opvxa1200: Card %d Going on hook\n", card);
+					printk(KERN_DEBUG "opvxa1200: Card %d Going on hook\n", card);
 				dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_ONHOOK);
 				wc->mod[card].fxs.oldrxhook = 0;
 			}
@@ -1278,13 +1343,13 @@
 	
 	if (ints & 0x10) {
 		/* Stop DMA, wait for watchdog */
-		printk("TDM PCI Master abort\n");
+		printk(KERN_INFO "TDM PCI Master abort\n");
 		wctdm_stop_dma(wc);
 		return IRQ_RETVAL(1);
 	}
 	
 	if (ints & 0x20) {
-		printk("PCI Target abort\n");
+		printk(KERN_INFO "PCI Target abort\n");
 		return IRQ_RETVAL(1);
 	}
 
@@ -1385,7 +1450,7 @@
 		return -2;
 	blah = wctdm_getreg(wc, card, 11);
 	if (debug)
-		printk("VoiceDAA System: %02x\n", blah & 0xf);
+		printk(KERN_DEBUG "VoiceDAA System: %02x\n", blah & 0xf);
 	return 0;
 }
 
@@ -1396,11 +1461,11 @@
 
 	blah = wctdm_getreg(wc, card, 0);
 	if (debug) 
-		printk("ProSLIC on module %d, product %d, version %d\n", card, (blah & 0x30) >> 4, (blah & 0xf));
+		printk(KERN_DEBUG "ProSLIC on module %d, product %d, version %d\n", card, (blah & 0x30) >> 4, (blah & 0xf));
 
 #if 0
 	if ((blah & 0x30) >> 4) {
-		printk("ProSLIC on module %d is not a 3210.\n", card);
+		printk(KERN_DEBUG "ProSLIC on module %d is not a 3210.\n", card);
 		return -1;
 	}
 #endif
@@ -1409,7 +1474,7 @@
 		return -1;
 	}
 	if ((blah & 0xf) < 2) {
-		printk("ProSLIC 3210 version %d is too old\n", blah & 0xf);
+		printk(KERN_NOTICE "ProSLIC 3210 version %d is too old\n", blah & 0xf);
 		return -1;
 	}
 	if (wctdm_getreg(wc, card, 1) & 0x80)
@@ -1418,30 +1483,30 @@
 	
 	blah = wctdm_getreg(wc, card, 8);
 	if (blah != 0x2) {
-		printk("ProSLIC on module %d insane (1) %d should be 2\n", card, blah);
+		printk(KERN_NOTICE  "ProSLIC on module %d insane (1) %d should be 2\n", card, blah);
 		return -1;
 	} else if ( insane_report)
-		printk("ProSLIC on module %d Reg 8 Reads %d Expected is 0x2\n",card,blah);
+		printk(KERN_NOTICE  "ProSLIC on module %d Reg 8 Reads %d Expected is 0x2\n",card,blah);
 
 	blah = wctdm_getreg(wc, card, 64);
 	if (blah != 0x0) {
-		printk("ProSLIC on module %d insane (2)\n", card);
+		printk(KERN_NOTICE  "ProSLIC on module %d insane (2)\n", card);
 		return -1;
 	} else if ( insane_report)
-		printk("ProSLIC on module %d Reg 64 Reads %d Expected is 0x0\n",card,blah);
+		printk(KERN_NOTICE  "ProSLIC on module %d Reg 64 Reads %d Expected is 0x0\n",card,blah);
 
 	blah = wctdm_getreg(wc, card, 11);
 	if (blah != 0x33) {
-		printk("ProSLIC on module %d insane (3)\n", card);
+		printk(KERN_NOTICE  "ProSLIC on module %d insane (3)\n", card);
 		return -1;
 	} else if ( insane_report)
-		printk("ProSLIC on module %d Reg 11 Reads %d Expected is 0x33\n",card,blah);
+		printk(KERN_NOTICE  "ProSLIC on module %d Reg 11 Reads %d Expected is 0x33\n",card,blah);
 
 	/* Just be sure it's setup right. */
 	wctdm_setreg(wc, card, 30, 0);
 
 	if (debug) 
-		printk("ProSLIC on module %d seems sane.\n", card);
+		printk(KERN_DEBUG "ProSLIC on module %d seems sane.\n", card);
 	return 0;
 }
 
@@ -1465,11 +1530,11 @@
 	}
 
 	if (vbat < 0x06) {
-		printk("Excessive leakage detected on module %d: %d volts (%02x) after %d ms\n", card,
+		printk(KERN_NOTICE "Excessive leakage detected on module %d: %d volts (%02x) after %d ms\n", card,
 		       376 * vbat / 1000, vbat, (int)((jiffies - origjiffies) * 1000 / HZ));
 		return -1;
 	} else if (debug) {
-		printk("Post-leakage voltage: %d volts\n", 376 * vbat / 1000);
+		printk(KERN_NOTICE "Post-leakage voltage: %d volts\n", 376 * vbat / 1000);
 	}
 	return 0;
 }
@@ -1502,13 +1567,13 @@
 
 	if (vbat < 0xc0) {
 		if (wc->proslic_power == PROSLIC_POWER_UNKNOWN)
-				 printk("ProSLIC on module %d failed to powerup within %d ms (%d mV only)\n\n -- DID YOU REMEMBER TO PLUG IN THE HD POWER CABLE TO THE A1200P??\n",
+				 printk(KERN_NOTICE "ProSLIC on module %d failed to powerup within %d ms (%d mV only)\n\n -- DID YOU REMEMBER TO PLUG IN THE HD POWER CABLE TO THE A1200P??\n",
 					card, (int)(((jiffies - origjiffies) * 1000 / HZ)),
 					vbat * 375);
 		wc->proslic_power = PROSLIC_POWER_WARNED;
 		return -1;
 	} else if (debug) {
-		printk("ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",
+		printk(KERN_DEBUG "ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",
 		       card, vbat * 376 / 1000, vbat, (int)(((jiffies - origjiffies) * 1000 / HZ)));
 	}
 	wc->proslic_power = PROSLIC_POWER_ON;
@@ -1519,10 +1584,10 @@
         if ( loopcurrent > 41 ) {
                 lim = 0;
                 if (debug)
-                        printk("Loop current out of range! Setting to default 20mA!\n");
+                        printk(KERN_DEBUG "Loop current out of range! Setting to default 20mA!\n");
         }
         else if (debug)
-                        printk("Loop current set to %dmA!\n",(lim*3)+20);
+                        printk(KERN_DEBUG "Loop current set to %dmA!\n",(lim*3)+20);
         wctdm_setreg(wc,card,LOOP_I_LIMIT,lim);
 
 	/* Engage DC-DC converter */
@@ -1531,7 +1596,7 @@
 	origjiffies = jiffies;
 	while(0x80 & wctdm_getreg(wc, card, 93)) {
 		if ((jiffies - origjiffies) > 2 * HZ) {
-			printk("Timeout waiting for DC-DC calibration on module %d\n", card);
+			printk(KERN_DEBUG "Timeout waiting for DC-DC calibration on module %d\n", card);
 			return -1;
 		}
 	}
@@ -1542,7 +1607,7 @@
 
 	/* Just check to be sure */
 	vbat = wctdm_getreg(wc, card, 82);
-	printk("ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",
+	printk(KERN_DEBUG "ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",
 		       card, vbat * 376 / 1000, vbat, (int)(((jiffies - origjiffies) * 1000 / HZ)));
 #endif
 #endif
@@ -1638,16 +1703,16 @@
 	origjiffies = jiffies;
 	while(wctdm_getreg(wc, card, 96)) {
 		if ((jiffies - origjiffies) > 2 * HZ) {
-			printk("Timeout waiting for calibration of module %d\n", card);
+			printk(KERN_NOTICE "Timeout waiting for calibration of module %d\n", card);
 			return -1;
 		}
 	}
 	
 	if (debug) {
 		/* Print calibration parameters */
-		printk("Calibration Vector Regs 98 - 107: \n");
+		printk(KERN_DEBUG "Calibration Vector Regs 98 - 107: \n");
 		for (x=98;x<108;x++) {
-			printk("%d: %02x\n", x, wctdm_getreg(wc, card, x));
+			printk(KERN_DEBUG "%d: %02x\n", x, wctdm_getreg(wc, card, x));
 		}
 	}
 	return 0;
@@ -1672,12 +1737,12 @@
 static int wctdm_set_hwgain(struct wctdm *wc, int card, __s32 gain, __u32 tx)
 {
 	if (!(wc->modtype[card] == MOD_TYPE_FXO)) {
-		printk("Cannot adjust gain.  Unsupported module type!\n");
+		printk(KERN_NOTICE "Cannot adjust gain.  Unsupported module type!\n");
 		return -1;
 	}
 	if (tx) {
 		if (debug)
-			printk("setting FXO tx gain for card=%d to %d\n", card, gain);
+			printk(KERN_DEBUG "setting FXO tx gain for card=%d to %d\n", card, gain);
 		if (gain >=  -150 && gain <= 0) {
 			wctdm_setreg(wc, card, 38, 16 + (gain/-10));
 			wctdm_setreg(wc, card, 40, 16 + (-gain%10));
@@ -1685,12 +1750,12 @@
 			wctdm_setreg(wc, card, 38, gain/10);
 			wctdm_setreg(wc, card, 40, (gain%10));
 		} else {
-			printk("FXO tx gain is out of range (%d)\n", gain);
+			printk(KERN_INFO "FXO tx gain is out of range (%d)\n", gain);
 			return -1;
 		}
 	} else { /* rx */
 		if (debug)
-			printk("setting FXO rx gain for card=%d to %d\n", card, gain);
+			printk(KERN_DEBUG "setting FXO rx gain for card=%d to %d\n", card, gain);
 		if (gain >=  -150 && gain <= 0) {
 			wctdm_setreg(wc, card, 39, 16+ (gain/-10));
 			wctdm_setreg(wc, card, 41, 16 + (-gain%10));
@@ -1698,7 +1763,7 @@
 			wctdm_setreg(wc, card, 39, gain/10);
 			wctdm_setreg(wc, card, 41, (gain%10));
 		} else {
-			printk("FXO rx gain is out of range (%d)\n", gain);
+			printk(KERN_INFO "FXO rx gain is out of range (%d)\n", gain);
 			return -1;
 		}
 	}
@@ -1784,11 +1849,11 @@
 		wait_just_a_bit(HZ/10);
 
 	if (!(wctdm_getreg(wc, card, 11) & 0xf0)) {
-		printk("VoiceDAA did not bring up ISO link properly!\n");
+		printk(KERN_NOTICE "VoiceDAA did not bring up ISO link properly!\n");
 		return -1;
 	}
 	if (debug)
-		printk("ISO-Cap is now up, line side: %02x rev %02x\n", 
+		printk(KERN_DEBUG "ISO-Cap is now up, line side: %02x rev %02x\n", 
 		       wctdm_getreg(wc, card, 11) >> 4,
 		       (wctdm_getreg(wc, card, 13) >> 2) & 0xf);
 	/* Enable on-hook line monitor */
@@ -1800,17 +1865,14 @@
 
 	/* NZ -- crank the tx gain up by 7 dB */
 	if (!strcmp(fxo_modes[_opermode].name, "NEWZEALAND")) {
-		printk("Adjusting gain\n");
+		printk(KERN_INFO "Adjusting gain\n");
 		wctdm_set_hwgain(wc, card, 7, 1);
 	}
 
 	if(debug)
-		printk("DEBUG fxotxgain:%i.%i fxorxgain:%i.%i\n", (wctdm_getreg(wc, card, 38)/16)?-(wctdm_getreg(wc, card, 38) - 16) : wctdm_getreg(wc, card, 38), (wctdm_getreg(wc, card, 40)/16)? -(wctdm_getreg(wc, card, 40) - 16):wctdm_getreg(wc, card, 40), (wctdm_getreg(wc, card, 39)/16)? -(wctdm_getreg(wc, card, 39) - 16) : wctdm_getreg(wc, card, 39),(wctdm_getreg(wc, card, 41)/16)?-(wctdm_getreg(wc, card, 41) - 16):wctdm_getreg(wc, card, 41));
-
-	/* battery state still unknown */
-	wc->mod[card].fxo.battery = -1;
-
-	return 0;
+		printk(KERN_DEBUG "DEBUG fxotxgain:%i.%i fxorxgain:%i.%i\n", (wctdm_getreg(wc, card, 38)/16)?-(wctdm_getreg(wc, card, 38) - 16) : wctdm_getreg(wc, card, 38), (wctdm_getreg(wc, card, 40)/16)? -(wctdm_getreg(wc, card, 40) - 16):wctdm_getreg(wc, card, 40), (wctdm_getreg(wc, card, 39)/16)? -(wctdm_getreg(wc, card, 39) - 16) : wctdm_getreg(wc, card, 39),(wctdm_getreg(wc, card, 41)/16)?-(wctdm_getreg(wc, card, 41) - 16):wctdm_getreg(wc, card, 41));
+
+    return 0;
 		
 }
 
@@ -1868,7 +1930,7 @@
 
 	/* Power up the DC-DC converter */
 	if (wctdm_powerup_proslic(wc, card, fast)) {
-		printk("Unable to do INITIAL ProSLIC powerup on module %d\n", card);
+		printk(KERN_NOTICE "Unable to do INITIAL ProSLIC powerup on module %d\n", card);
 		return -1;
 	}
 
@@ -1876,40 +1938,40 @@
 
 		/* Check for power leaks */
 		if (wctdm_proslic_powerleak_test(wc, card)) {
-			printk("ProSLIC module %d failed leakage test.  Check for short circuit\n", card);
+			printk(KERN_NOTICE "ProSLIC module %d failed leakage test.  Check for short circuit\n", card);
 		}
 		/* Power up again */
 		if (wctdm_powerup_proslic(wc, card, fast)) {
-			printk("Unable to do FINAL ProSLIC powerup on module %d\n", card);
+			printk(KERN_NOTICE "Unable to do FINAL ProSLIC powerup on module %d\n", card);
 			return -1;
 		}
 #ifndef NO_CALIBRATION
 		/* Perform calibration */
 		if(manual) {
 			if (wctdm_proslic_manual_calibrate(wc, card)) {
-				//printk("Proslic failed on Manual Calibration\n");
+				//printk(KERN_NOTICE "Proslic failed on Manual Calibration\n");
 				if (wctdm_proslic_manual_calibrate(wc, card)) {
-					printk("Proslic Failed on Second Attempt to Calibrate Manually. (Try -DNO_CALIBRATION in Makefile)\n");
+					printk(KERN_NOTICE "Proslic Failed on Second Attempt to Calibrate Manually. (Try -DNO_CALIBRATION in Makefile)\n");
 					return -1;
 				}
-				printk("Proslic Passed Manual Calibration on Second Attempt\n");
+				printk(KERN_NOTICE "Proslic Passed Manual Calibration on Second Attempt\n");
 			}
 		}
 		else {
 			if(wctdm_proslic_calibrate(wc, card))  {
-				//printk("ProSlic died on Auto Calibration.\n");
+				//printk(KERN_NOTICE "ProSlic died on Auto Calibration.\n");
 				if (wctdm_proslic_calibrate(wc, card)) {
-					printk("Proslic Failed on Second Attempt to Auto Calibrate\n");
+					printk(KERN_NOTICE "Proslic Failed on Second Attempt to Auto Calibrate\n");
 					return -1;
 				}
-				printk("Proslic Passed Auto Calibration on Second Attempt\n");
+				printk(KERN_NOTICE "Proslic Passed Auto Calibration on Second Attempt\n");
 			}
 		}
 		/* Perform DC-DC calibration */
 		wctdm_setreg(wc, card, 93, 0x99);
 		r19 = wctdm_getreg(wc, card, 107);
 		if ((r19 < 0x2) || (r19 > 0xd)) {
-			printk("DC-DC cal has a surprising direct 107 of 0x%02x!\n", r19);
+			printk(KERN_NOTICE "DC-DC cal has a surprising direct 107 of 0x%02x!\n", r19);
 			wctdm_setreg(wc, card, 107, 0x8);
 		}
 
@@ -1994,24 +2056,24 @@
 			wctdm_setreg(wc, card, 74, 0x3f);
 			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x247)) 
 				return -1;
-			printk("Boosting fast ringer on slot %d (89V peak)\n", card + 1);
+			printk(KERN_INFO  "Boosting fast ringer on slot %d (89V peak)\n", card + 1);
 		} else if (lowpower) {
 			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x14b)) 
 				return -1;
-			printk("Reducing fast ring power on slot %d (50V peak)\n", card + 1);
+			printk(KERN_INFO  "Reducing fast ring power on slot %d (50V peak)\n", card + 1);
 		} else
-			printk("Speeding up ringer on slot %d (25Hz)\n", card + 1);
+			printk(KERN_INFO  "Speeding up ringer on slot %d (25Hz)\n", card + 1);
 	} else {
 		/* Beef up Ringing voltage to 89V */
 		if (boostringer) {
 			wctdm_setreg(wc, card, 74, 0x3f);
 			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x1d1)) 
 				return -1;
-			printk("Boosting ringer on slot %d (89V peak)\n", card + 1);
+			printk(KERN_INFO  "Boosting ringer on slot %d (89V peak)\n", card + 1);
 		} else if (lowpower) {
 			if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x108)) 
 				return -1;
-			printk("Reducing ring power on slot %d (50V peak)\n", card + 1);
+			printk(KERN_INFO  "Reducing ring power on slot %d (50V peak)\n", card + 1);
 		}
 	}
 
@@ -2044,7 +2106,7 @@
 	}
 
 	if(debug)
-		printk("DEBUG: fxstxgain:%s fxsrxgain:%s\n",((wctdm_getreg(wc, card, 9)/8) == 1)?"3.5":(((wctdm_getreg(wc,card,9)/4) == 1)?"-3.5":"0.0"),((wctdm_getreg(wc, card, 9)/2) == 1)?"3.5":((wctdm_getreg(wc,card,9)%2)?"-3.5":"0.0"));
+		printk(KERN_DEBUG "DEBUG: fxstxgain:%s fxsrxgain:%s\n",((wctdm_getreg(wc, card, 9)/8) == 1)?"3.5":(((wctdm_getreg(wc,card,9)/4) == 1)?"-3.5":"0.0"),((wctdm_getreg(wc, card, 9)/2) == 1)?"3.5":((wctdm_getreg(wc,card,9)%2)?"-3.5":"0.0"));
 
 	wctdm_setreg(wc, card, 64, 0x01);
 	return 0;
@@ -2064,7 +2126,7 @@
 	case DAHDI_ONHOOKTRANSFER:
 		if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
 			return -EINVAL;
-		if (get_user(x, (int *)data))
+		if (get_user(x, (__user  int *)data))
 			return -EFAULT;
 		wc->mod[chan->chanpos - 1].fxs.ohttimer = x << 3;
 		if (reversepolarity)
@@ -2081,7 +2143,7 @@
 		}
 		break;
 	case DAHDI_SETPOLARITY:
-		if (get_user(x, (int *)data))
+		if (get_user(x, (__user int *)data))
 			return -EFAULT;
 		if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
 			return -EINVAL;
@@ -2107,7 +2169,7 @@
 			stats.batvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000;
 		} else 
 			return -EINVAL;
-		if (copy_to_user((struct wctdm_stats *)data, &stats, sizeof(stats)))
+		if (copy_to_user((__user void *)data, &stats, sizeof(stats)))
 			return -EFAULT;
 		break;
 	case WCTDM_GET_REGS:
@@ -2121,26 +2183,26 @@
 			for (x=0;x<NUM_FXO_REGS;x++)
 				regs.direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x);
 		}
-		if (copy_to_user((struct wctdm_regs *)data, &regs, sizeof(regs)))
+		if (copy_to_user((__user void *)data, &regs, sizeof(regs)))
 			return -EFAULT;
 		break;
 	case WCTDM_SET_REG:
-		if (copy_from_user(&regop, (struct wctdm_regop *)data, sizeof(regop)))
+		if (copy_from_user(&regop, (__user void *)data, sizeof(regop)))
 			return -EFAULT;
 		if (regop.indirect) {
 			if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
 				return -EINVAL;
-			printk("Setting indirect %d to 0x%04x on %d\n", regop.reg, regop.val, chan->chanpos);
+			printk(KERN_INFO  "Setting indirect %d to 0x%04x on %d\n", regop.reg, regop.val, chan->chanpos);
 			wctdm_proslic_setreg_indirect(wc, chan->chanpos - 1, regop.reg, regop.val);
 		} else {
 			regop.val &= 0xff;
-			printk("Setting direct %d to %04x on %d\n", regop.reg, regop.val, chan->chanpos);
+			printk(KERN_INFO  "Setting direct %d to %04x on %d\n", regop.reg, regop.val, chan->chanpos);
 			wctdm_setreg(wc, chan->chanpos - 1, regop.reg, regop.val);
 		}
 		break;
 	case WCTDM_SET_ECHOTUNE:
-		printk("-- Setting echo registers: \n");
-		if (copy_from_user(&echoregs, (struct wctdm_echo_coefs*)data, sizeof(echoregs)))
+		printk(KERN_INFO  "-- Setting echo registers: \n");
+		if (copy_from_user(&echoregs, (__user void *)data, sizeof(echoregs)))
 			return -EFAULT;
 
 		if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
@@ -2157,7 +2219,7 @@
 			wctdm_setreg(wc, chan->chanpos - 1, 51, echoregs.coef7);
 			wctdm_setreg(wc, chan->chanpos - 1, 52, echoregs.coef8);
 
-			printk("-- Set echo registers successfully\n");
+			printk(KERN_INFO  "-- Set echo registers successfully\n");
 
 			break;
 		} else {
@@ -2166,13 +2228,13 @@
 		}
 		break;
 	case DAHDI_SET_HWGAIN:
-		if (copy_from_user(&hwgain, (struct dahdi_hwgain*) data, sizeof(hwgain)))
+		if (copy_from_user(&hwgain, (__user void *) data, sizeof(hwgain)))
 			return -EFAULT;
 
 		wctdm_set_hwgain(wc, chan->chanpos-1, hwgain.newgain, hwgain.tx);
 
 		if (debug)
-			printk("Setting hwgain on channel %d to %d for %s direction\n", 
+			printk(KERN_DEBUG  "Setting hwgain on channel %d to %d for %s direction\n", 
 				chan->chanpos-1, hwgain.newgain, hwgain.tx ? "tx" : "rx");
 		break;
 	default:
@@ -2198,7 +2260,7 @@
 
 static int wctdm_watchdog(struct dahdi_span *span, int event)
 {
-	printk("opvxa1200: Restarting DMA\n");
+	printk(KERN_INFO "opvxa1200: Restarting DMA\n");
 	wctdm_restart_dma(span->pvt);
 	return 0;
 }
@@ -2247,7 +2309,7 @@
 			wctdm_setreg(wc, chan->chanpos - 1, 5, 0x8);
 			break;
 		default:
-			printk("wcfxo: Can't set tx state to %d\n", txsig);
+			printk(KERN_NOTICE "wcfxo: Can't set tx state to %d\n", txsig);
 		}
 	} else {
 		switch(txsig) {
@@ -2280,10 +2342,10 @@
 			wc->mod[chan->chanpos-1].fxs.lasttxhook = 0;
 			break;
 		default:
-			printk("opvxa1200: Can't set tx state to %d\n", txsig);
+			printk(KERN_NOTICE "opvxa1200: Can't set tx state to %d\n", txsig);
 		}
 		if (debug)
-			printk("Setting FXS hook state to %d (%02x)\n", txsig, reg);
+			printk(KERN_DEBUG "Setting FXS hook state to %d (%02x)\n", txsig, reg);
 
 #if 1
 		wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos-1].fxs.lasttxhook);
@@ -2296,15 +2358,15 @@
 {
 	int x;
 
-	/* Zapata stuff */
+	/* Dahdi stuff */
 	sprintf(wc->span.name, "OPVXA1200/%d", wc->pos);
 	snprintf(wc->span.desc, sizeof(wc->span.desc)-1, "%s Board %d", wc->variety, wc->pos + 1);
 	snprintf(wc->span.location, sizeof(wc->span.location) - 1,
 		 "PCI Bus %02d Slot %02d", wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
 	wc->span.manufacturer = "OpenVox";
-	strncpy(wc->span.devicetype, wc->variety, sizeof(wc->span.devicetype) - 1);
+	dahdi_copy_string(wc->span.devicetype, wc->variety, sizeof(wc->span.devicetype));
 	if (alawoverride) {
-		printk("ALAW override parameter detected.  Device will be operating in ALAW\n");
+		printk(KERN_INFO "ALAW override parameter detected.  Device will be operating in ALAW\n");
 		wc->span.deflaw = DAHDI_LAW_ALAW;
 	} else
 		wc->span.deflaw = DAHDI_LAW_MULAW;
@@ -2342,7 +2404,7 @@
 
 	wc->span.pvt = wc;
 	if (dahdi_register(&wc->span, 0)) {
-		printk("Unable to register span with zaptel\n");
+		printk(KERN_NOTICE "Unable to register span with Dahdi\n");
 		return -1;
 	}
 	return 0;
@@ -2387,7 +2449,7 @@
 			break;;
 	}
 
-	printk("after raise reset\n");*/
+	printk(KERN_INFO "after raise reset\n");*/
 
 	/* Check OpenVox chip */
 	x=inb(wc->ioaddr + WC_CNTL);
@@ -2403,7 +2465,7 @@
 		wc->card_name = A1200P_Name;
 		wc->max_cards = 12;
 	}*/
-	printk("OpenVox %s version: %01x.%01x\n", wc->card_name, (ver&(~FLAG_A800))>>4, ver&0x0f);
+	printk(KERN_NOTICE "OpenVox %s version: %01x.%01x\n", wc->card_name, (ver&(~FLAG_A800))>>4, ver&0x0f);
 	
 	failed = 0;
 	if (ver != 0x00) {
@@ -2412,19 +2474,19 @@
 			__wctdm_setcreg(wc, WC_CS, x);
 			y = __wctdm_getcreg(wc, WC_CS) & 0x0f;
 			if (x != y) {
-				printk("%02x != %02x\n", x, y);
+				printk(KERN_INFO "%02x != %02x\n", x, y);
 				failed++;
 			}
 		}
 
 		if (!failed) {
-			printk("OpenVox %s passed register test\n", wc->card_name);
+			printk(KERN_INFO "OpenVox %s passed register test\n", wc->card_name);
 		} else {
-			printk("OpenVox %s failed register test\n", wc->card_name);
+			printk(KERN_NOTICE "OpenVox %s failed register test\n", wc->card_name);
 			return -1;
 		}
 	} else {
-		printk("No OpenVox chip %02x\n", ver);
+		printk(KERN_INFO "No OpenVox chip %02x\n", ver);
 	}
 
 	if (spibyhw)
@@ -2480,6 +2542,7 @@
 	for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
 		int sane=0,ret=0,readi=0;
 #if 1
+		touch_softlockup_watchdog();  // avoid showing CPU softlock message
 		/* Init with Auto Calibration */
 		if (!(ret=wctdm_init_proslic(wc, x, 0, 0, sane))) {
 			wc->cardflag |= (1 << x);
@@ -2488,13 +2551,13 @@
                                 printk("Proslic module %d loop current is %dmA\n",x,
                                 ((readi*3)+20));
                         }
-			printk("Module %d: Installed -- AUTO FXS/DPO\n",x);
+			printk(KERN_INFO "Module %d: Installed -- AUTO FXS/DPO\n",x);
 			wctdm_set_led(wc, (unsigned int)x, 1);
 		} else {
 			if(ret!=-2) {
 				sane=1;
 				
-				printk("Init ProSlic with Manual Calibration \n");
+				printk(KERN_INFO "Init ProSlic with Manual Calibration \n");
 				/* Init with Manual Calibration */
 				if (!wctdm_init_proslic(wc, x, 0, 1, sane)) {
 					wc->cardflag |= (1 << x);
@@ -2503,17 +2566,17 @@
                                         printk("Proslic module %d loop current is %dmA\n",x,
                                         ((readi*3)+20));
                                 }
-					printk("Module %d: Installed -- MANUAL FXS\n",x);
+					printk(KERN_INFO "Module %d: Installed -- MANUAL FXS\n",x);
 				} else {
-					printk("Module %d: FAILED FXS (%s)\n", x, fxshonormode ? fxo_modes[_opermode].name : "FCC");
+					printk(KERN_NOTICE "Module %d: FAILED FXS (%s)\n", x, fxshonormode ? fxo_modes[_opermode].name : "FCC");
 					wc->chans[x]->sigcap = __DAHDI_SIG_FXO | DAHDI_SIG_BROKEN;
 				} 
 			} else if (!(ret = wctdm_init_voicedaa(wc, x, 0, 0, sane))) {
 				wc->cardflag |= (1 << x);
-				printk("Module %d: Installed -- AUTO FXO (%s mode)\n",x, fxo_modes[_opermode].name);
+				printk(KERN_INFO "Module %d: Installed -- AUTO FXO (%s mode)\n",x, fxo_modes[_opermode].name);
 				wctdm_set_led(wc, (unsigned int)x, 1);
 			} else
-				printk("Module %d: Not installed\n", x);
+				printk(KERN_NOTICE "Module %d: Not installed\n", x);
 		}
 #endif
 	}
@@ -2587,7 +2650,7 @@
 	for (x=0;x<WC_MAX_IFACES;x++)
 		if (!ifaces[x]) break;
 	if (x >= WC_MAX_IFACES) {
-		printk("Too many interfaces\n");
+		printk(KERN_NOTICE "Too many interfaces\n");
 		return -EIO;
 	}
 	
@@ -2631,7 +2694,7 @@
 			   8 bits.  */
 			wc->writechunk = pci_alloc_consistent(pdev, DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, &wc->writedma);
 			if (!wc->writechunk) {
-				printk("opvxa1200: Unable to allocate DMA-able memory\n");
+				printk(KERN_NOTICE "opvxa1200: Unable to allocate DMA-able memory\n");
 				if (wc->freeregion & 0x01)
 					release_region(wc->ioaddr, 0xff);
 				if (wc->freeregion & 0x02)
@@ -2646,7 +2709,7 @@
 			wc->readdma = wc->writedma + DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2;	/* in bytes */
 			
 			if (wctdm_initialize(wc)) {
-				printk("opvxa1200: Unable to intialize FXS\n");
+				printk(KERN_NOTICE "opvxa1200: Unable to intialize FXS\n");
 				/* Set Reset Low */
 				x=inb(wc->ioaddr + WC_CNTL);
 				outb((~0x1)&x, wc->ioaddr + WC_CNTL);
@@ -2669,7 +2732,7 @@
 
 
 			if (request_irq(pdev->irq, wctdm_interrupt, DAHDI_IRQ_SHARED, "opvxa1200", wc)) {
-				printk("opvxa1200: Unable to request IRQ %d\n", pdev->irq);
+				printk(KERN_NOTICE "opvxa1200: Unable to request IRQ %d\n", pdev->irq);
 				if (wc->freeregion & 0x01)
 					release_region(wc->ioaddr, 0xff);
 				if (wc->freeregion & 0x02)
@@ -2743,9 +2806,9 @@
 					cardcount++;
 			}
 
-			printk("Found aa OpenVox %s: Version %x.%x (%d modules)\n", wc->card_name, (wc->fwversion&(~FLAG_A800))>>4, wc->fwversion&0x0f, cardcount);
+			printk(KERN_INFO "Found an OpenVox %s: Version %x.%x (%d modules)\n", wc->card_name, (wc->fwversion&(~FLAG_A800))>>4, wc->fwversion&0x0f, cardcount);
 			if(debug)
-				printk("OpenVox %s debug On\n", wc->card_name);
+				printk(KERN_DEBUG "OpenVox %s debug On\n", wc->card_name);
 			
 			res = 0;
 		} else
@@ -2808,7 +2871,7 @@
 	}
  
 	kfree(wc);
-	printk("Freed a OpenVox A1200 card\n");
+	printk(KERN_INFO "Freed a OpenVox A1200 card\n");
 }
 
 static void __devexit wctdm_remove_one(struct pci_dev *pdev)
@@ -2852,18 +2915,19 @@
 	{ 0xe159, 0x0001, 0x9532, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme }, 
 	{ 0xe159, 0x0001, 0x8519, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
 	{ 0xe159, 0x0001, 0x9559, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
+	{ 0xe159, 0x0001, 0x9599, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
 	{ 0 }
 };
 
 MODULE_DEVICE_TABLE(pci, wctdm_pci_tbl);
 
 static struct pci_driver wctdm_driver = {
-	name: 	"opvxa1200",
-	probe: 	wctdm_init_one,
-	remove:	__devexit_p(wctdm_remove_one),
-	suspend: NULL,
-	resume:	NULL,
-	id_table: wctdm_pci_tbl,
+	.name = "opvxa1200",
+	.probe =	wctdm_init_one,
+	.remove =	__devexit_p(wctdm_remove_one),
+	.suspend = NULL,
+	.resume =	NULL,
+	.id_table = wctdm_pci_tbl,
 };
 
 static int __init wctdm_init(void)
@@ -2877,15 +2941,24 @@
 	if (x < sizeof(fxo_modes) / sizeof(fxo_modes[0])) {
 		_opermode = x;
 	} else {
-		printk("Invalid/unknown operating mode '%s' specified.  Please choose one of:\n", opermode);
+		printk(KERN_NOTICE "Invalid/unknown operating mode '%s' specified.  Please choose one of:\n", opermode);
 		for (x=0;x<sizeof(fxo_modes) / sizeof(fxo_modes[0]); x++)
-			printk("  %s\n", fxo_modes[x].name);
-		printk("Note this option is CASE SENSITIVE!\n");
+			printk(KERN_INFO "  %s\n", fxo_modes[x].name);
+		printk(KERN_INFO "Note this option is CASE SENSITIVE!\n");
 		return -ENODEV;
 	}
 	if (!strcmp(fxo_modes[_opermode].name, "AUSTRALIA")) {
 		boostringer=1;
 		fxshonormode=1;
+}
+	if (battdebounce == 0) {
+		battdebounce = fxo_modes[_opermode].battdebounce;
+	}
+	if (battalarm == 0) {
+		battalarm = fxo_modes[_opermode].battalarm;
+	}
+	if (battthresh == 0) {
+		battthresh = fxo_modes[_opermode].battthresh;
 	}
 
 	res = dahdi_pci_module(&wctdm_driver);
@@ -2903,15 +2976,15 @@
 module_param(loopcurrent, int, 0600);
 module_param(reversepolarity, int, 0600);
 module_param(robust, int, 0600);
-module_param(_opermode, int, 0600);
 module_param(opermode, charp, 0600);
 module_param(timingonly, int, 0600);
 module_param(lowpower, int, 0600);
 module_param(boostringer, int, 0600);
 module_param(fastringer, int, 0600);
 module_param(fxshonormode, int, 0600);
-module_param(battdebounce, int, 0600);
-module_param(battthresh, int, 0600);
+module_param(battdebounce, uint, 0600);
+module_param(battthresh, uint, 0600);
+module_param(battalarm, uint, 0600);
 module_param(ringdebounce, int, 0600);
 module_param(fwringdetect, int, 0600);
 module_param(alawoverride, int, 0600);
@@ -2926,7 +2999,7 @@
 module_param(cidbuflen, int, 0600);
 module_param(cidtimeout, int, 0600);
 module_param(fxofullscale, int, 0600);
-
+module_param(fixedtimepolarity, int, 0600);
 
 MODULE_DESCRIPTION("OpenVox A1200 Driver");
 MODULE_AUTHOR("MiaoLin <miaolin at openvox.com.cn>");




More information about the Pkg-voip-commits mailing list