summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-04-28 19:13:00 +0000
committermattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-04-28 19:13:00 +0000
commite938a478184e67088fc89ce03838929f4112e40b (patch)
tree72a6b484598392696714478f49c672f15e87e0f7
parenteea65b8209e3b57ad413a4af3cfb6766225467f4 (diff)
Merged revisions 2465 via svnmerge from
https://origsvn.digium.com/svn/zaptel/branches/1.4 ................ r2465 | mattf | 2007-04-28 14:11:20 -0500 (Sat, 28 Apr 2007) | 10 lines Merged revisions 2464 via svnmerge from https://origsvn.digium.com/svn/zaptel/branches/1.2 ........ r2464 | mattf | 2007-04-28 14:04:50 -0500 (Sat, 28 Apr 2007) | 2 lines Fix for potential deadlock in drivers ........ ................ git-svn-id: http://svn.digium.com/svn/zaptel/trunk@2466 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rw-r--r--wcte11xp.c72
1 files changed, 56 insertions, 16 deletions
diff --git a/wcte11xp.c b/wcte11xp.c
index 78537ed..e417be7 100644
--- a/wcte11xp.c
+++ b/wcte11xp.c
@@ -561,24 +561,35 @@ static int t1xxp_rbsbits(struct zt_chan *chan, int bits)
return 0;
}
-static void __t1_check_sigbits(struct t1 *wc)
+static void t1_check_sigbits(struct t1 *wc)
{
int a,i,rxs;
+ unsigned long flags;
+
if (!(wc->span.flags & ZT_FLAG_RUNNING))
return;
+
+ spin_lock_irqsave(&wc->lock, flags);
+
if (wc->spantype == TYPE_E1) {
for (i = 0; i < 15; i++) {
a = __t1_framer_in(wc, 0x71 + i);
/* Get high channel in low bits */
rxs = (a & 0xf);
if (!(wc->span.chans[i+16].sig & ZT_SIG_CLEAR)) {
- if (wc->span.chans[i+16].rxsig != rxs)
+ if (wc->span.chans[i+16].rxsig != rxs) {
+ spin_unlock_irqrestore(&wc->lock, flags);
zt_rbsbits(&wc->span.chans[i+16], rxs);
+ spin_lock_irqsave(&wc->lock, flags);
+ }
}
rxs = (a >> 4) & 0xf;
if (!(wc->span.chans[i].sig & ZT_SIG_CLEAR)) {
- if (wc->span.chans[i].rxsig != rxs)
+ if (wc->span.chans[i].rxsig != rxs) {
+ spin_unlock_irqrestore(&wc->lock, flags);
zt_rbsbits(&wc->span.chans[i], rxs);
+ spin_lock_irqsave(&wc->lock, flags);
+ }
}
}
} else if (wc->span.lineconfig & ZT_CONFIG_D4) {
@@ -587,23 +598,35 @@ static void __t1_check_sigbits(struct t1 *wc)
/* Get high channel in low bits */
rxs = (a & 0x3) << 2;
if (!(wc->span.chans[i+3].sig & ZT_SIG_CLEAR)) {
- if (wc->span.chans[i+3].rxsig != rxs)
+ if (wc->span.chans[i+3].rxsig != rxs) {
+ spin_unlock_irqrestore(&wc->lock, flags);
zt_rbsbits(&wc->span.chans[i+3], rxs);
+ spin_lock_irqsave(&wc->lock, flags);
+ }
}
rxs = (a & 0xc);
if (!(wc->span.chans[i+2].sig & ZT_SIG_CLEAR)) {
- if (wc->span.chans[i+2].rxsig != rxs)
+ if (wc->span.chans[i+2].rxsig != rxs) {
+ spin_unlock_irqrestore(&wc->lock, flags);
zt_rbsbits(&wc->span.chans[i+2], rxs);
+ spin_lock_irqsave(&wc->lock, flags);
+ }
}
rxs = (a >> 2) & 0xc;
if (!(wc->span.chans[i+1].sig & ZT_SIG_CLEAR)) {
- if (wc->span.chans[i+1].rxsig != rxs)
+ if (wc->span.chans[i+1].rxsig != rxs) {
+ spin_unlock_irqrestore(&wc->lock, flags);
zt_rbsbits(&wc->span.chans[i+1], rxs);
+ spin_lock_irqsave(&wc->lock, flags);
+ }
}
rxs = (a >> 4) & 0xc;
if (!(wc->span.chans[i].sig & ZT_SIG_CLEAR)) {
- if (wc->span.chans[i].rxsig != rxs)
+ if (wc->span.chans[i].rxsig != rxs) {
+ spin_unlock_irqrestore(&wc->lock, flags);
zt_rbsbits(&wc->span.chans[i], rxs);
+ spin_lock_irqsave(&wc->lock, flags);
+ }
}
}
} else {
@@ -612,16 +635,23 @@ static void __t1_check_sigbits(struct t1 *wc)
/* Get high channel in low bits */
rxs = (a & 0xf);
if (!(wc->span.chans[i+1].sig & ZT_SIG_CLEAR)) {
- if (wc->span.chans[i+1].rxsig != rxs)
+ if (wc->span.chans[i+1].rxsig != rxs) {
+ spin_unlock_irqrestore(&wc->lock, flags);
zt_rbsbits(&wc->span.chans[i+1], rxs);
+ spin_lock_irqsave(&wc->lock, flags);
+ }
}
rxs = (a >> 4) & 0xf;
if (!(wc->span.chans[i].sig & ZT_SIG_CLEAR)) {
- if (wc->span.chans[i].rxsig != rxs)
+ if (wc->span.chans[i].rxsig != rxs) {
+ spin_unlock_irqrestore(&wc->lock, flags);
zt_rbsbits(&wc->span.chans[i], rxs);
+ spin_lock_irqsave(&wc->lock, flags);
+ }
}
}
}
+ spin_unlock_irqrestore(&wc->lock, flags);
}
static void t4_serial_setup(struct t1 *wc)
@@ -1145,15 +1175,18 @@ static void t1xxp_receiveprep(struct t1 *wc, int ints)
zt_receive(&wc->span);
}
-static void __t1_check_alarms(struct t1 *wc)
+static void t1_check_alarms(struct t1 *wc)
{
unsigned char c,d;
int alarms;
int x,j;
+ unsigned long flags;
if (!(wc->span.flags & ZT_FLAG_RUNNING))
return;
+ spin_lock_irqsave(&wc->lock, flags);
+
c = __t1_framer_in(wc, 0x4c);
if (wc->spanflags & FLAG_FALC12)
d = __t1_framer_in(wc, 0x4f);
@@ -1267,18 +1300,25 @@ static void __t1_check_alarms(struct t1 *wc)
if (wc->span.mainttimer || wc->span.maintstat)
alarms |= ZT_ALARM_LOOPBACK;
wc->span.alarms = alarms;
+ spin_unlock_irqrestore(&wc->lock, flags);
zt_alarm_notify(&wc->span);
}
-static void __t1_do_counters(struct t1 *wc)
+static void t1_do_counters(struct t1 *wc)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&wc->lock, flags);
if (wc->alarmtimer) {
if (!--wc->alarmtimer) {
wc->span.alarms &= ~(ZT_ALARM_RECOVER);
+ spin_unlock_irqrestore(&wc->lock, flags);
zt_alarm_notify(&wc->span);
+ spin_lock_irqsave(&wc->lock, flags);
}
}
+ spin_unlock_irqrestore(&wc->lock, flags);
}
ZAP_IRQ_HANDLER(t1xxp_interrupt)
@@ -1316,8 +1356,10 @@ ZAP_IRQ_HANDLER(t1xxp_interrupt)
__handle_leds(wc);
#endif
+ spin_unlock_irqrestore(&wc->lock, flags);
+
/* Count down timers */
- __t1_do_counters(wc);
+ t1_do_counters(wc);
/* Do some things that we don't have to do very often */
x = wc->intcount & 15 /* 63 */;
@@ -1326,17 +1368,15 @@ ZAP_IRQ_HANDLER(t1xxp_interrupt)
case 1:
break;
case 2:
- __t1_check_sigbits(wc);
+ t1_check_sigbits(wc);
break;
case 4:
/* Check alarms 1/4 as frequently */
if (!(wc->intcount & 0x30))
- __t1_check_alarms(wc);
+ t1_check_alarms(wc);
break;
}
- spin_unlock_irqrestore(&wc->lock, flags);
-
if (ints & 0x10)
printk("PCI Master abort\n");