diff options
author | tilghman <tilghman@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-06-22 20:23:41 +0000 |
---|---|---|
committer | tilghman <tilghman@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-06-22 20:23:41 +0000 |
commit | df2e8131e92f1967eb61fb443036fdf9491ce745 (patch) | |
tree | ff896c23081a2c04ef47d1be583c9c7e612e7fe0 /ztdynamic.c | |
parent | e7324ee365da30e9b7b18d6baaec5ae21de1894b (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.c | 55 |
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; |