diff options
author | sruffell <sruffell@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2008-01-04 22:54:10 +0000 |
---|---|---|
committer | sruffell <sruffell@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2008-01-04 22:54:10 +0000 |
commit | 2692248a15a57abf559b72d2445eca72e59542ee (patch) | |
tree | 07fdaa3173c1a3f8e92793343a294c0bf663713c /wcte12xp | |
parent | 862da09752d1361a91f9318f90314ac0353f5e90 (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.c | 92 | ||||
-rw-r--r-- | wcte12xp/vpmadt032.c | 7 |
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) |