summaryrefslogtreecommitdiff
path: root/ztdynamic.c
diff options
context:
space:
mode:
authortilghman <tilghman@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-06-22 20:23:41 +0000
committertilghman <tilghman@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-06-22 20:23:41 +0000
commitdf2e8131e92f1967eb61fb443036fdf9491ce745 (patch)
treeff896c23081a2c04ef47d1be583c9c7e612e7fe0 /ztdynamic.c
parente7324ee365da30e9b7b18d6baaec5ae21de1894b (diff)
Bug 5126 - Fix for incompatiblities between the TDMo* drivers and the 2.6 kernel
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@1157 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'ztdynamic.c')
-rw-r--r--ztdynamic.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/ztdynamic.c b/ztdynamic.c
index f15799b..c2c86ad 100644
--- a/ztdynamic.c
+++ b/ztdynamic.c
@@ -132,6 +132,12 @@ static DEFINE_SPINLOCK(dlock);
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 @@ static void checkmaster(void)
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 @@ static void __ztdynamic_run(void)
{
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 @@ static void __ztdynamic_run(void)
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 @@ void zt_dynamic_receive(struct zt_span *span, unsigned char *msg, int msglen)
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 @@ void zt_dynamic_receive(struct zt_span *span, unsigned char *msg, int msglen)
master = ztd->master;
+ rxcnt = ztd->rxcnt;
+ ztd->rxcnt = rxpos+1;
+
spin_unlock_irqrestore(&dlock, flags);
/* Check for Yellow alarm */
@@ -388,6 +407,10 @@ void zt_dynamic_receive(struct zt_span *span, unsigned char *msg, int msglen)
/* 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)
ztdynamic_run();
@@ -715,14 +738,14 @@ int zt_dynamic_register(struct zt_dynamic_driver *dri)
{
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 @@ void zt_dynamic_unregister(struct zt_dynamic_driver *dri)
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 @@ void zt_dynamic_unregister(struct zt_dynamic_driver *dri)
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 @@ static void check_for_red_alarm(unsigned long ignored)
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;