From ec3da485f11dc83627691b49323ed6bf94ac7c5d Mon Sep 17 00:00:00 2001 From: mattf Date: Fri, 24 Aug 2007 19:25:20 +0000 Subject: Beginning backport of trunk to 1.4 git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@2946 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- wct4xxp/base.c | 571 ++++++++++++++++++++++++--------------------------------- 1 file changed, 236 insertions(+), 335 deletions(-) (limited to 'wct4xxp/base.c') diff --git a/wct4xxp/base.c b/wct4xxp/base.c index 4aebb70..012a8b6 100644 --- a/wct4xxp/base.c +++ b/wct4xxp/base.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include #ifdef STANDALONE_ZAPATA #include "zaptel.h" #else @@ -47,19 +49,6 @@ #include "wct4xxp.h" #include "vpm450m.h" -/* - * Tasklets provide better system interactive response at the cost of the - * possibility of losing a frame of data at very infrequent intervals. If - * you are more concerned with the performance of your machine, enable the - * tasklets. If you are strict about absolutely no drops, then do not enable - * tasklets. - * - * XXX THIS IS NOT CURRENTLY IMPLEMENTED FOR THIS MODULE. FOR NOW, DO NOT USE! - */ - -/* #define ENABLE_TASKLETS */ - - /* Work queues are a way to better distribute load on SMP systems */ #if defined(LINUX26) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) /* @@ -92,7 +81,7 @@ #define DEBUG_FRAMER (1 << 6) #ifdef ENABLE_WORKQUEUES -#include +#include /* XXX UGLY!!!! XXX We have to access the direct structures of the workqueue which are only defined within workqueue.c because they don't give us a routine to allow us @@ -131,7 +120,12 @@ struct cpu_workqueue_struct { * per-CPU workqueues: */ struct workqueue_struct { + /* TODO: Find out exactly where the API changed */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) + struct cpu_workqueue_struct *cpu_wq; +#else struct cpu_workqueue_struct cpu_wq[NR_CPUS]; +#endif const char *name; struct list_head list; /* Empty if single thread */ }; @@ -160,12 +154,13 @@ static void __t4_queue_work(struct cpu_workqueue_struct *cwq, static inline int t4_queue_work(struct workqueue_struct *wq, struct work_struct *work, int cpu) { int ret = 0; - + get_cpu(); if (!test_and_set_bit(0, &work->pending)) { BUG_ON(!list_empty(&work->entry)); __t4_queue_work(wq->cpu_wq + cpu, work); ret = 1; } + put_cpu(); return ret; } @@ -194,8 +189,6 @@ static int lastdtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD; aggressive cards. Please note that burst mode has no effect on CPU 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; @@ -247,8 +240,6 @@ static struct devtype wct205 = { "Wildcard TE205P ", FLAG_2NDGEN | FLAG_2PORT }; static struct devtype wct210 = { "Wildcard TE210P ", FLAG_2NDGEN | FLAG_2PORT }; -static int inirq = 0; - struct t4; struct t4_span { @@ -285,9 +276,9 @@ struct t4_span { int frames_in; #ifdef VPM_SUPPORT - unsigned int dtmfactive; - unsigned int dtmfmask; - unsigned int dtmfmutemask; + unsigned long dtmfactive; + unsigned long dtmfmask; + unsigned long dtmfmutemask; short dtmfenergy[31]; short dtmfdigit[31]; #endif @@ -307,10 +298,6 @@ struct t4 { int syncsrc; /* active sync source */ struct t4_span *tspans[4]; /* Individual spans */ int numspans; /* Number of spans on the card */ -#ifdef VPM_SUPPORT - int vpm; -#endif - int blinktimer; #ifdef FANCY_ALARM int alarmpos; @@ -323,37 +310,39 @@ struct t4 { unsigned int gpio; unsigned int gpioctl; int stopdma; /* Set to stop DMA */ - unsigned int dmactrl; int e1recover; /* E1 recovery timer */ - dma_addr_t readdma; - dma_addr_t writedma; - unsigned long memaddr; /* Base address of card */ - unsigned long memlen; - volatile unsigned int *membase; /* Base address of card */ - int spansstarted; /* number of spans started */ - /* spinlock_t lock; */ /* lock context */ spinlock_t reglock; /* lock register access */ + int spansstarted; /* number of spans started */ volatile unsigned int *writechunk; /* Double-word aligned write memory */ volatile unsigned int *readchunk; /* Double-word aligned read memory */ unsigned short canary; #ifdef ENABLE_WORKQUEUES atomic_t worklist; struct workqueue_struct *workq; -#else -#ifdef ENABLE_TASKLETS - int taskletrun; - int taskletsched; - int taskletpending; - int taskletexec; - int txerrors; - struct tasklet_struct t4_tlet; -#endif #endif unsigned int passno; /* number of interrupt passes */ char *variety; int last0; /* for detecting double-missed IRQ */ int checktiming; /* Set >0 to cause the timing source to be checked */ + + /* DMA related fields */ + unsigned int dmactrl; + dma_addr_t readdma; + dma_addr_t writedma; + unsigned long memaddr; /* Base address of card */ + unsigned long memlen; + volatile unsigned int *membase; /* Base address of card */ + + /* Flags for our bottom half */ + unsigned long checkflag; + struct tasklet_struct t4_tlet; + unsigned int vpm400checkstatus; + +#ifdef VPM_SUPPORT struct vpm450m *vpm450m; + int vpm; +#endif + }; #define T4_VPM_PRESENT (1 << 28) @@ -407,9 +396,7 @@ static void t4_check_sigbits(struct t4 *wc, int span); #define MAX_T4_CARDS 64 -#ifdef ENABLE_TASKLETS -static void t4_tasklet(unsigned long data); -#endif +static void t4_isr_bh(unsigned long data); static struct t4 *cards[MAX_T4_CARDS]; @@ -547,13 +534,13 @@ static inline unsigned int t4_framer_in(struct t4 *wc, int unit, const unsigned static inline void __t4_framer_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value) { unit &= 0x3; - if (debug & DEBUG_REGS) + if (unlikely(debug & DEBUG_REGS)) printk("Writing %02x to address %02x of unit %d\n", value, addr, unit); __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff)); __t4_pci_out(wc, WC_LDATA, value); __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | WC_LFRMR_CS | WC_LWRITE); __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff)); - if (debug & DEBUG_REGS) printk("Write complete\n"); + if (unlikely(debug & DEBUG_REGS)) printk("Write complete\n"); #if 0 if ((addr != FRMR_TXFIFO) && (addr != FRMR_CMDR) && (addr != 0xbc)) { unsigned int tmp; @@ -749,14 +736,14 @@ 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 ((wc->tspans[span]->dtmfmask & (1 << channel)) && (tone != 'u')) { + if (test_bit(channel, &wc->tspans[span]->dtmfmask) && (tone != 'u')) { if (start) { /* The octasic is supposed to mute us, but... Yah, you guessed it. */ - if (wc->tspans[span]->dtmfmutemask & (1 << channel)) { + if (test_bit(channel, &wc->tspans[span]->dtmfmutemask)) { unsigned long flags; struct zt_chan *chan = &wc->tspans[span]->span.chans[channel]; int y; @@ -767,10 +754,10 @@ static void t4_check_vpm450(struct t4 *wc) } spin_unlock_irqrestore(&chan->lock, flags); } - wc->tspans[span]->dtmfactive |= (1 << channel); + set_bit(channel, &wc->tspans[span]->dtmfactive); zt_qevent_lock(&wc->tspans[span]->span.chans[channel], (ZT_EVENT_DTMFDOWN | tone)); } else { - wc->tspans[span]->dtmfactive &= ~(1 << channel); + clear_bit(channel, &wc->tspans[span]->dtmfactive); zt_qevent_lock(&wc->tspans[span]->span.chans[channel], (ZT_EVENT_DTMFUP | tone)); } } @@ -785,24 +772,22 @@ static void t4_check_vpm400(struct t4 *wc, unsigned int newio) short energy=0; static unsigned int lastio = 0; struct t4_span *ts; - unsigned long flags; if (debug && (newio != lastio)) printk("Last was %08x, new is %08x\n", lastio, newio); lastio = newio; - spin_lock_irqsave(&wc->reglock, flags); for(x = 0; x < 8; x++) { if (newio & (1 << (7 - x))) 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++) { @@ -812,42 +797,32 @@ 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; } - ts->dtmfactive |= (1 << base); + set_bit(base, &ts->dtmfactive); if (ts->dtmfdigit[base]) { - if (ts->dtmfmask & (1 << base)) { - spin_unlock_irqrestore(&wc->reglock, flags); + if (ts->dtmfmask & (1 << base)) zt_qevent_lock(&ts->span.chans[base], (ZT_EVENT_DTMFUP | ts->dtmfdigit[base])); - spin_lock_irqsave(&wc->reglock, flags); - } } ts->dtmfdigit[base] = digit; - if (ts->dtmfmask & (1 << base)) { - spin_unlock_irqrestore(&wc->reglock, flags); + if (test_bit(base, &ts->dtmfmask)) zt_qevent_lock(&ts->span.chans[base], (ZT_EVENT_DTMFDOWN | digit)); - spin_lock_irqsave(&wc->reglock, flags); - } - if (ts->dtmfmutemask & (1 << base)) { + if (test_bit(base, &ts->dtmfmutemask)) { /* Mute active receive buffer*/ - unsigned long flags2; + unsigned long flags; struct zt_chan *chan = &ts->span.chans[base]; int y; - /* We can't hold the reglock and the channel lock at the same time. If we do so, - * we can cause a deadlock scenario */ - spin_unlock_irqrestore(&wc->reglock, flags); - spin_lock_irqsave(&chan->lock, flags2); + spin_lock_irqsave(&chan->lock, flags); for (y=0;ynumbufs;y++) { if ((chan->inreadbuf > -1) && (chan->readidx[y])) memset(chan->readbuf[chan->inreadbuf], ZT_XLAW(0, chan), chan->readidx[y]); } - spin_unlock_irqrestore(&chan->lock, flags2); - spin_lock_irqsave(&wc->reglock, flags); + spin_unlock_irqrestore(&chan->lock, flags); } if (debug) printk("Digit Seen: %d, Span: %d, channel: %d, energy: %02x, 'channel %d' chip %d\n", digit, x % 4, base + 1, energy, channel, x); @@ -859,11 +834,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++) { @@ -873,13 +848,10 @@ static void t4_check_vpm400(struct t4 *wc, unsigned int newio) if (!wc->t1e1) base -= 4; - ts->dtmfactive &= ~(1 << base); + clear_bit(base, &ts->dtmfactive); if (ts->dtmfdigit[base]) { - if (ts->dtmfmask & (1 << base)) { - spin_unlock_irqrestore(&wc->reglock, flags); + if (test_bit(base, &ts->dtmfmask)) zt_qevent_lock(&ts->span.chans[base], (ZT_EVENT_DTMFUP | ts->dtmfdigit[base])); - spin_lock_irqsave(&wc->reglock, flags); - } } digit = ts->dtmfdigit[base]; ts->dtmfdigit[base] = 0; @@ -891,11 +863,10 @@ static void t4_check_vpm400(struct t4 *wc, unsigned int newio) } } - spin_unlock_irqrestore(&wc->reglock, flags); } #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; @@ -905,23 +876,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; } @@ -931,31 +902,32 @@ 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++) { + if (!loops++ && (debug & DEBUG_FRAMER)) { printk("!!!SIS Waiting before cmd %02x\n", cmd); } } - if (loops) + if (loops && (debug & DEBUG_FRAMER)) 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); @@ -965,33 +937,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; @@ -1192,13 +1167,13 @@ static int t4_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) if (j && (vpmdtmfsupport == 0)) return -ENOSYS; if (j & ZT_TONEDETECT_ON) - ts->dtmfmask |= (1 << (chan->chanpos - 1)); + set_bit(chan->chanpos - 1, &ts->dtmfmask); else - ts->dtmfmask &= ~(1 << (chan->chanpos - 1)); + clear_bit(chan->chanpos - 1, &ts->dtmfmask); if (j & ZT_TONEDETECT_MUTE) - ts->dtmfmutemask |= (1 << (chan->chanpos - 1)); + set_bit(chan->chanpos - 1, &ts->dtmfmutemask); else - ts->dtmfmutemask &= ~(1 << (chan->chanpos - 1)); + clear_bit(chan->chanpos - 1, &ts->dtmfmutemask); if (wc->vpm450m) { channel = (chan->chanpos) << 2; if (!wc->t1e1) @@ -1218,12 +1193,8 @@ static void inline t4_hdlc_xmit_fifo(struct t4 *wc, unsigned int span, struct t4 { int res, i, size = 32; unsigned char buf[32]; - unsigned long flags; res = zt_hdlc_getbuf(ts->sigchan, buf, &size); - - spin_lock_irqsave(&wc->reglock, flags); - if (debug & DEBUG_FRAMER) printk("Got buffer sized %d and res %d for %d\n", size, res, span); if (size > 0) { ts->sigactive = 1; @@ -1236,11 +1207,11 @@ static void inline t4_hdlc_xmit_fifo(struct t4 *wc, unsigned int span, struct t4 } 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 @@ -1249,13 +1220,11 @@ static void inline t4_hdlc_xmit_fifo(struct t4 *wc, unsigned int span, struct t4 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) ts->sigactive = 0; - - spin_unlock_irqrestore(&wc->reglock, flags); } static void t4_hdlc_hard_xmit(struct zt_chan *chan) @@ -1271,12 +1240,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) { - spin_unlock_irqrestore(&wc->reglock, flags); + + if ((ts->sigchan == chan) && !ts->sigactive) t4_hdlc_xmit_fifo(wc, span, ts); - } else - spin_unlock_irqrestore(&wc->reglock, flags); } static int t4_maint(struct zt_span *span, int cmd) @@ -1405,18 +1374,15 @@ 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; span->flags &= ~ZT_FLAG_RUNNING; - 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)) && @@ -1432,6 +1398,12 @@ static int t4_shutdown(struct zt_span *span) wc->stopdma = 1; } else wc->checktiming = 1; spin_unlock_irqrestore(&wc->reglock, flags); + + /* Wait for interrupt routine to shut itself down */ + msleep(10); + if (wasrunning) + wc->spansstarted--; + if (debug & DEBUG_MAIN) printk("Span %d (%s) shutdown\n", span->spanno, span->name); return 0; @@ -1497,30 +1469,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; } @@ -1547,7 +1523,7 @@ static int t4_close(struct zt_chan *chan) static void init_spans(struct t4 *wc) { - int x,y,c; + int x,y; int gen2; int offset = 1; struct t4_span *ts; @@ -1603,7 +1579,6 @@ static void init_spans(struct t4 *wc) sprintf(mychans->name, "TE%d/%d/%d/%d", wc->numspans, wc->num, x + 1, y + 1); mychans->sigcap = ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_FXSLS | ZT_SIG_FXSGS | ZT_SIG_FXSKS | ZT_SIG_HARDHDLC | ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_FXOKS | ZT_SIG_CAS | ZT_SIG_EM_E1 | ZT_SIG_DACS_RBS; - c = (x * ts->span.channels) + y; mychans->pvt = wc; mychans->chanpos = y + 1; if (gen2) { @@ -1896,13 +1871,8 @@ static void __t4_configure_t1(struct t4 *wc, int unit, int lineconfig, int txlev __t4_framer_out(wc, unit, FRMR_IMR0, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR0_MASK : 0)); /* IMR0: We care about CAS changes, etc */ __t4_framer_out(wc, unit, FRMR_IMR1, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0)); /* IMR1: We care about nothing */ __t4_framer_out(wc, unit, 0x16, 0x00); /* IMR2: We care about all the alarm stuff! */ - if (debugslips) { - __t4_framer_out(wc, unit, 0x17, 0xf4); /* IMR3: We care about AIS and friends */ - __t4_framer_out(wc, unit, 0x18, 0x3f); /* IMR4: We care about slips on transmit */ - } else { - __t4_framer_out(wc, unit, 0x17, 0xf7); /* IMR3: We care about AIS and friends */ - __t4_framer_out(wc, unit, 0x18, 0xff); /* IMR4: We don't care about slips on transmit */ - } + __t4_framer_out(wc, unit, 0x17, 0xf4); /* IMR3: We care about AIS and friends */ + __t4_framer_out(wc, unit, 0x18, 0x3f); /* IMR4: We care about slips on transmit */ printk("TE%dXXP: Span %d configured for %s/%s\n", wc->numspans, unit + 1, framing, line); } @@ -1980,13 +1950,9 @@ static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig) __t4_framer_out(wc, unit, FRMR_IMR0, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR0_MASK : 0)); /* IMR0: We care about CRC errors, CAS changes, etc */ __t4_framer_out(wc, unit, FRMR_IMR1, 0x3f & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0)); /* IMR1: We care about loopup / loopdown */ __t4_framer_out(wc, unit, 0x16, 0x00); /* IMR2: We care about all the alarm stuff! */ - if (debugslips) { - __t4_framer_out(wc, unit, 0x17, 0xc4 | imr3extra); /* IMR3: We care about AIS and friends */ - __t4_framer_out(wc, unit, 0x18, 0x3f); /* IMR4: We care about slips on transmit */ - } else { - __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 */ - } + __t4_framer_out(wc, unit, 0x17, 0xc4 | imr3extra); /* IMR3: We care about AIS and friends */ + __t4_framer_out(wc, unit, 0x18, 0x3f); /* IMR4: We care about slips on transmit */ + printk("TE%dXXP: Span %d configured for %s/%s%s\n", wc->numspans, unit + 1, framing, line, crc4); } @@ -2042,6 +2008,8 @@ static int t4_startup(struct zt_span *span) /* enable interrupts */ /* Start DMA, enabling DMA interrupts on read only */ wc->dmactrl = 1 << 29; + /* Enable framer only interrupts */ + wc->dmactrl |= 1 << 27; wc->dmactrl |= (ts->spanflags & FLAG_2NDGEN) ? 0xc0000000 : 0xc0000003; #ifdef VPM_SUPPORT wc->dmactrl |= wc->vpm; @@ -2051,15 +2019,19 @@ static int t4_startup(struct zt_span *span) if (noburst && !(ts->spanflags & FLAG_BURST)) wc->dmactrl |= (1 << 26); __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl); + /* 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); @@ -2205,12 +2177,12 @@ static inline void __receive_span(struct t4_span *ts) { #ifdef VPM_SUPPORT int y; - unsigned int merged; + unsigned long merged; merged = ts->dtmfactive & ts->dtmfmutemask; if (merged) { for (y=0;yspan.channels;y++) { /* Mute any DTMFs which are supposed to be muted */ - if (merged & (1 << y)) { + if (test_bit(y, &merged)) { memset(ts->span.chans[y].readchunk, ZT_XLAW(0, (ts->span.chans + y)), ZT_CHUNKSIZE); } } @@ -2334,7 +2306,6 @@ static void t4_check_sigbits(struct t4 *wc, int span) if (!(ts->span.flags & ZT_FLAG_RUNNING)) return; - if (ts->spantype == TYPE_E1) { for (i = 0; i < 15; i++) { a = t4_framer_in(wc, span, 0x71 + i); @@ -2519,21 +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) { int span; - unsigned long flags; - for (span=0;spannumspans;span++) { struct t4_span *ts = wc->tspans[span]; int docheck=0; - spin_lock_irqsave(&wc->reglock, flags); + + spin_lock(&wc->reglock); if (ts->loopupcnt || ts->loopdowncnt) docheck++; if (ts->alarmtimer) { @@ -2542,10 +2510,9 @@ static void t4_do_counters(struct t4 *wc) ts->span.alarms &= ~(ZT_ALARM_RECOVER); } } - spin_unlock_irqrestore(&wc->reglock, flags); + spin_unlock(&wc->reglock); if (docheck) { - if (!polling) - t4_check_alarms(wc, span); + t4_check_alarms(wc, span); zt_alarm_notify(&ts->span); } } @@ -2619,6 +2586,7 @@ static inline void t4_framer_interrupt(struct t4 *wc, int 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) @@ -2647,16 +2615,20 @@ static inline void t4_framer_interrupt(struct t4 *wc, int span) if (isr2 || (isr3 & 0x08)) t4_check_alarms(wc, span); } - if (debugslips && !ts->span.alarms) { - if (isr3 & 0x02) - printk("TE%d10P: RECEIVE slip NEGATIVE on span %d\n", wc->numspans, span + 1); - if (isr3 & 0x01) - printk("TE%d10P: RECEIVE slip POSITIVE on span %d\n", wc->numspans, span + 1); - if (isr4 & 0x80) - printk("TE%dXXP: TRANSMIT slip POSITIVE on span %d\n", wc->numspans, span + 1); - if (isr4 & 0x40) - printk("TE%d10P: TRANSMIT slip NEGATIVE on span %d\n", wc->numspans, span + 1); - } + if (!ts->span.alarms) { + ts->span.timingslips++; + if (debug & DEBUG_MAIN) { + if (isr3 & 0x02) + printk("TE%d10P: RECEIVE slip NEGATIVE on span %d\n", wc->numspans, span + 1); + if (isr3 & 0x01) + printk("TE%d10P: RECEIVE slip POSITIVE on span %d\n", wc->numspans, span + 1); + if (isr4 & 0x80) + printk("TE%dXXP: TRANSMIT slip POSITIVE on span %d\n", wc->numspans, span + 1); + if (isr4 & 0x40) + printk("TE%d10P: TRANSMIT slip NEGATIVE on span %d\n", wc->numspans, span + 1); + } + } else + ts->span.timingslips = 0; spin_lock_irqsave(&wc->reglock, flags); /* HDLC controller checks - receive side */ @@ -2665,8 +2637,11 @@ static inline void t4_framer_interrupt(struct t4 *wc, int span) 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)) @@ -2675,17 +2650,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("); @@ -2697,8 +2671,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)) @@ -2706,7 +2682,6 @@ static inline void t4_framer_interrupt(struct t4 *wc, int span) #endif ++ts->frames_in; - spin_unlock_irqrestore(&wc->reglock, flags); if ((debug & DEBUG_FRAMER) && !(ts->frames_in & 0x0f)) printk("Received %d frames on span %d\n", ts->frames_in, span); if (debug & DEBUG_FRAMER) printk("Received HDLC frame %d. RSIS = 0x%x (%x)\n", ts->frames_in, rsis, rsis_reg); @@ -2727,37 +2702,29 @@ 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); } - spin_lock_irqsave(&wc->reglock, flags); +#if 0 debug = olddebug; - } else if (isr0 & FRMR_ISR0_RPF) { - spin_unlock_irqrestore(&wc->reglock, flags); +#endif + } else if (isr0 & FRMR_ISR0_RPF) zt_hdlc_putbuf(sigchan, readbuf, readsize); - spin_lock_irqsave(&wc->reglock, flags); - } } /* 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); - spin_unlock_irqrestore(&wc->reglock, flags); t4_hdlc_xmit_fifo(wc, span, ts); - spin_lock_irqsave(&wc->reglock, flags); } if (isr1 & FRMR_ISR1_ALLS) { if (debug & DEBUG_FRAMER) printk("ALLS received\n"); } - spin_unlock_irqrestore(&wc->reglock, flags); - } #ifdef SUPPORT_GEN1 @@ -2775,9 +2742,9 @@ ZAP_IRQ_HANDLER(t4_interrupt) printk("Pre-interrupt\n"); #endif - inirq = 1; /* Make sure it's really for us */ - status = t4_pci_in(wc, WC_INTR); + status = __t4_pci_in(wc, WC_INTR); + /* Process framer interrupts */ status2 = t4_framer_in(wc, 0, FRMR_CIS); if (status2 & 0x0f) { @@ -2795,7 +2762,7 @@ ZAP_IRQ_HANDLER(t4_interrupt) return; #endif - t4_pci_out(wc, WC_INTR, 0); + __t4_pci_out(wc, WC_INTR, 0); if (!wc->spansstarted) { printk("Not prepped yet!\n"); @@ -2859,42 +2826,32 @@ ZAP_IRQ_HANDLER(t4_interrupt) } #endif -ZAP_IRQ_HANDLER(t4_interrupt_gen2) +static void t4_isr_bh(unsigned long data) { - struct t4 *wc = dev_id; - unsigned long flags; - unsigned char cis; - int x; - int needcheckvpm450=0; - - unsigned int status; -#if 0 - unsigned int status2; -#endif + struct t4 *wc = (struct t4 *)data; -#if 0 - if (wc->intcount < 20) - printk("2G: Pre-interrupt\n"); -#endif - - spin_lock_irqsave(&wc->reglock, flags); - - if (wc->stopdma) { - /* Stop DMA cleanly if requested */ - wc->dmactrl = 0x0; - __t4_pci_out(wc, WC_DMACTRL, 0x00000000); - /* Acknowledge any pending interrupts */ - __t4_pci_out(wc, WC_INTR, 0x00000000); - __t4_set_timing_source(wc, 4, 0, 0); - wc->stopdma = 0x0; +#ifdef VPM_SUPPORT + if (wc->vpm) { + if (test_and_clear_bit(T4_CHECK_VPM, &wc->checkflag)) { + if (wc->vpm450m) { + /* How stupid is it that the octasic can't generate an + interrupt when there's a tone, in spite of what their + documentation says? */ + t4_check_vpm450(wc); + } else + t4_check_vpm400(wc, wc->vpm400checkstatus); + } } +#endif +} - spin_unlock_irqrestore(&wc->reglock, flags); - +ZAP_IRQ_HANDLER(t4_interrupt_gen2) +{ + struct t4 *wc = dev_id; + unsigned int status; - inirq = 1; /* Make sure it's really for us */ - status = t4_pci_in(wc, WC_INTR); + status = __t4_pci_in(wc, WC_INTR); /* Ignore if it's not for us */ if (!(status & 0x7)) { @@ -2906,9 +2863,10 @@ ZAP_IRQ_HANDLER(t4_interrupt_gen2) } #ifdef ENABLE_WORKQUEUES - t4_pci_out(wc, WC_INTR, status & 0x00000008); + __t4_pci_out(wc, WC_INTR, status & 0x00000008); #endif - if (!wc->spansstarted) { + + if (unlikely(!wc->spansstarted)) { printk("Not prepped yet!\n"); #ifdef LINUX26 return IRQ_NONE; @@ -2918,13 +2876,12 @@ ZAP_IRQ_HANDLER(t4_interrupt_gen2) } wc->intcount++; -#if 1 - if ((wc->intcount < 20) && debug) + + if (unlikely((wc->intcount < 20) && debug)) printk("2G: Got interrupt, status = %08x, CIS = %04x\n", status, t4_framer_in(wc, 0, FRMR_CIS)); -#endif - if (status & 0x2) { + if (likely(status & 0x2)) { #ifdef ENABLE_WORKQUEUES int cpus = num_online_cpus(); atomic_set(&wc->worklist, wc->numspans); @@ -2949,28 +2906,16 @@ ZAP_IRQ_HANDLER(t4_interrupt_gen2) #else t4_prep_gen2(wc); #endif + t4_do_counters(wc); + spin_lock(&wc->reglock); + __handle_leds(wc); + spin_unlock(&wc->reglock); + } - if (status & 0x2) - t4_do_counters(wc); + if (unlikely(status & 0x1)) { + unsigned char cis; - if (polling && (status & 0x2)) { - x = wc->intcount & 15 /* 63 */; - switch(x) { - case 0: - case 1: - case 2: - case 3: - t4_check_sigbits(wc, x); - break; - case 4: - case 5: - case 6: - case 7: - t4_check_alarms(wc, x - 4); - break; - } - } else if (status & 0x1) { cis = t4_framer_in(wc, 0, FRMR_CIS); if (cis & FRMR_CIS_GIS1) t4_framer_interrupt(wc, 0); @@ -2982,81 +2927,43 @@ ZAP_IRQ_HANDLER(t4_interrupt_gen2) t4_framer_interrupt(wc, 3); } - spin_lock_irqsave(&wc->reglock, flags); - -#ifdef VPM_SUPPORT if (wc->vpm) { - if (!wc->vpm450m && !(wc->intcount % 16) && !(wc->tspans[0]->spanflags & FLAG_VPM2GEN)) { - /* Check DTMF events */ - int span = (wc->intcount >> 4) & 0x3; - int y; - short energy; - int offset = 1; - int chip; - int channel; - struct t4_span *ts = wc->tspans[span]; - if (!wc->t1e1) - offset = 5; - if (ts->dtmfactive) { - for (y = 0; y < ts->span.channels; y++) { - if (ts->dtmfactive & (1 << y)) { - channel = y + offset; - chip = span + ((channel & 0x1) << 2); - /* Have an active channel, check its energy! */ - energy = __t4_vpm_in(wc, chip, 0x58 + channel); - energy = ZT_XLAW(energy, ts->span.chans); - if (energy < (ts->dtmfenergy[y])) { - if (debug & DEBUG_DTMF) - printk("Finished digit on span %d, channel %d (energy = %02x < %02x) 'channel' %d, chip %d!\n", span, y + 1, energy, ts->dtmfenergy[y], channel, chip); - if (debug & DEBUG_DTMF) - printk("Finished digit '%c' on channel %d of span %d\n", ts->dtmfdigit[y], y + 1, span); - if (ts->dtmfmask & (1 << y)) { - spin_unlock_irqrestore(&wc->reglock, flags); - zt_qevent_lock(&ts->span.chans[y], (ZT_EVENT_DTMFUP | ts->dtmfdigit[y])); - spin_lock_irqsave(&wc->reglock, flags); - } - ts->dtmfenergy[y] = 0; - ts->dtmfdigit[y] = 0; - ts->dtmfactive &= ~(1 << y); - } else if (energy > (ts->dtmfenergy[y])) { - if (debug & DEBUG_DTMF) - printk("Increasing digit energy on span %d, channel %d (energy = %02x > %02x)!\n", span, y + 1, energy, ts->dtmfenergy[y]); - ts->dtmfenergy[y] = energy; - } - } - } - } - } if (wc->vpm450m) { /* How stupid is it that the octasic can't generate an interrupt when there's a tone, in spite of what their documentation says? */ if (!(wc->intcount & 0xf)) { - needcheckvpm450 = 1; + set_bit(T4_CHECK_VPM, &wc->checkflag); } } else if ((status & 0xff00) != 0xff00) { - spin_unlock_irqrestore(&wc->reglock, flags); - t4_check_vpm400(wc, (status & 0xff00) >> 8); - spin_lock_irqsave(&wc->reglock, flags); + wc->vpm400checkstatus = (status & 0xff00) >> 8; + set_bit(T4_CHECK_VPM, &wc->checkflag); } } -#endif -#if 1 - __handle_leds(wc); -#endif + spin_lock(&wc->reglock); - if (wc->checktiming > 0) + if (unlikely(wc->checktiming > 0)) { __t4_set_timing_source_auto(wc); - spin_unlock_irqrestore(&wc->reglock, flags); + } - if (needcheckvpm450 && (vpmdtmfsupport == 1)) { - t4_check_vpm450(wc); - needcheckvpm450 = 0; + if (unlikely(wc->stopdma)) { + /* Stop DMA cleanly if requested */ + wc->dmactrl = 0x0; + __t4_pci_out(wc, WC_DMACTRL, 0x00000000); + /* Acknowledge any pending interrupts */ + __t4_pci_out(wc, WC_INTR, 0x00000000); + __t4_set_timing_source(wc, 4, 0, 0); + wc->stopdma = 0x0; } + spin_unlock(&wc->reglock); + + if (unlikely(test_bit(T4_CHECK_VPM, &wc->checkflag))) + tasklet_schedule(&wc->t4_tlet); + #ifndef ENABLE_WORKQUEUES - t4_pci_out(wc, WC_INTR, 0); + __t4_pci_out(wc, WC_INTR, 0); #endif #ifdef LINUX26 return IRQ_RETVAL(1); @@ -3243,8 +3150,8 @@ static void t4_vpm450_init(struct t4 *wc) #endif if (vpmdtmfsupport == -1) { - printk("VPM450: hardware DTMF disabled.\n"); - vpmdtmfsupport = 0; + printk("VPM450: hardware DTMF enabled.\n"); + vpmdtmfsupport = 1; } wc->vpm = T4_VPM_PRESENT; @@ -3453,7 +3360,7 @@ static int t4_hardware_init_1(struct t4 *wc, unsigned int cardflags) unsigned int version; version = t4_pci_in(wc, WC_VERSION); - printk("TE%dXXP version %08x, burst %s, slip debug: %s\n", wc->numspans, version, (!(cardflags & FLAG_BURST) && noburst) ? "OFF" : "ON", debugslips ? "ON" : "OFF"); + printk("TE%dXXP version %08x, burst %s\n", wc->numspans, version, (!(cardflags & FLAG_BURST) && noburst) ? "OFF" : "ON"); #ifdef ENABLE_WORKQUEUES printk("TE%dXXP running with work queues.\n", wc->numspans); #endif @@ -3550,9 +3457,7 @@ static int __devinit t4_launch(struct t4 *wc) spin_lock_irqsave(&wc->reglock, flags); __t4_set_timing_source(wc,4, 0, 0); spin_unlock_irqrestore(&wc->reglock, flags); -#ifdef ENABLE_TASKLETS - tasklet_init(&wc->t4_tlet, t4_tasklet, (unsigned long)wc); -#endif + tasklet_init(&wc->t4_tlet, t4_isr_bh, (unsigned long)wc); return 0; } @@ -3691,14 +3596,14 @@ static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_i #ifdef SUPPORT_GEN1 - if (request_irq(pdev->irq, (dt->flags & FLAG_2NDGEN) ? t4_interrupt_gen2 :t4_interrupt, ZAP_IRQ_SHARED_DISABLED, (wc->numspans == 2) ? "wct2xxp" : "wct4xxp", wc)) + if (request_irq(pdev->irq, (dt->flags & FLAG_2NDGEN) ? t4_interrupt_gen2 :t4_interrupt, SA_INTERRUPT | SA_SHIRQ, (wc->numspans == 2) ? "wct2xxp" : "wct4xxp", wc)) #else if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN)) { printk("This driver does not support 1st gen modules\n"); kfree(wc); return -ENODEV; } - if (request_irq(pdev->irq, t4_interrupt_gen2, ZAP_IRQ_SHARED_DISABLED, "t4xxp", wc)) + if (request_irq(pdev->irq, t4_interrupt_gen2, SA_INTERRUPT | SA_SHIRQ, "t4xxp", wc)) #endif { printk("t4xxp: Unable to request IRQ %d\n", pdev->irq); @@ -3902,8 +3807,6 @@ module_param(pedanticpci, int, 0600); 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); @@ -3920,8 +3823,6 @@ MODULE_PARM(pedanticpci, "i"); 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