Update of /usr/cvsroot/zaptel
In directory mongoose.digium.com:/tmp/cvs-serv7507

Modified Files:
      Tag: v1-0
        wct4xxp.c 
Log Message:
backport all fixes from HEAD


Index: wct4xxp.c
===================================================================
RCS file: /usr/cvsroot/zaptel/wct4xxp.c,v
retrieving revision 1.51.2.14
retrieving revision 1.51.2.15
diff -u -d -r1.51.2.14 -r1.51.2.15
--- wct4xxp.c   18 Aug 2005 00:15:59 -0000      1.51.2.14
+++ wct4xxp.c   22 Aug 2005 15:32:55 -0000      1.51.2.15
@@ -56,7 +56,12 @@
 
 /* Work queues are a way to better distribute load on SMP systems */
 #ifdef LINUX26
-#define ENABLE_WORKQUEUES
+/*
+ * Work queues can significantly improve performance and scalability
+ * on multi-processor machines, but requires bypassing some kernel
+ * API's, so it's not guaranteed to be compatible with all kernels.
+ */
+/* #define ENABLE_WORKQUEUES */
 #endif
 
 /* Enable prefetching may help performance */
@@ -169,8 +174,15 @@
 static int alarmdebounce = 0;
 #ifdef VPM_SUPPORT
 static int vpmsupport = 1;
+#define VPM_DEFAULT_DTMFTHRESHOLD 1000
+static int dtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
+static int lastdtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
 #endif
-static int noburst = 0;
+/* Enabling bursting can more efficiently utilize PCI bus bandwidth, but
+   can also cause PCI bus starvation, especially in combination with other
+   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;
 
@@ -310,6 +322,7 @@
 
 #ifdef VPM_SUPPORT
 static void t4_vpm_init(struct t4 *wc);
+static void t4_vpm_set_dtmf_threshold(struct t4 *wc, unsigned int threshold);
 #endif
 static void __set_clear(struct t4 *wc, int span);
 static int t4_startup(struct zt_span *span);
@@ -523,9 +536,12 @@
        spin_unlock_irqrestore(&wc->reglock, flags);
 }
 
+static const char vpm_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', 
'9', 'A', 'B', 'C', 'D', '*', '#'};
+
 static void __t4_check_vpm(struct t4 *wc, unsigned int newio)
 {
        unsigned int digit, regval = 0;
+       unsigned int regbyte;
        int x, i;
        short energy;
        static unsigned int lastio = 0;
@@ -541,27 +557,22 @@
                        continue;
                ts = wc->tspans[x%4];
                /* Start of DTMF detection process */   
-               regval = __t4_vpm_in(wc, x, 0xb8);
-               __t4_vpm_out(wc, x, 0xb8, regval); /* Write 1 to clear */
-               regval = regval << 8;
-               regval |= __t4_vpm_in(wc, x, 0xb9);
-               __t4_vpm_out(wc, x, 0xb9, regval & 0xff);
+               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);
+               regval |= regbyte;
 
                for(i = 0; (i < MAX_DTMF_DET) && regval; i++) {
                        if(regval & 0x0001) {
                                int channel = (i << 1) + (x >> 2);
                                int base = channel - 1;
+
                                if (!wc->t1e1)
                                        base -= 4;
-                               digit = __t4_vpm_in(wc, x, 0xa8 + i);
-                               if (digit < 10) 
-                                       digit += '0'; 
-                               else if (digit < 0xe) 
-                                       digit += 'A' - 0xe; 
-                               else if (digit == 0xe) 
-                                       digit = '*';
-                               else if (digit == 0xf) 
-                                       digit = '#';
+                               regbyte = __t4_vpm_in(wc, x, 0xa8 + i);
+                               digit = vpm_digits[regbyte];
                                energy = __t4_vpm_in(wc, x, 0x58 + channel);
                                energy = ZT_XLAW(energy, ts->chans);
                                ts->dtmfactive |= (1 << base);
@@ -571,10 +582,6 @@
                                                
zt_qevent_lock(&ts->span.chans[base], (ZT_EVENT_DTMFUP | ts->dtmfdigit[base]));
                                }
                                ts->dtmfdigit[base] = digit;
-                               if (ts->dtmfdigit[base]) {
-                                       if (ts->dtmfmask & (1 << base))
-                                               
zt_qevent_lock(&ts->span.chans[base], (ZT_EVENT_DTMFUP | ts->dtmfdigit[base]));
-                               }
                                if (ts->dtmfmask & (1 << base))
                                        zt_qevent_lock(&ts->span.chans[base], 
(ZT_EVENT_DTMFDOWN | digit));
                                if (ts->dtmfmutemask & (1 << base)) {
@@ -584,7 +591,7 @@
                                        int y;
                                        spin_lock_irqsave(&chan->lock, flags);
                                        for (y=0;y<chan->numbufs;y++) {
-                                               if (chan->readidx[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, 
flags);
@@ -719,9 +726,17 @@
        struct t4_span *ts = wc->tspans[chan->span->offset];
 #endif
 
+#ifdef VPM_SUPPORT
+       if (dtmfthreshold == 0)
+               dtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
+       if (lastdtmfthreshold != dtmfthreshold) {
+               lastdtmfthreshold = dtmfthreshold;
+               t4_vpm_set_dtmf_threshold(wc, dtmfthreshold);
+       }
+#endif
+
        switch(cmd) {
        case WCT4_GET_REGS:
-               wc = chan->pvt;
                for (x=0;x<NUM_PCI;x++)
                        regs.pci[x] = t4_pci_in(wc, x);
                for (x=0;x<NUM_REGS;x++)
@@ -737,7 +752,6 @@
        case ZT_TONEDETECT:
                if (get_user(j, (int *)data))
                        return -EFAULT;
-               wc = chan->pvt;
                if (!wc->vpm)
                        return -ENOSYS;
                if (j & ZT_TONEDETECT_ON)
@@ -2283,25 +2297,36 @@
 #endif
 
 #ifdef VPM_SUPPORT
+static void t4_vpm_set_dtmf_threshold(struct t4 *wc, unsigned int threshold)
+{
+       unsigned int x;
+
+       for (x = 0; x < 8; x++) {
+               t4_vpm_out(wc, x, 0xC4, (threshold >> 8) & 0xFF);
+               t4_vpm_out(wc, x, 0xC5, (threshold & 0xFF));
+       }
+       printk("VPM: DTMF threshold set to %d\n", threshold);
+}
+
 static void t4_vpm_init(struct t4 *wc)
 {
        unsigned char reg;
        unsigned int mask;
        unsigned int ver;
-       int i,x,y;
+       unsigned int i, x, y;
+
        if (!vpmsupport) {
                printk("VPM: Support Disabled\n");
                return;
        }
 
        for (x=0;x<8;x++) {
-               struct t4_span *ts = wc->tspans[x & 0x3];
+               int spanno = x & 0x3;
+               struct t4_span *ts = wc->tspans[spanno];
+
                ver = t4_vpm_in(wc, x, 0x1a0); /* revision */
                if (ver != 0x26) {
-                       if (x)
-                               printk("VPM: Inopperable\n");
-                       else
-                               printk("VPM: Not Present\n");
+                       printk("VPM: %s\n", x ? "Inoperable" : "Not Present");
                        return;
                }       
 
@@ -2317,36 +2342,33 @@
                t4_vpm_out(wc, x, 0x1a3, reg & ~2);
 
                /* Setup timeslots */
-               t4_vpm_out(wc, x, 0x02f, 0x20 | ((x%4) << 3)); 
-               if (x < 4)
-                       mask = 0x55555555;
-               else
-                       mask = 0xaaaaaaaa;
+               t4_vpm_out(wc, x, 0x02f, 0x20 | (spanno << 3)); 
 
                /* Setup Echo length (128 taps) */
                t4_vpm_out(wc, x, 0x022, 0x00);
                t4_vpm_out(wc, x, 0x023, 0x7f);
                
-               /* Setup the tdm channel masks for all LV's*/
-               for (i=0;i<4;i++)
-                       t4_vpm_out(wc, x, 0x30+i, (mask >> (i << 3)) & 0xff);
+               /* Setup the tdm channel masks for all chips*/
+               mask = (x < 4) ? 0x55555555 : 0xaaaaaaaa;
+               for (i = 0; i < 4; i++)
+                       t4_vpm_out(wc, x, 0x30 + i, (mask >> (i << 3)) & 0xff);
 
                /* Setup convergence rate */
                reg = t4_vpm_in(wc,x,0x20);
                reg &= 0xE0;
                if (ts->spantype == TYPE_E1) {
                        if (x < 4)
-                               printk("VPM: Span %d A-law mode\n", x & 0x3);
+                               printk("VPM: Span %d A-law mode\n", spanno);
                        reg |= 0x01;
                } else {
                        if (x < 4)
-                               printk("VPM: Span %d U-law mode\n", x & 0x3);
+                               printk("VPM: Span %d U-law mode\n", spanno);
                        reg &= ~0x01;
                }
                t4_vpm_out(wc,x,0x20,(reg | 0x20));
                
                /* Initialize echo cans */
-               for (i = 0 ; i < MAX_TDM_CHAN ; i++) {
+               for (i = 0 ; i < MAX_TDM_CHAN; i++) {
                        if (mask & (0x00000001 << i))
                                t4_vpm_out(wc,x,i,0x00);
                }
@@ -2366,25 +2388,21 @@
                                t4_vpm_out(wc,x,0x78 + i,0x01);
                }
       
-        /* Enable DTMF detectors */
-               for (i=0;i<MAX_DTMF_DET;i++) {
-                       if(x < 4)
-                               t4_vpm_out(wc, x, 0x98+i,(i*2)|0x40);
-                       else
-                               t4_vpm_out(wc, x, 0x98+i, ((i*2)+1)|0x40);
-        }
-               for (i=0xb8;i<0xbe;i++)
-                       t4_vpm_out(wc, x, i, 0xff);
-               if(x < 4) {
-                       for(i=0;i<4;i++)
-                               t4_vpm_out(wc, x, 0xc0+i, 0x55);
-               } else {
-                       for(i = 0; i < 4; i++)
-                               t4_vpm_out(wc, x, 0xc0+i, 0xaa);
+               /* set DTMF detection threshold */
+               t4_vpm_set_dtmf_threshold(wc, dtmfthreshold);
+
+               /* Enable DTMF detectors */
+               for (i = 0; i < MAX_DTMF_DET; i++) {
+                       t4_vpm_out(wc, x, 0x98 + i, 0x40 | (i * 2) | ((x < 4) ? 
0 : 1));
                }
-   } 
-   printk("VPM: Present and operational\n");
-   wc->vpm = T4_VPM_PRESENT;
+               for (i = 0xB8; i < 0xBE; i++)
+                       t4_vpm_out(wc, x, i, 0xFF);
+               for (i = 0xC0; i < 0xC4; i++)
+                       t4_vpm_out(wc, x, i, (x < 4) ? 0x55 : 0xAA);
+
+       } 
+       printk("VPM: Present and operational\n");
+       wc->vpm = T4_VPM_PRESENT;
 }
 
 #endif
@@ -2851,7 +2869,7 @@
 
 
 MODULE_AUTHOR("Mark Spencer");
-MODULE_DESCRIPTION("Unified TE4XXP/TE2XXP PCI Driver");
+MODULE_DESCRIPTION("Unified TE4XXP-TE2XXP PCI Driver");
 #ifdef MODULE_LICENSE
 MODULE_LICENSE("GPL");
 #endif
@@ -2867,6 +2885,7 @@
 module_param(j1mode, int, 0600);
 #ifdef VPM_SUPPORT
 module_param(vpmsupport, int, 0600);
+module_param(dtmfthreshold, int, 0600);
 #endif
 #else
 MODULE_PARM(debug, "i");
@@ -2880,6 +2899,7 @@
 MODULE_PARM(j1mode, "i");
 #ifdef VPM_SUPPORT
 MODULE_PARM(vpmsupport, "i");
+MODULE_PARM(dtmfthreshold, "i");
 #endif
 #endif
 
@@ -2887,4 +2907,3 @@
 
 module_init(t4_init);
 module_exit(t4_cleanup);
-

_______________________________________________
Asterisk-Cvs mailing list
[email protected]
http://lists.digium.com/mailman/listinfo/asterisk-cvs

Reply via email to