summaryrefslogtreecommitdiff
path: root/wcte12xp
diff options
context:
space:
mode:
authorsruffell <sruffell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-01-04 22:54:10 +0000
committersruffell <sruffell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-01-04 22:54:10 +0000
commit2692248a15a57abf559b72d2445eca72e59542ee (patch)
tree07fdaa3173c1a3f8e92793343a294c0bf663713c /wcte12xp
parent862da09752d1361a91f9318f90314ac0353f5e90 (diff)
Increase the amount of code that is protected by locks in the wcte12xp interrupt handler.
git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@3618 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wcte12xp')
-rw-r--r--wcte12xp/base.c92
-rw-r--r--wcte12xp/vpmadt032.c7
2 files changed, 63 insertions, 36 deletions
diff --git a/wcte12xp/base.c b/wcte12xp/base.c
index eb9ea6a..d3e7789 100644
--- a/wcte12xp/base.c
+++ b/wcte12xp/base.c
@@ -220,7 +220,6 @@ static inline void cmd_dequeue(struct t1 *wc, volatile unsigned char *writechunk
/* Skip audio */
writechunk += 66;
- spin_lock_irqsave(&wc->reglock, flags);
/* Search for something waiting to transmit */
if ((slot < 6) && (eframe) && (eframe < ZT_CHUNKSIZE - 1)) {
/* only 6 useable cs slots per */
@@ -255,7 +254,6 @@ static inline void cmd_dequeue(struct t1 *wc, volatile unsigned char *writechunk
writechunk[CMD_BYTE(slot,2,0)] = curcmd->data;
}
- spin_unlock_irqrestore(&wc->reglock, flags);
}
static inline void cmd_decipher(struct t1 *wc, volatile unsigned char *readchunk)
@@ -267,7 +265,6 @@ static inline void cmd_decipher(struct t1 *wc, volatile unsigned char *readchunk
/* Skip audio */
readchunk += 66;
- spin_lock_irqsave(&wc->reglock, flags);
/* Search for any pending results */
for (x = 0; x < sizeof(wc->cmdq.cmds) / sizeof(wc->cmdq.cmds[0]); x++) {
if ((wc->cmdq.cmds[x].flags & (__CMD_RD | __CMD_WR | __CMD_LEDS | __CMD_PINS)) &&
@@ -287,7 +284,6 @@ static inline void cmd_decipher(struct t1 *wc, volatile unsigned char *readchunk
}
}
}
- spin_unlock_irqrestore(&wc->reglock, flags);
}
static inline unsigned int __t1_sdi_clk(struct t1 *wc)
@@ -383,6 +379,7 @@ static inline int t1_setreg_full(struct t1 *wc, int addr, int val, int inisr, in
int hit;
int ret;
+
do {
spin_lock_irqsave(&wc->reglock, flags);
hit = empty_slot(wc);
@@ -423,7 +420,6 @@ static inline void clean_leftovers(struct t1 *wc)
unsigned int x;
int count = 0;
- spin_lock_irqsave(&wc->reglock, flags);
/* find our requested command */
for (x = 0; x < sizeof(wc->cmdq.cmds) / sizeof(wc->cmdq.cmds[0]); x++) {
if ((wc->cmdq.cmds[x].flags & __CMD_RD) &&
@@ -433,7 +429,6 @@ static inline void clean_leftovers(struct t1 *wc)
memset(&wc->cmdq.cmds[x], 0, sizeof(wc->cmdq.cmds[x]));
}
}
- spin_unlock_irqrestore(&wc->reglock, flags);
}
/********************************************************************
@@ -449,7 +444,6 @@ static inline int t1_getreg_isr(struct t1 *wc, int addr)
int ret;
unsigned int x;
- spin_lock_irqsave(&wc->reglock, flags);
/* find our requested command */
for (x = 0;x < sizeof(wc->cmdq.cmds) / sizeof(wc->cmdq.cmds[0]); x++) {
if ((wc->cmdq.cmds[x].flags & __CMD_RD) &&
@@ -461,14 +455,12 @@ static inline int t1_getreg_isr(struct t1 *wc, int addr)
}
if (hit < 0) {
- spin_unlock_irqrestore(&wc->reglock, flags);
debug_printk(2, "t1_getreg_isr() no addr=%02x\n", addr);
return -1; /* oops, couldn't find it */
}
ret = wc->cmdq.cmds[hit].data;
memset(&wc->cmdq.cmds[hit], 0, sizeof(struct command));
- spin_unlock_irqrestore(&wc->reglock, flags);
return ret;
}
@@ -480,7 +472,9 @@ static inline int t1_getreg_full(struct t1 *wc, int addr, int inisr, int vpm_num
int ret = 0;
do {
- spin_lock_irqsave(&wc->reglock, flags);
+ if (!inisr) {
+ spin_lock_irqsave(&wc->reglock, flags);
+ }
hit = empty_slot(wc);
if (hit > -1) {
wc->cmdq.cmds[hit].address = addr;
@@ -493,9 +487,11 @@ static inline int t1_getreg_full(struct t1 *wc, int addr, int inisr, int vpm_num
if (inisr)
wc->cmdq.cmds[hit].flags |= __CMD_ISR;
}
- spin_unlock_irqrestore(&wc->reglock, flags);
if (inisr) /* must be requested in t1_getreg_isr() */
return (hit > -1) ? 0 : -1;
+ else {
+ spin_unlock_irqrestore(&wc->reglock, flags);
+ }
if (hit < 0) {
if ((ret = schluffen(&wc->regq)))
return ret;
@@ -533,15 +529,19 @@ static inline int t1_setleds(struct t1 *wc, int leds, int inisr)
leds = ~leds & 0x0E; /* invert the LED bits (3 downto 1)*/
do {
- spin_lock_irqsave(&wc->reglock, flags);
+ if (!inisr) {
+ spin_lock_irqsave(&wc->reglock, flags);
+ }
hit = empty_slot(wc);
if (hit > -1) {
wc->cmdq.cmds[hit].flags |= __CMD_LEDS;
wc->cmdq.cmds[hit].address = leds;
}
- spin_unlock_irqrestore(&wc->reglock, flags);
- if (inisr)
+ if (inisr) {
break;
+ } else {
+ spin_unlock_irqrestore(&wc->reglock, flags);
+ }
if (hit < 0) {
if ((ret = schluffen(&wc->regq)))
return ret;
@@ -1062,13 +1062,19 @@ static inline void __t1_check_sigbits(struct t1 *wc)
/* 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(&wc->reglock);
zt_rbsbits(&wc->span.chans[i+16], rxs);
+ spin_lock(&wc->reglock);
+ }
}
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(&wc->reglock);
zt_rbsbits(&wc->span.chans[i], rxs);
+ spin_lock(&wc->reglock);
+ }
}
} else {
debug_printk(1, "no space to request register in isr\n");
@@ -1081,23 +1087,35 @@ static inline 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(&wc->reglock);
zt_rbsbits(&wc->span.chans[i+3], rxs);
+ spin_lock(&wc->reglock);
+ }
}
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(&wc->reglock);
zt_rbsbits(&wc->span.chans[i+2], rxs);
+ spin_lock(&wc->reglock);
+ }
}
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(&wc->reglock);
zt_rbsbits(&wc->span.chans[i+1], rxs);
+ spin_lock(&wc->reglock);
+ }
}
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(&wc->reglock);
zt_rbsbits(&wc->span.chans[i], rxs);
+ spin_lock(&wc->reglock);
+ }
}
}
}
@@ -1108,13 +1126,19 @@ static inline 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(&wc->reglock);
zt_rbsbits(&wc->span.chans[i+1], rxs);
+ spin_lock(&wc->reglock);
+ }
}
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(&wc->reglock);
zt_rbsbits(&wc->span.chans[i], rxs);
+ spin_lock(&wc->reglock);
+ }
}
}
}
@@ -1560,7 +1584,9 @@ static inline void __t1_check_alarms(struct t1 *wc)
if (wc->span.mainttimer || wc->span.maintstat)
alarms |= ZT_ALARM_LOOPBACK;
wc->span.alarms = alarms;
+ spin_unlock(&wc->reglock);
zt_alarm_notify(&wc->span);
+ spin_lock(&wc->reglock);
}
static inline void __handle_leds(struct t1 *wc)
@@ -1664,8 +1690,11 @@ static inline void t1_transmitprep(struct t1 *wc, int dbl)
writechunk += SFRAME_SIZE;
/* Calculate Transmission */
- if (likely(wc->initialized))
+ if (likely(wc->initialized)) {
+ spin_unlock(&wc->reglock);
zt_transmit(&wc->span);
+ spin_lock(&wc->reglock);
+ }
for (x = 0; x < ZT_CHUNKSIZE; x++) {
if (likely(wc->initialized)) {
@@ -1678,8 +1707,9 @@ static inline void t1_transmitprep(struct t1 *wc, int dbl)
cmd_dequeue(wc, writechunk, x, y);
}
#ifdef VPM_SUPPORT
- if(likely(wc->vpm150m))
+ if(likely(wc->vpm150m)) {
vpm150m_cmd_dequeue(wc, writechunk, x);
+ }
#endif
if (x < ZT_CHUNKSIZE - 1) {
@@ -1695,14 +1725,12 @@ static inline void cmd_retransmit(struct t1 *wc)
unsigned int x;
unsigned long flags;
- spin_lock_irqsave(&wc->reglock, flags);
for (x = 0; x < sizeof(wc->cmdq.cmds) / sizeof(wc->cmdq.cmds[0]); x++) {
if (!(wc->cmdq.cmds[x].flags & __CMD_FIN)) {
wc->cmdq.cmds[x].flags &= ~(__CMD_TX) ; /* clear __CMD_TX */
wc->cmdq.cmds[x].ident = 0;
}
}
- spin_unlock_irqrestore(&wc->reglock, flags);
}
static inline void t1_receiveprep(struct t1 *wc, int dbl)
@@ -1743,12 +1771,14 @@ static inline void t1_receiveprep(struct t1 *wc, int dbl)
/* echo cancel */
if (likely(wc->initialized)) {
+ spin_unlock(&wc->reglock);
for (x = 0; x < wc->span.channels; x++) {
zt_ec_chunk(&wc->chans[x], wc->chans[x].readchunk, wc->ec_chunk2[x]);
memcpy(wc->ec_chunk2[x],wc->ec_chunk1[x],ZT_CHUNKSIZE);
memcpy(wc->ec_chunk1[x],wc->chans[x].writechunk,ZT_CHUNKSIZE);
}
zt_receive(&wc->span);
+ spin_lock(&wc->reglock);
}
/* Wake up anyone sleeping to read/write a new register */
@@ -1842,17 +1872,20 @@ ZAP_IRQ_HANDLER(te12xp_interrupt)
int res;
/* Read interrupts */
- ints = t1_getctl(wc, 0x0028);
+ spin_lock(&wc->reglock);
+ ints = __t1_getctl(wc, 0x0028);
- if (!ints)
+ if (!ints) {
+ spin_unlock(&wc->reglock);
#ifdef LINUX26
return IRQ_NONE;
#else
return;
#endif
+ }
/* clear interrupts interrupts (we only get here if interrupt is for us) */
- t1_setctl(wc, 0x0028, ints);
+ __t1_setctl(wc, 0x0028, ints);
ints &= wc->intmask;
if (ints & 0x00000041) {
@@ -1861,6 +1894,7 @@ ZAP_IRQ_HANDLER(te12xp_interrupt)
res |= t1_check_descriptor(wc, 1);
} while(res);
}
+ spin_unlock(&wc->reglock);
#ifdef LINUX26
return IRQ_RETVAL(1);
diff --git a/wcte12xp/vpmadt032.c b/wcte12xp/vpmadt032.c
index 5dfe0fe..964f3c4 100644
--- a/wcte12xp/vpmadt032.c
+++ b/wcte12xp/vpmadt032.c
@@ -55,8 +55,6 @@ inline void vpm150m_cmd_dequeue(struct t1 *wc, volatile unsigned char *writechun
/* Skip audio */
writechunk += 66;
- spin_lock_irqsave(&wc->reglock, flags);
-
if (test_bit(VPM150M_SPIRESET, &vpm150m->control) || test_bit(VPM150M_HPIRESET, &vpm150m->control)) {
debug_printk(1, "HW Resetting VPMADT032 ...\n");
for (x = 0; x < 4; x++) {
@@ -70,7 +68,6 @@ inline void vpm150m_cmd_dequeue(struct t1 *wc, volatile unsigned char *writechun
writechunk[CMD_BYTE(x, 1, 1)] = 0;
writechunk[CMD_BYTE(x, 2, 1)] = 0x00;
}
- spin_unlock_irqrestore(&wc->reglock, flags);
return;
}
@@ -233,8 +230,6 @@ inline void vpm150m_cmd_dequeue(struct t1 *wc, volatile unsigned char *writechun
if (test_bit(VPM150M_ACTIVE, &vpm150m->control) && !whichframe && !(wc->intcount % 10000))
queue_work(vpm150m->wq, &vpm150m->work_debug);
#endif
-
- spin_unlock_irqrestore(&wc->reglock, flags);
}
inline void vpm150m_cmd_decipher(struct t1 *wc, volatile unsigned char *readchunk)
@@ -245,7 +240,6 @@ inline void vpm150m_cmd_decipher(struct t1 *wc, volatile unsigned char *readchun
/* Skip audio */
readchunk += 66;
- spin_lock_irqsave(&wc->reglock, flags);
/* Search for any pending results */
for (x = 0; x < VPM150M_MAX_COMMANDS; x++) {
if ((wc->vpm150m->cmdq[x].flags & (__VPM150M_RD | __VPM150M_WR)) &&
@@ -267,7 +261,6 @@ inline void vpm150m_cmd_decipher(struct t1 *wc, volatile unsigned char *readchun
}
}
}
- spin_unlock_irqrestore(&wc->reglock, flags);
}
static inline struct t1 * wc_find_iface(unsigned short dspid)