[svn-commits] trunk r1157 - in /trunk: zaptel.h ztd-eth.c ztd-loc.c ztdynamic.c

svn-commits at lists.digium.com svn-commits at lists.digium.com
Thu Jun 22 13:23:42 MST 2006


Author: tilghman
Date: Thu Jun 22 15:23:41 2006
New Revision: 1157

URL: http://svn.digium.com/view/zaptel?rev=1157&view=rev
Log:
Bug 5126 - Fix for incompatiblities between the TDMo* drivers and the 2.6 kernel

Modified:
    trunk/zaptel.h
    trunk/ztd-eth.c
    trunk/ztd-loc.c
    trunk/ztdynamic.c

Modified: trunk/zaptel.h
URL: http://svn.digium.com/view/zaptel/trunk/zaptel.h?rev=1157&r1=1156&r2=1157&view=diff
==============================================================================
--- trunk/zaptel.h (original)
+++ trunk/zaptel.h Thu Jun 22 15:23:41 2006
@@ -1347,6 +1347,9 @@
 	/* Transmit a given message */
 	int (*transmit)(void *tpipe, unsigned char *msg, int msglen);
 
+	/* Flush any pending messages */
+	int (*flush)(void);
+
 	struct zt_dynamic_driver *next;
 };
 

Modified: trunk/ztd-eth.c
URL: http://svn.digium.com/view/zaptel/trunk/ztd-eth.c?rev=1157&r1=1156&r2=1157&view=diff
==============================================================================
--- trunk/ztd-eth.c (original)
+++ trunk/ztd-eth.c Thu Jun 22 15:23:41 2006
@@ -56,6 +56,8 @@
 static spinlock_t zlock = SPIN_LOCK_UNLOCKED;
 #endif
 
+static struct sk_buff_head skbs;
+
 static struct ztdeth {
 	unsigned char addr[ETH_ALEN];
 	unsigned short subaddr; /* Network byte order */
@@ -171,11 +173,23 @@
 			skb->dev = dev;
 			if (dev->hard_header)
 				dev->hard_header(skb, dev, ETH_P_ZTDETH, addr, dev->dev_addr, skb->len);
-			dev_queue_xmit(skb);
+			skb_queue_tail(&skbs, skb);
 		}
 	}
 	else
 		spin_unlock_irqrestore(&zlock, flags);
+	return 0;
+}
+
+
+static int ztdeth_flush(void)
+{
+	struct sk_buff *skb;
+
+	/* Handle all transmissions now */
+	while ((skb = skb_dequeue(&skbs))) {
+		dev_queue_xmit(skb);
+	}
 	return 0;
 }
 
@@ -381,7 +395,8 @@
 	"Ethernet",
 	ztdeth_create,
 	ztdeth_destroy,
-	ztdeth_transmit
+	ztdeth_transmit,
+	ztdeth_flush
 };
 
 static struct notifier_block ztdeth_nblock = {
@@ -393,6 +408,9 @@
 	dev_add_pack(&ztdeth_ptype);
 	register_netdevice_notifier(&ztdeth_nblock);
 	zt_dynamic_register(&ztd_eth);
+
+	skb_queue_head_init(&skbs);
+
 	return 0;
 }
 

Modified: trunk/ztd-loc.c
URL: http://svn.digium.com/view/zaptel/trunk/ztd-loc.c?rev=1157&r1=1156&r2=1157&view=diff
==============================================================================
--- trunk/ztd-loc.c (original)
+++ trunk/ztd-loc.c Thu Jun 22 15:23:41 2006
@@ -260,7 +260,8 @@
 	"Local",
 	ztdlocal_create,
 	ztdlocal_destroy,
-	ztdlocal_transmit
+	ztdlocal_transmit,
+	NULL	/* flush */
 };
 
 /*static*/ int __init ztdlocal_init(void)

Modified: trunk/ztdynamic.c
URL: http://svn.digium.com/view/zaptel/trunk/ztdynamic.c?rev=1157&r1=1156&r2=1157&view=diff
==============================================================================
--- trunk/ztdynamic.c (original)
+++ trunk/ztdynamic.c Thu Jun 22 15:23:41 2006
@@ -132,6 +132,12 @@
 static spinlock_t dlock = SPIN_LOCK_UNLOCKED;
 #endif
 
+#ifdef DEFINE_RWLOCK
+static DEFINE_RWLOCK(drvlock);
+#else
+static rwlock_t drvlock = RW_LOCK_UNLOCKED;
+#endif
+
 static void checkmaster(void)
 {
 	unsigned long flags;
@@ -142,15 +148,13 @@
 	z = dspans;
 	while(z) {
 		if (z->timing) {
-			if (z->timing) {
-				z->master = 0;
-				newhasmaster = 1;
-				if (!z->alarm && (z->timing < best) && !z->dead) {
-					/* If not in alarm and they're
-					   a better timing source, use them */
-					master = z;
-					best = z->timing;
-				}
+			z->master = 0;
+			newhasmaster = 1;
+			if (!z->alarm && (z->timing < best) && !z->dead) {
+				/* If not in alarm and they're
+				   a better timing source, use them */
+				master = z;
+				best = z->timing;
 			}
 		}
 		z = z->next;
@@ -230,6 +234,7 @@
 {
 	unsigned long flags;
 	struct zt_dynamic *z;
+	struct zt_dynamic_driver *drv;
 	int y;
 	spin_lock_irqsave(&dlock, flags);
 	z = dspans;
@@ -248,6 +253,17 @@
 		z = z->next;
 	}
 	spin_unlock_irqrestore(&dlock, flags);
+
+	read_lock(&drvlock);
+	drv = drivers;
+	while(drv) {
+		/* Flush any traffic still pending in the driver */
+		if (drv->flush) {
+			drv->flush();
+		}
+		drv = drv->next;
+	}
+	read_unlock(&drvlock);
 }
 
 #ifdef ENABLE_TASKLETS
@@ -275,7 +291,7 @@
 	int x, bits, sig;
 	int nchans, master;
 	int newalarm;
-	unsigned short rxpos;
+	unsigned short rxpos, rxcnt;
 	
 	
 	spin_lock_irqsave(&dlock, flags);
@@ -373,6 +389,9 @@
 
 	master = ztd->master;
 	
+	rxcnt = ztd->rxcnt;
+	ztd->rxcnt = rxpos+1;
+
 	spin_unlock_irqrestore(&dlock, flags);
 	
 	/* Check for Yellow alarm */
@@ -387,6 +406,10 @@
 	
 	/* Keep track of last received packet */
 	ztd->rxjif = jiffies;
+
+	/* note if we had a missing packet */
+	if (rxpos != rxcnt)
+		printk("Span %s: Expected seq no %d, but received %d instead\n", span->name, rxcnt, rxpos);
 
 	/* If this is our master span, then run everything */
 	if (master)
@@ -715,14 +738,14 @@
 {
 	unsigned long flags;
 	int res = 0;
-	spin_lock_irqsave(&dlock, flags);
+	write_lock_irqsave(&drvlock, flags);
 	if (find_driver(dri->name))
 		res = -1;
 	else {
 		dri->next = drivers;
 		drivers = dri;
 	}
-	spin_unlock_irqrestore(&dlock, flags);
+	write_unlock_irqrestore(&drvlock, flags);
 	return res;
 }
 
@@ -731,7 +754,7 @@
 	struct zt_dynamic_driver *cur, *prev=NULL;
 	struct zt_dynamic *z, *zp, *zn;
 	unsigned long flags;
-	spin_lock_irqsave(&dlock, flags);
+	write_lock_irqsave(&drvlock, flags);
 	cur = drivers;
 	while(cur) {
 		if (cur == dri) {
@@ -744,6 +767,8 @@
 		prev = cur;
 		cur = cur->next;
 	}
+	write_unlock_irqrestore(&drvlock, flags);
+	spin_lock_irqsave(&dlock, flags);
 	z = dspans;
 	zp = NULL;
 	while(z) {
@@ -778,8 +803,8 @@
 	z = dspans;
 	while(z) {
 		newalarm = z->span.alarms & ~ZT_ALARM_RED;
-		/* If nothing received for a minute, consider that RED ALARM */
-		if ((jiffies - z->rxjif) > 1000 / HZ) {
+		/* If nothing received for a second, consider that RED ALARM */
+		if ((jiffies - z->rxjif) > 1 * HZ) {
 			newalarm |= ZT_ALARM_RED;
 			if (z->span.alarms != newalarm) {
 				z->span.alarms = newalarm;



More information about the svn-commits mailing list