[zaptel-commits] trunk r1157 - in /trunk: zaptel.h ztd-eth.c
ztd-loc.c ztdynamic.c
zaptel-commits at lists.digium.com
zaptel-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 zaptel-commits
mailing list