From eea65b8209e3b57ad413a4af3cfb6766225467f4 Mon Sep 17 00:00:00 2001 From: mattf Date: Sat, 28 Apr 2007 18:33:45 +0000 Subject: Fix potential deadlock as well as reduce our locked time. git-svn-id: http://svn.digium.com/svn/zaptel/trunk@2463 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- wct4xxp/base.c | 281 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 150 insertions(+), 131 deletions(-) diff --git a/wct4xxp/base.c b/wct4xxp/base.c index 43c0acb..b4c5735 100644 --- a/wct4xxp/base.c +++ b/wct4xxp/base.c @@ -165,7 +165,7 @@ static inline int t4_queue_work(struct workqueue_struct *wq, struct work_struct #endif -static int debug=0; +static int debug=0xff; static int timingcable = 0; static int highestorder; static int t1e1override = -1; //0xFF; // -1 = jumper; 0xFF = E1 @@ -188,7 +188,6 @@ static int lastdtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD; utilization / max number of calls / etc. */ static int noburst = 1; static int debugslips = 0; -static int polling = 0; /* For 56kbps links, set this module parameter to 0x7f */ static int hardhdlcmode = 0xff; @@ -359,8 +358,8 @@ static int t4_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data); static void t4_tsi_assign(struct t4 *wc, int fromspan, int fromchan, int tospan, int tochan); static void t4_tsi_unassign(struct t4 *wc, int tospan, int tochan); static void __t4_set_timing_source(struct t4 *wc, int unit, int master, int slave); -static void __t4_check_alarms(struct t4 *wc, int span); -static void __t4_check_sigbits(struct t4 *wc, int span); +static void t4_check_alarms(struct t4 *wc, int span); +static void t4_check_sigbits(struct t4 *wc, int span); #define WC_RDADDR 0 #define WC_WRADDR 1 @@ -725,7 +724,7 @@ static void t4_check_vpm450(struct t4 *wc) channel -= 5; else channel -= 1; - if (debug) + if (unlikely(debug)) printk("Got tone %s of '%c' on channel %d of span %d\n", (start ? "START" : "STOP"), tone, channel, span + 1); if (test_bit(channel, &wc->tspans[span]->dtmfmask) && (tone != 'u')) { @@ -753,7 +752,7 @@ static void t4_check_vpm450(struct t4 *wc) } } -static void __t4_check_vpm400(struct t4 *wc, unsigned int newio) +static void t4_check_vpm400(struct t4 *wc, unsigned int newio) { unsigned int digit, regval = 0; unsigned int regbyte; @@ -772,11 +771,11 @@ static void __t4_check_vpm400(struct t4 *wc, unsigned int newio) continue; ts = wc->tspans[x%4]; /* Start of DTMF detection process */ - regbyte = __t4_vpm_in(wc, x, 0xb8); - __t4_vpm_out(wc, x, 0xb8, regbyte); /* Write 1 to clear */ + regbyte = t4_vpm_in(wc, x, 0xb8); + t4_vpm_out(wc, x, 0xb8, regbyte); /* Write 1 to clear */ regval = regbyte << 8; - regbyte = __t4_vpm_in(wc, x, 0xb9); - __t4_vpm_out(wc, x, 0xb9, regbyte); + regbyte = t4_vpm_in(wc, x, 0xb9); + t4_vpm_out(wc, x, 0xb9, regbyte); regval |= regbyte; for(i = 0; (i < MAX_DTMF_DET) && regval; i++) { @@ -786,10 +785,10 @@ static void __t4_check_vpm400(struct t4 *wc, unsigned int newio) if (!wc->t1e1) base -= 4; - regbyte = __t4_vpm_in(wc, x, 0xa8 + i); + regbyte = t4_vpm_in(wc, x, 0xa8 + i); digit = vpm_digits[regbyte]; if (!(wc->tspans[0]->spanflags & FLAG_VPM2GEN)) { - energy = __t4_vpm_in(wc, x, 0x58 + channel); + energy = t4_vpm_in(wc, x, 0x58 + channel); energy = ZT_XLAW(energy, ts->chans); ts->dtmfenergy[base] = energy; } @@ -823,11 +822,11 @@ static void __t4_check_vpm400(struct t4 *wc, unsigned int newio) continue; /* Start of DTMF off detection process */ - regbyte = __t4_vpm_in(wc, x, 0xbc); - __t4_vpm_out(wc, x, 0xbc, regbyte); /* Write 1 to clear */ + regbyte = t4_vpm_in(wc, x, 0xbc); + t4_vpm_out(wc, x, 0xbc, regbyte); /* Write 1 to clear */ regval = regbyte << 8; - regbyte = __t4_vpm_in(wc, x, 0xbd); - __t4_vpm_out(wc, x, 0xbd, regbyte); + regbyte = t4_vpm_in(wc, x, 0xbd); + t4_vpm_out(wc, x, 0xbd, regbyte); regval |= regbyte; for(i = 0; (i < MAX_DTMF_DET) && regval; i++) { @@ -855,7 +854,7 @@ static void __t4_check_vpm400(struct t4 *wc, unsigned int newio) } #endif -static void __hdlc_stop(struct t4 *wc, unsigned int span) +static void hdlc_stop(struct t4 *wc, unsigned int span) { struct t4_span *t = wc->tspans[span]; unsigned char imr0, imr1, mode; @@ -865,23 +864,23 @@ static void __hdlc_stop(struct t4 *wc, unsigned int span) /* Clear receive and transmit timeslots */ for (i = 0; i < 4; i++) { - __t4_framer_out(wc, span, FRMR_RTR_BASE + i, 0x00); - __t4_framer_out(wc, span, FRMR_TTR_BASE + i, 0x00); + t4_framer_out(wc, span, FRMR_RTR_BASE + i, 0x00); + t4_framer_out(wc, span, FRMR_TTR_BASE + i, 0x00); } - imr0 = __t4_framer_in(wc, span, FRMR_IMR0); - imr1 = __t4_framer_in(wc, span, FRMR_IMR1); + imr0 = t4_framer_in(wc, span, FRMR_IMR0); + imr1 = t4_framer_in(wc, span, FRMR_IMR1); /* Disable HDLC interrupts */ imr0 |= HDLC_IMR0_MASK; - __t4_framer_out(wc, span, FRMR_IMR0, imr0); + t4_framer_out(wc, span, FRMR_IMR0, imr0); imr1 |= HDLC_IMR1_MASK; - __t4_framer_out(wc, span, FRMR_IMR1, imr1); + t4_framer_out(wc, span, FRMR_IMR1, imr1); - mode = __t4_framer_in(wc, span, FRMR_MODE); + mode = t4_framer_in(wc, span, FRMR_MODE); mode &= ~FRMR_MODE_HRAC; - __t4_framer_out(wc, span, FRMR_MODE, mode); + t4_framer_out(wc, span, FRMR_MODE, mode); t->sigactive = 0; } @@ -891,14 +890,14 @@ static inline void __t4_framer_cmd(struct t4 *wc, unsigned int span, int cmd) __t4_framer_out(wc, span, FRMR_CMDR, cmd); } -static inline void __t4_framer_cmd_wait(struct t4 *wc, unsigned int span, int cmd) +static inline void t4_framer_cmd_wait(struct t4 *wc, unsigned int span, int cmd) { int sis; int loops = 0; /* XXX could be time consuming XXX */ for (;;) { - sis = __t4_framer_in(wc, span, FRMR_SIS); + sis = t4_framer_in(wc, span, FRMR_SIS); if (!(sis & 0x04)) break; if (!loops++) { @@ -908,14 +907,15 @@ static inline void __t4_framer_cmd_wait(struct t4 *wc, unsigned int span, int cm if (loops) printk("!!!SIS waited %d loops\n", loops); - __t4_framer_out(wc, span, FRMR_CMDR, cmd); + t4_framer_out(wc, span, FRMR_CMDR, cmd); } -static int __hdlc_start(struct t4 *wc, unsigned int span, struct zt_chan *chan, unsigned char mode) +static int hdlc_start(struct t4 *wc, unsigned int span, struct zt_chan *chan, unsigned char mode) { struct t4_span *t = wc->tspans[span]; unsigned char imr0, imr1; int offset = chan->chanpos; + unsigned long flags; if (debug & DEBUG_FRAMER) printk("Starting HDLC controller for channel %d span %d\n", offset, span+1); @@ -925,33 +925,36 @@ static int __hdlc_start(struct t4 *wc, unsigned int span, struct zt_chan *chan, mode |= FRMR_MODE_HRAC; /* Make sure we're in the right mode */ - __t4_framer_out(wc, span, FRMR_MODE, mode); - __t4_framer_out(wc, span, FRMR_TSEO, 0x00); - __t4_framer_out(wc, span, FRMR_TSBS1, hardhdlcmode); + t4_framer_out(wc, span, FRMR_MODE, mode); + t4_framer_out(wc, span, FRMR_TSEO, 0x00); + t4_framer_out(wc, span, FRMR_TSBS1, hardhdlcmode); /* Set the interframe gaps, etc */ - __t4_framer_out(wc, span, FRMR_CCR1, FRMR_CCR1_ITF|FRMR_CCR1_EITS); + t4_framer_out(wc, span, FRMR_CCR1, FRMR_CCR1_ITF|FRMR_CCR1_EITS); - __t4_framer_out(wc, span, FRMR_CCR2, FRMR_CCR2_RCRC); + t4_framer_out(wc, span, FRMR_CCR2, FRMR_CCR2_RCRC); /* Set up the time slot that we want to tx/rx on */ - __t4_framer_out(wc, span, FRMR_TTR_BASE + (offset / 8), (0x80 >> (offset % 8))); - __t4_framer_out(wc, span, FRMR_RTR_BASE + (offset / 8), (0x80 >> (offset % 8))); + t4_framer_out(wc, span, FRMR_TTR_BASE + (offset / 8), (0x80 >> (offset % 8))); + t4_framer_out(wc, span, FRMR_RTR_BASE + (offset / 8), (0x80 >> (offset % 8))); - imr0 = __t4_framer_in(wc, span, FRMR_IMR0); - imr1 = __t4_framer_in(wc, span, FRMR_IMR1); + imr0 = t4_framer_in(wc, span, FRMR_IMR0); + imr1 = t4_framer_in(wc, span, FRMR_IMR1); /* Enable our interrupts again */ imr0 &= ~HDLC_IMR0_MASK; - __t4_framer_out(wc, span, FRMR_IMR0, imr0); + t4_framer_out(wc, span, FRMR_IMR0, imr0); imr1 &= ~HDLC_IMR1_MASK; - __t4_framer_out(wc, span, FRMR_IMR1, imr1); + t4_framer_out(wc, span, FRMR_IMR1, imr1); /* Reset the signaling controller */ - __t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES); + t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES); + spin_lock_irqsave(&wc->reglock, flags); t->sigchan = chan; + spin_unlock_irqrestore(&wc->reglock, flags); + t->sigactive = 0; return 0; @@ -1174,7 +1177,7 @@ static int t4_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) return 0; } -static void inline __t4_hdlc_xmit_fifo(struct t4 *wc, unsigned int span, struct t4_span *ts) +static void inline t4_hdlc_xmit_fifo(struct t4 *wc, unsigned int span, struct t4_span *ts) { int res, i, size = 32; unsigned char buf[32]; @@ -1192,11 +1195,11 @@ static void inline __t4_hdlc_xmit_fifo(struct t4 *wc, unsigned int span, struct } for (i = 0; i < size; i++) - __t4_framer_out(wc, span, FRMR_TXFIFO, buf[i]); + t4_framer_out(wc, span, FRMR_TXFIFO, buf[i]); if (res) /* End of message */ { if (debug & DEBUG_FRAMER) printk("transmiting XHF|XME\n"); - __t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF | FRMR_CMDR_XME); + t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF | FRMR_CMDR_XME); #if 0 ts->sigactive = (__t4_framer_in(wc, span, FRMR_SIS) & FRMR_SIS_XFW) ? 0 : 1; #endif @@ -1205,7 +1208,7 @@ static void inline __t4_hdlc_xmit_fifo(struct t4 *wc, unsigned int span, struct printk("Transmitted %d frames on span %d\n", ts->frames_out, span); } else { /* Still more to transmit */ if (debug & DEBUG_FRAMER) printk("transmiting XHF\n"); - __t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF); + t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF); } } else if (res < 0) @@ -1225,10 +1228,12 @@ static void t4_hdlc_hard_xmit(struct zt_chan *chan) spin_unlock_irqrestore(&wc->reglock, flags); return; } + spin_unlock_irqrestore(&wc->reglock, flags); + if (debug & DEBUG_FRAMER) printk("t4_hdlc_hard_xmit on channel %s (sigchan %s), sigactive=%d\n", chan->name, ts->sigchan->name, ts->sigactive); + if ((ts->sigchan == chan) && !ts->sigactive) - __t4_hdlc_xmit_fifo(wc, span, ts); - spin_unlock_irqrestore(&wc->reglock, flags); + t4_hdlc_xmit_fifo(wc, span, ts); } static int t4_maint(struct zt_span *span, int cmd) @@ -1357,6 +1362,10 @@ static int t4_shutdown(struct zt_span *span) } if (debug & DEBUG_MAIN) printk("Shutting down span %d (%s)\n", span->spanno, span->name); + + /* Stop HDLC controller if runned */ + if (ts->sigchan) + hdlc_stop(wc, span->offset); spin_lock_irqsave(&wc->reglock, flags); wasrunning = span->flags & ZT_FLAG_RUNNING; @@ -1365,10 +1374,6 @@ static int t4_shutdown(struct zt_span *span) if (wasrunning) wc->spansstarted--; - /* Stop HDLC controller if runned */ - if (ts->sigchan) - __hdlc_stop(wc, span->offset); - __t4_set_led(wc, span->offset, WC_OFF); if (((wc->numspans == 4) && (!(wc->tspans[0]->span.flags & ZT_FLAG_RUNNING)) && @@ -1449,30 +1454,34 @@ static int t4_chanconfig(struct zt_chan *chan, int sigtype) if (alreadyrunning) __set_clear(wc, chan->span->offset); + spin_unlock_irqrestore(&wc->reglock, flags); + /* (re)configure signalling channel */ if ((sigtype == ZT_SIG_HARDHDLC) || (ts->sigchan == chan)) { if (debug & DEBUG_FRAMER) printk("%sonfiguring hardware HDLC on %s\n", ((sigtype == ZT_SIG_HARDHDLC) ? "C" : "Unc"), chan->name); if (alreadyrunning) { if (ts->sigchan) - __hdlc_stop(wc, ts->sigchan->span->offset); + hdlc_stop(wc, ts->sigchan->span->offset); if (sigtype == ZT_SIG_HARDHDLC) { - if (__hdlc_start(wc, chan->span->offset, chan, ts->sigmode)) { + if (hdlc_start(wc, chan->span->offset, chan, ts->sigmode)) { printk("Error initializing signalling controller\n"); - spin_unlock_irqrestore(&wc->reglock, flags); return -1; } - } - else + } else { + spin_lock_irqsave(&wc->reglock, flags); ts->sigchan = NULL; + spin_unlock_irqrestore(&wc->reglock, flags); + } } else { + spin_lock_irqsave(&wc->reglock, flags); ts->sigchan = (sigtype == ZT_SIG_HARDHDLC) ? chan : NULL; + spin_unlock_irqrestore(&wc->reglock, flags); ts->sigactive = 0; } } - spin_unlock_irqrestore(&wc->reglock, flags); return 0; } @@ -1855,11 +1864,11 @@ static void __t4_configure_t1(struct t4 *wc, int unit, int lineconfig, int txlev __t4_framer_out(wc, unit, 0x18, 0xff); /* IMR4: We don't care about slips on transmit */ } - if (!polling) { - __t4_check_alarms(wc, unit); - __t4_check_sigbits(wc, unit); - } - +#if 0 + t4_check_alarms(wc, unit); + t4_check_sigbits(wc, unit); +#endif + printk("TE%dXXP: Span %d configured for %s/%s\n", wc->numspans, unit + 1, framing, line); } @@ -1943,10 +1952,10 @@ static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig) __t4_framer_out(wc, unit, 0x17, 0xc7 | imr3extra); /* IMR3: We care about AIS and friends */ __t4_framer_out(wc, unit, 0x18, 0xff); /* IMR4: We don't care about slips on transmit */ } - if (!polling) { - __t4_check_alarms(wc, unit); - __t4_check_sigbits(wc, unit); - } +#if 0 + t4_check_alarms(wc, unit); + t4_check_sigbits(wc, unit); +#endif printk("TE%dXXP: Span %d configured for %s/%s%s\n", wc->numspans, unit + 1, framing, line, crc4); } @@ -2011,22 +2020,25 @@ static int t4_startup(struct zt_span *span) if (noburst) wc->dmactrl |= (1 << 26); __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl); - if (!polling) { - __t4_check_alarms(wc, span->offset); - __t4_check_sigbits(wc, span->offset); - } + /* Startup HDLC controller too */ - if (ts->sigchan) { - if (__hdlc_start(wc, span->offset, ts->sigchan, ts->sigmode)) { - printk("Error initializing signalling controller\n"); - /* XXX Should de-initialize span XXX */ - spin_unlock_irqrestore(&wc->reglock, flags); - return -1; - } + } + + if (ts->sigchan) { + struct zt_chan *sigchan = ts->sigchan; + + spin_unlock_irqrestore(&wc->reglock, flags); + if (hdlc_start(wc, span->offset, sigchan, ts->sigmode)) { + printk("Error initializing signalling controller\n"); + return -1; } + spin_lock_irqsave(&wc->reglock, flags); } spin_unlock_irqrestore(&wc->reglock, flags); + + t4_check_alarms(wc, span->offset); + t4_check_sigbits(wc, span->offset); if (wc->tspans[0]->sync == span->spanno) printk("SPAN %d: Primary Sync Source\n",span->spanno); if (wc->tspans[1]->sync == span->spanno) printk("SPAN %d: Secondary Sync Source\n",span->spanno); if (wc->numspans == 4) { @@ -2284,7 +2296,7 @@ static void t4_transmitprep(struct t4 *wc, int irq) } #endif -static void __t4_check_sigbits(struct t4 *wc, int span) +static void t4_check_sigbits(struct t4 *wc, int span) { int a,i,rxs; struct t4_span *ts = wc->tspans[span]; @@ -2296,7 +2308,7 @@ static void __t4_check_sigbits(struct t4 *wc, int span) return; if (ts->spantype == TYPE_E1) { for (i = 0; i < 15; i++) { - a = __t4_framer_in(wc, span, 0x71 + i); + a = t4_framer_in(wc, span, 0x71 + i); /* Get high channel in low bits */ rxs = (a & 0xf); if (!(ts->span.chans[i+16].sig & ZT_SIG_CLEAR)) { @@ -2311,7 +2323,7 @@ static void __t4_check_sigbits(struct t4 *wc, int span) } } else if (ts->span.lineconfig & ZT_CONFIG_D4) { for (i = 0; i < 24; i+=4) { - a = __t4_framer_in(wc, span, 0x70 + (i>>2)); + a = t4_framer_in(wc, span, 0x70 + (i>>2)); /* Get high channel in low bits */ rxs = (a & 0x3) << 2; if (!(ts->span.chans[i+3].sig & ZT_SIG_CLEAR)) { @@ -2336,7 +2348,7 @@ static void __t4_check_sigbits(struct t4 *wc, int span) } } else { for (i = 0; i < 24; i+=2) { - a = __t4_framer_in(wc, span, 0x70 + (i>>1)); + a = t4_framer_in(wc, span, 0x70 + (i>>1)); /* Get high channel in low bits */ rxs = (a & 0xf); if (!(ts->span.chans[i+1].sig & ZT_SIG_CLEAR)) { @@ -2356,16 +2368,19 @@ static void __t4_check_sigbits(struct t4 *wc, int span) } } -static void __t4_check_alarms(struct t4 *wc, int span) +static void t4_check_alarms(struct t4 *wc, int span) { unsigned char c,d; int alarms; int x,j; struct t4_span *ts = wc->tspans[span]; + unsigned long flags; if (!(ts->span.flags & ZT_FLAG_RUNNING)) return; + spin_lock_irqsave(&wc->reglock, flags); + c = __t4_framer_in(wc, span, 0x4c); d = __t4_framer_in(wc, span, 0x4d); @@ -2475,15 +2490,18 @@ static void __t4_check_alarms(struct t4 *wc, int span) if (ts->span.mainttimer || ts->span.maintstat) alarms |= ZT_ALARM_LOOPBACK; ts->span.alarms = alarms; + spin_unlock_irqrestore(&wc->reglock, flags); zt_alarm_notify(&ts->span); } -static void __t4_do_counters(struct t4 *wc) +static void t4_do_counters(struct t4 *wc) { int span; for (span=0;spannumspans;span++) { struct t4_span *ts = wc->tspans[span]; int docheck=0; + + spin_lock(&wc->reglock); if (ts->loopupcnt || ts->loopdowncnt) docheck++; if (ts->alarmtimer) { @@ -2492,9 +2510,9 @@ static void __t4_do_counters(struct t4 *wc) ts->span.alarms &= ~(ZT_ALARM_RECOVER); } } + spin_unlock(&wc->reglock); if (docheck) { - if (!polling) - __t4_check_alarms(wc, span); + t4_check_alarms(wc, span); zt_alarm_notify(&ts->span); } } @@ -2562,38 +2580,40 @@ static inline void __handle_leds(struct t4 *wc) #endif } -static inline void __t4_framer_interrupt(struct t4 *wc, int span) +static inline void t4_framer_interrupt(struct t4 *wc, int span) { /* Check interrupts for a given span */ unsigned char gis, isr0, isr1, isr2, isr3, isr4; int readsize = -1; struct t4_span *ts = wc->tspans[span]; + struct zt_chan *sigchan; + unsigned long flags; if (debug & DEBUG_FRAMER) printk("framer interrupt span %d:%d!\n", wc->num, span + 1); /* 1st gen cards isn't used interrupts */ - gis = __t4_framer_in(wc, span, FRMR_GIS); - isr0 = (gis & FRMR_GIS_ISR0) ? __t4_framer_in(wc, span, FRMR_ISR0) : 0; - isr1 = (gis & FRMR_GIS_ISR1) ? __t4_framer_in(wc, span, FRMR_ISR1) : 0; - isr2 = (gis & FRMR_GIS_ISR2) ? __t4_framer_in(wc, span, FRMR_ISR2) : 0; - isr3 = (gis & FRMR_GIS_ISR3) ? __t4_framer_in(wc, span, FRMR_ISR3) : 0; - isr4 = (gis & FRMR_GIS_ISR4) ? __t4_framer_in(wc, span, FRMR_ISR4) : 0; + gis = t4_framer_in(wc, span, FRMR_GIS); + isr0 = (gis & FRMR_GIS_ISR0) ? t4_framer_in(wc, span, FRMR_ISR0) : 0; + isr1 = (gis & FRMR_GIS_ISR1) ? t4_framer_in(wc, span, FRMR_ISR1) : 0; + isr2 = (gis & FRMR_GIS_ISR2) ? t4_framer_in(wc, span, FRMR_ISR2) : 0; + isr3 = (gis & FRMR_GIS_ISR3) ? t4_framer_in(wc, span, FRMR_ISR3) : 0; + isr4 = (gis & FRMR_GIS_ISR4) ? t4_framer_in(wc, span, FRMR_ISR4) : 0; if (debug & DEBUG_FRAMER) printk("gis: %02x, isr0: %02x, isr1: %02x, isr2: %02x, isr3: %02x, isr4: %02x\n", gis, isr0, isr1, isr2, isr3, isr4); if (isr0) - __t4_check_sigbits(wc, span); + t4_check_sigbits(wc, span); if (ts->spantype == TYPE_E1) { /* E1 checks */ if ((isr3 & 0x38) || isr2 || isr1) - __t4_check_alarms(wc, span); + t4_check_alarms(wc, span); } else { /* T1 checks */ if (isr2 || (isr3 & 0x08)) - __t4_check_alarms(wc, span); + t4_check_alarms(wc, span); } if (debugslips && !ts->span.alarms) { if (isr3 & 0x02) @@ -2606,12 +2626,18 @@ static inline void __t4_framer_interrupt(struct t4 *wc, int span) printk("TE%d10P: TRANSMIT slip NEGATIVE on span %d\n", wc->numspans, span + 1); } + spin_lock_irqsave(&wc->reglock, flags); /* HDLC controller checks - receive side */ - if (!ts->sigchan) + if (!ts->sigchan) { + spin_unlock_irqrestore(&wc->reglock, flags); return; + } + + sigchan = ts->sigchan; + spin_unlock_irqrestore(&wc->reglock, flags); if (isr0 & FRMR_ISR0_RME) { - readsize = (__t4_framer_in(wc, span, FRMR_RBCH) << 8) | __t4_framer_in(wc, span, FRMR_RBCL); + readsize = (t4_framer_in(wc, span, FRMR_RBCH) << 8) | t4_framer_in(wc, span, FRMR_RBCL); if (debug & DEBUG_FRAMER) printk("Received data length is %d (%d)\n", readsize, readsize & FRMR_RBCL_MAX_SIZE); /* RPF isn't set on last part of frame */ if ((readsize > 0) && ((readsize &= FRMR_RBCL_MAX_SIZE) == 0)) @@ -2620,17 +2646,16 @@ static inline void __t4_framer_interrupt(struct t4 *wc, int span) readsize = 32; if (readsize > 0) { - struct zt_chan *sigchan = ts->sigchan; int i; unsigned char readbuf[readsize]; if (debug & DEBUG_FRAMER) printk("Framer %d: Got RPF/RME! readsize is %d\n", sigchan->span->offset, readsize); for (i = 0; i < readsize; i++) - readbuf[i] = __t4_framer_in(wc, span, FRMR_RXFIFO); + readbuf[i] = t4_framer_in(wc, span, FRMR_RXFIFO); /* Tell the framer to clear the RFIFO */ - __t4_framer_cmd_wait(wc, span, FRMR_CMDR_RMC); + t4_framer_cmd_wait(wc, span, FRMR_CMDR_RMC); if (debug & DEBUG_FRAMER) { printk("RX("); @@ -2642,8 +2667,10 @@ static inline void __t4_framer_interrupt(struct t4 *wc, int span) if (isr0 & FRMR_ISR0_RME) { /* Do checks for HDLC problems */ unsigned char rsis = readbuf[readsize-1]; +#if 0 unsigned int olddebug = debug; - unsigned char rsis_reg = __t4_framer_in(wc, span, FRMR_RSIS); +#endif + unsigned char rsis_reg = t4_framer_in(wc, span, FRMR_RSIS); #if 0 if ((rsis != 0xA2) || (rsis != rsis_reg)) @@ -2671,7 +2698,9 @@ static inline void __t4_framer_interrupt(struct t4 *wc, int span) zt_hdlc_finish(sigchan); if (debug & DEBUG_FRAMER) printk("Received valid HDLC frame on span %d\n", span); } +#if 0 debug = olddebug; +#endif } else if (isr0 & FRMR_ISR0_RPF) zt_hdlc_putbuf(sigchan, readbuf, readsize); } @@ -2679,15 +2708,13 @@ static inline void __t4_framer_interrupt(struct t4 *wc, int span) /* Transmit side */ if (isr1 & FRMR_ISR1_XDU) { if (debug & DEBUG_FRAMER) printk("XDU: Resetting signal controler!\n"); - __t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES); + t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES); } else if (isr1 & FRMR_ISR1_XPR) { - struct zt_chan *sigchan = ts->sigchan; - if (debug & DEBUG_FRAMER) printk("Sigchan %d is %p\n", sigchan->chanpos, sigchan); if (debug & DEBUG_FRAMER) printk("Framer %d: Got XPR!\n", sigchan->span->offset); - __t4_hdlc_xmit_fifo(wc, span, ts); + t4_hdlc_xmit_fifo(wc, span, ts); } if (isr1 & FRMR_ISR1_ALLS) { @@ -2717,12 +2744,10 @@ ZAP_IRQ_HANDLER(t4_interrupt) /* Process framer interrupts */ status2 = t4_framer_in(wc, 0, FRMR_CIS); if (status2 & 0x0f) { - spin_lock_irqsave(&wc->reglock, flags); for (x = 0; x < wc->numspans; ++x) { if (status2 & (1 << x)) - __t4_framer_interrupt(wc, x); + t4_framer_interrupt(wc, x); } - spin_unlock_irqrestore(&wc->reglock, flags); } /* Ignore if it's not for us */ @@ -2765,11 +2790,7 @@ ZAP_IRQ_HANDLER(t4_interrupt) } } #endif - spin_lock_irqsave(&wc->reglock, flags); - - __handle_leds(wc); - - __t4_do_counters(wc); + t4_do_counters(wc); x = wc->intcount & 15 /* 63 */; switch(x) { @@ -2777,18 +2798,23 @@ ZAP_IRQ_HANDLER(t4_interrupt) case 1: case 2: case 3: - __t4_check_sigbits(wc, x); + t4_check_sigbits(wc, x); break; case 4: case 5: case 6: case 7: - __t4_check_alarms(wc, x - 4); + t4_check_alarms(wc, x - 4); break; } + spin_lock_irqsave(&wc->reglock, flags); + + __handle_leds(wc); + if (wc->checktiming > 0) __t4_set_timing_source_auto(wc); + spin_unlock_irqrestore(&wc->reglock, flags); #ifdef LINUX26 return IRQ_RETVAL(1); @@ -2799,21 +2825,18 @@ ZAP_IRQ_HANDLER(t4_interrupt) static void t4_isr_bh(unsigned long data) { struct t4 *wc = (struct t4 *)data; - unsigned long flags; unsigned char cis; if (test_and_clear_bit(T4_CHECK_FRAMER, &wc->checkflag)) { - spin_lock_irqsave(&wc->reglock, flags); - cis = __t4_framer_in(wc, 0, FRMR_CIS); + cis = t4_framer_in(wc, 0, FRMR_CIS); if (cis & FRMR_CIS_GIS1) - __t4_framer_interrupt(wc, 0); + t4_framer_interrupt(wc, 0); if (cis & FRMR_CIS_GIS2) - __t4_framer_interrupt(wc, 1); + t4_framer_interrupt(wc, 1); if (cis & FRMR_CIS_GIS3) - __t4_framer_interrupt(wc, 2); + t4_framer_interrupt(wc, 2); if (cis & FRMR_CIS_GIS4) - __t4_framer_interrupt(wc, 3); - spin_unlock_irqrestore(&wc->reglock, flags); + t4_framer_interrupt(wc, 3); } #ifdef VPM_SUPPORT @@ -2824,11 +2847,8 @@ static void t4_isr_bh(unsigned long data) interrupt when there's a tone, in spite of what their documentation says? */ t4_check_vpm450(wc); - } else { - spin_lock_irqsave(&wc->reglock, flags); - __t4_check_vpm400(wc, wc->vpm400checkstatus); - spin_unlock_irqrestore(&wc->reglock, flags); - } + } else + t4_check_vpm400(wc, wc->vpm400checkstatus); } } #endif @@ -2914,9 +2934,10 @@ ZAP_IRQ_HANDLER(t4_interrupt_gen2) } } + t4_do_counters(wc); + spin_lock(&wc->reglock); - __t4_do_counters(wc); __handle_leds(wc); if (unlikely(wc->checktiming > 0)) { @@ -3777,7 +3798,6 @@ module_param(debug, int, 0600); module_param(loopback, int, 0600); module_param(noburst, int, 0600); module_param(debugslips, int, 0600); -module_param(polling, int, 0600); module_param(timingcable, int, 0600); module_param(t1e1override, int, 0600); module_param(alarmdebounce, int, 0600); @@ -3794,7 +3814,6 @@ MODULE_PARM(debug, "i"); MODULE_PARM(loopback, "i"); MODULE_PARM(noburst, "i"); MODULE_PARM(debugslips, "i"); -MODULE_PARM(polling, "i"); MODULE_PARM(hardhdlcmode, "i"); MODULE_PARM(timingcable, "i"); MODULE_PARM(t1e1override, "i"); -- cgit v1.2.3