[svn-commits] sruffell: branch linux/2.2 r6864 - in /linux/branches/2.2: ./ drivers/dahdi/ ...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Jul 21 13:11:58 CDT 2009


Author: sruffell
Date: Tue Jul 21 13:11:53 2009
New Revision: 6864

URL: http://svn.asterisk.org/svn-view/dahdi?view=rev&rev=6864
Log:
Merged revisions 6844,6852,6862-6863 via svnmerge from 
https://origsvn.digium.com/svn/dahdi/linux/trunk

........
  r6844 | sruffell | 2009-07-16 12:29:53 -0500 (Thu, 16 Jul 2009) | 10 lines
  
  wcte12xp: Disable vpmadt032 companding by default.
  
  This fixes a regression in 2.2.0 where certain configurations will fail
  patloop test or have repeated HDLC aborts because the VPMADT032 is modifying
  the clear channel or d channel data streams.  This restores the behavior to
  how it was in dahdi-linux 2.1.0.4.
  
  (closes issue #15498)
  Reported by: alecdavis
  Tested by: alecdavis
........
  r6852 | tzafrir | 2009-07-19 10:45:40 -0500 (Sun, 19 Jul 2009) | 12 lines
  
  tor2: allow using port4 as timing source
  
  Fix a silly regression introduced when strict check on the timing
  parameter was added (sync-1 is the array index, not sync itself. And 0
  is a special case).
  
  (closes issue #15408)
  Reported by: dferrer
  Patches:
        tor2-4th_sync.patch uploaded by dferrer (license 525)
........
  r6862 | sruffell | 2009-07-21 12:52:59 -0500 (Tue, 21 Jul 2009) | 4 lines
  
  Revert "wct4xxp, wcte11xp: Use the default configuration by default at startup."
  
  This reverts the change introduced by revision 6712.  This change can cause
  problems when there is a VPM module installed on the quad-span digital cards.
........
  r6863 | sruffell | 2009-07-21 12:53:02 -0500 (Tue, 21 Jul 2009) | 12 lines
  
  dahdi-base: Add support for core timing.
  
  This essentially moves the function of dahdi_dummy into the core of DAHDI.  It
  ensures that if DAHDI is loaded, it will always be able to provide timing,
  regardless of whether there are board drivers loaded, or if the board drivers
  are properly calling dahdi_receive.
  
  If there is a master span loaded which is calling dahdi_receive, then the
  behavior will be like it is normally.
  
  This functionality is off by default, uncomment CONFIG_DAHDI_CORE_TIMER in
  include/dahdi/config_dahdi.h in order to enable it.
........

Modified:
    linux/branches/2.2/   (props changed)
    linux/branches/2.2/drivers/dahdi/dahdi-base.c
    linux/branches/2.2/drivers/dahdi/tor2.c
    linux/branches/2.2/drivers/dahdi/wct4xxp/base.c
    linux/branches/2.2/drivers/dahdi/wcte11xp.c
    linux/branches/2.2/drivers/dahdi/wcte12xp/base.c
    linux/branches/2.2/include/dahdi/dahdi_config.h

Propchange: linux/branches/2.2/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Jul 21 13:11:53 2009
@@ -1,1 +1,1 @@
-/linux/trunk:1-6696,6712-6713,6715-6716,6718-6759,6761-6767,6769-6770,6772-6779,6781-6784,6786-6790,6792-6793,6795-6796,6798-6803
+/linux/trunk:1-6696,6712-6713,6715-6716,6718-6759,6761-6767,6769-6770,6772-6779,6781-6784,6786-6790,6792-6793,6795-6796,6798-6803,6844-6863

Modified: linux/branches/2.2/drivers/dahdi/dahdi-base.c
URL: http://svn.asterisk.org/svn-view/dahdi/linux/branches/2.2/drivers/dahdi/dahdi-base.c?view=diff&rev=6864&r1=6863&r2=6864
==============================================================================
--- linux/branches/2.2/drivers/dahdi/dahdi-base.c (original)
+++ linux/branches/2.2/drivers/dahdi/dahdi-base.c Tue Jul 21 13:11:53 2009
@@ -237,6 +237,19 @@
 	int	src;	/* source conf number */
 	int	dst;	/* dst conf number */
 } conf_links[DAHDI_MAX_CONF + 1];
+
+#ifdef CONFIG_DAHDI_CORE_TIMER
+
+static struct core_timer {
+	struct timer_list timer;
+	struct timespec start_interval;
+	atomic_t count;
+	atomic_t shutdown;
+	atomic_t last_count;
+} core_timer;
+
+#endif /* CONFIG_DAHDI_CORE_TIMER */
+
 
 
 /* There are three sets of conference sum accumulators. One for the current
@@ -2671,12 +2684,22 @@
 	return res;
 }
 
+static int can_open_timer(void)
+{
+#ifdef CONFIG_DAHDI_CORE_TIMER
+	return 1;
+#else
+	return maxspans > 0;
+#endif
+}
+
 static struct dahdi_chan *dahdi_alloc_pseudo(void)
 {
 	struct dahdi_chan *pseudo;
 
-	/* Don't allow /dev/dahdi/pseudo to open if there are no spans */
-	if (maxspans < 1)
+	/* Don't allow /dev/dahdi/pseudo to open if there is not a timing
+	 * source. */
+	if (!can_open_timer())
 		return NULL;
 
 	if (!(pseudo = kzalloc(sizeof(*pseudo), GFP_KERNEL)))
@@ -2734,7 +2757,7 @@
 		return -ENXIO;
 	}
 	if (unit == 253) {
-		if (maxspans) {
+		if (can_open_timer()) {
 			return dahdi_timing_open(inode, file);
 		} else {
 			return -ENXIO;
@@ -2743,16 +2766,13 @@
 	if (unit == 254)
 		return dahdi_chan_open(inode, file);
 	if (unit == 255) {
-		if (maxspans) {
-			chan = dahdi_alloc_pseudo();
-			if (chan) {
-				file->private_data = chan;
-				return dahdi_specchan_open(inode, file, chan->channo);
-			} else {
-				return -ENXIO;
-			}
-		} else
+		chan = dahdi_alloc_pseudo();
+		if (chan) {
+			file->private_data = chan;
+			return dahdi_specchan_open(inode, file, chan->channo);
+		} else {
 			return -ENXIO;
+		}
 	}
 	return dahdi_specchan_open(inode, file, unit);
 }
@@ -7748,12 +7768,207 @@
 	return 0;
 }
 
+static void process_masterspan(void)
+{
+	unsigned long flags;
+	int x, y, z;
+
+#ifdef CONFIG_DAHDI_CORE_TIMER
+	/* We increment the calls since start here, so that if we switch over
+	 * to the core timer, we know how many times we need to call
+	 * process_masterspan in order to catch up since this function needs
+	 * to be called 1000 times per second. */
+	atomic_inc(&core_timer.count);
+#endif
+	/* Hold the big zap lock for the duration of major
+	   activities which touch all sorts of channels */
+	spin_lock_irqsave(&bigzaplock, flags);
+	read_lock(&chan_lock);
+	/* Process any timers */
+	process_timers();
+	/* If we have dynamic stuff, call the ioctl with 0,0 parameters to
+	   make it run */
+	if (dahdi_dynamic_ioctl)
+		dahdi_dynamic_ioctl(0, 0);
+
+	for (x = 1; x < maxchans; x++) {
+		if (chans[x] && chans[x]->confmode &&
+		    !(chans[x]->flags & DAHDI_FLAG_PSEUDO)) {
+			u_char *data;
+			spin_lock(&chans[x]->lock);
+			data = __buf_peek(&chans[x]->confin);
+			__dahdi_receive_chunk(chans[x], data);
+			if (data) {
+				__buf_pull(&chans[x]->confin, NULL, chans[x],
+					   "confreceive");
+			}
+			spin_unlock(&chans[x]->lock);
+		}
+	}
+	/* This is the master channel, so make things switch over */
+	rotate_sums();
+	/* do all the pseudo and/or conferenced channel receives (getbuf's) */
+	for (x = 1; x < maxchans; x++) {
+		if (chans[x] && (chans[x]->flags & DAHDI_FLAG_PSEUDO)) {
+			spin_lock(&chans[x]->lock);
+			__dahdi_transmit_chunk(chans[x], NULL);
+			spin_unlock(&chans[x]->lock);
+		}
+	}
+	if (maxlinks) {
+#ifdef CONFIG_DAHDI_MMX
+		dahdi_kernel_fpu_begin();
+#endif
+		/* process all the conf links */
+		for (x = 1; x <= maxlinks; x++) {
+			/* if we have a destination conf */
+			z = confalias[conf_links[x].dst];
+			if (z) {
+				y = confalias[conf_links[x].src];
+				if (y)
+					ACSS(conf_sums[z], conf_sums[y]);
+			}
+		}
+#ifdef CONFIG_DAHDI_MMX
+		dahdi_kernel_fpu_end();
+#endif
+	}
+	/* do all the pseudo/conferenced channel transmits (putbuf's) */
+	for (x = 1; x < maxchans; x++) {
+		if (chans[x] && (chans[x]->flags & DAHDI_FLAG_PSEUDO)) {
+			unsigned char tmp[DAHDI_CHUNKSIZE];
+			spin_lock(&chans[x]->lock);
+			__dahdi_getempty(chans[x], tmp);
+			__dahdi_receive_chunk(chans[x], tmp);
+			spin_unlock(&chans[x]->lock);
+		}
+	}
+	for (x = 1; x < maxchans; x++) {
+		if (chans[x] && chans[x]->confmode &&
+		    !(chans[x]->flags & DAHDI_FLAG_PSEUDO)) {
+			u_char *data;
+			spin_lock(&chans[x]->lock);
+			data = __buf_pushpeek(&chans[x]->confout);
+			__dahdi_transmit_chunk(chans[x], data);
+			if (data)
+				__buf_push(&chans[x]->confout, NULL,
+					   "conftransmit");
+			spin_unlock(&chans[x]->lock);
+		}
+	}
+#ifdef	DAHDI_SYNC_TICK
+	for (x = 0; x < maxspans; x++) {
+		struct dahdi_span *const s = spans[x];
+		if (s && s->sync_tick)
+			s->sync_tick(s, s == master);
+	}
+#endif
+	read_unlock(&chan_lock);
+	spin_unlock_irqrestore(&bigzaplock, flags);
+}
+
+#ifndef CONFIG_DAHDI_CORE_TIMER
+
+static void coretimer_init(void)
+{
+	return;
+}
+
+static void coretimer_cleanup(void)
+{
+	return;
+}
+
+#else
+
+static unsigned long core_diff_ms(struct timespec *t0, struct timespec *t1)
+{
+	long nanosec, sec;
+	unsigned long ms;
+	sec = (t1->tv_sec - t0->tv_sec);
+	nanosec = (t1->tv_nsec - t0->tv_nsec);
+	while (nanosec >= NSEC_PER_SEC) {
+		nanosec -= NSEC_PER_SEC;
+		++sec;
+	}
+	while (nanosec < 0) {
+		nanosec += NSEC_PER_SEC;
+		--sec;
+	}
+	ms = (sec * 1000) + (nanosec / 1000000L);
+	return ms;
+}
+
+static void coretimer_func(unsigned long param)
+{
+	unsigned long ms_since_start;
+	struct timespec now;
+	const unsigned long MAX_INTERVAL = 100000L;
+	const unsigned long FOURMS_INTERVAL = HZ/250;
+	const unsigned long ONESEC_INTERVAL = HZ;
+
+	now = current_kernel_time();
+
+	if (atomic_read(&core_timer.count) ==
+	    atomic_read(&core_timer.last_count)) {
+
+		/* This is the code path if a board driver is not calling
+		 * dahdi_receive, and therefore the core of dahdi needs to
+		 * perform the master span processing itself. */
+
+		if (!atomic_read(&core_timer.shutdown))
+			mod_timer(&core_timer.timer, jiffies + FOURMS_INTERVAL);
+
+		ms_since_start = core_diff_ms(&core_timer.start_interval, &now);
+		while (ms_since_start > atomic_read(&core_timer.count))
+			process_masterspan();
+
+		if (ms_since_start > MAX_INTERVAL) {
+			atomic_set(&core_timer.count, 0);
+			atomic_set(&core_timer.last_count, 0);
+			core_timer.start_interval = now;
+		} else {
+			atomic_set(&core_timer.last_count,
+				   atomic_read(&core_timer.count));
+		}
+
+	} else {
+
+		/* It looks like a board driver is calling dahdi_receive. We
+		 * will just check again in a second. */
+		atomic_set(&core_timer.count, 0);
+		atomic_set(&core_timer.last_count, 0);
+		core_timer.start_interval = now;
+		if (!atomic_read(&core_timer.shutdown))
+			mod_timer(&core_timer.timer, jiffies + ONESEC_INTERVAL);
+	}
+}
+
+static void coretimer_init(void)
+{
+	init_timer(&core_timer.timer);
+	core_timer.timer.function = coretimer_func;
+	core_timer.start_interval = current_kernel_time();
+	core_timer.timer.expires = jiffies + HZ;
+	atomic_set(&core_timer.count, 0);
+	atomic_set(&core_timer.shutdown, 0);
+	add_timer(&core_timer.timer);
+}
+
+static void coretimer_cleanup(void)
+{
+	atomic_set(&core_timer.shutdown, 1);
+	del_timer_sync(&core_timer.timer);
+}
+
+#endif /* CONFIG_DAHDI_CORE_TIMER */
+
+
 int dahdi_receive(struct dahdi_span *span)
 {
 	int x,y,z;
 	unsigned long flags;
 
-#if 1
 #ifdef CONFIG_DAHDI_WATCHDOG
 	span->watchcounter--;
 #endif
@@ -7833,87 +8048,9 @@
 		}
 	}
 
-	if (span == master) {
-		/* Hold the big zap lock for the duration of major
-		   activities which touch all sorts of channels */
-		spin_lock_irqsave(&bigzaplock, flags);
-		read_lock(&chan_lock);
-		/* Process any timers */
-		process_timers();
-		/* If we have dynamic stuff, call the ioctl with 0,0 parameters to
-		   make it run */
-		if (dahdi_dynamic_ioctl)
-			dahdi_dynamic_ioctl(0,0);
-		for (x=1;x<maxchans;x++) {
-			if (chans[x] && chans[x]->confmode && !(chans[x]->flags & DAHDI_FLAG_PSEUDO)) {
-				u_char *data;
-				spin_lock(&chans[x]->lock);
-				data = __buf_peek(&chans[x]->confin);
-				__dahdi_receive_chunk(chans[x], data);
-				if (data)
-					__buf_pull(&chans[x]->confin, NULL,chans[x], "confreceive");
-				spin_unlock(&chans[x]->lock);
-			}
-		}
-		/* This is the master channel, so make things switch over */
-		rotate_sums();
-		/* do all the pseudo and/or conferenced channel receives (getbuf's) */
-		for (x=1;x<maxchans;x++) {
-			if (chans[x] && (chans[x]->flags & DAHDI_FLAG_PSEUDO)) {
-				spin_lock(&chans[x]->lock);
-				__dahdi_transmit_chunk(chans[x], NULL);
-				spin_unlock(&chans[x]->lock);
-			}
-		}
-		if (maxlinks) {
-#ifdef CONFIG_DAHDI_MMX
-			dahdi_kernel_fpu_begin();
-#endif
-			  /* process all the conf links */
-			for(x = 1; x <= maxlinks; x++) {
-				  /* if we have a destination conf */
-				if (((z = confalias[conf_links[x].dst]) > 0) &&
-				    ((y = confalias[conf_links[x].src]) > 0)) {
-					ACSS(conf_sums[z], conf_sums[y]);
-				}
-			}
-#ifdef CONFIG_DAHDI_MMX
-			kernel_fpu_end();
-#endif
-		}
-		/* do all the pseudo/conferenced channel transmits (putbuf's) */
-		for (x=1;x<maxchans;x++) {
-			if (chans[x] && (chans[x]->flags & DAHDI_FLAG_PSEUDO)) {
-				unsigned char tmp[DAHDI_CHUNKSIZE];
-				spin_lock(&chans[x]->lock);
-				__dahdi_getempty(chans[x], tmp);
-				__dahdi_receive_chunk(chans[x], tmp);
-				spin_unlock(&chans[x]->lock);
-			}
-		}
-		for (x=1;x<maxchans;x++) {
-			if (chans[x] && chans[x]->confmode && !(chans[x]->flags & DAHDI_FLAG_PSEUDO)) {
-				u_char *data;
-				spin_lock(&chans[x]->lock);
-				data = __buf_pushpeek(&chans[x]->confout);
-				__dahdi_transmit_chunk(chans[x], data);
-				if (data)
-					__buf_push(&chans[x]->confout, NULL, "conftransmit");
-				spin_unlock(&chans[x]->lock);
-			}
-		}
-#ifdef	DAHDI_SYNC_TICK
-		for (x=0;x<maxspans;x++) {
-			struct dahdi_span	*s = spans[x];
-
-			if (s && s->sync_tick)
-				s->sync_tick(s, s == master);
-		}
-#endif
-		read_unlock(&chan_lock);
-		spin_unlock_irqrestore(&bigzaplock, flags);
-	}
-#endif
+	if (span == master)
+		process_masterspan();
+
 	return 0;
 }
 
@@ -8045,12 +8182,15 @@
 #ifdef CONFIG_DAHDI_WATCHDOG
 	watchdog_init();
 #endif
+	coretimer_init();
 	return res;
 }
 
 static void __exit dahdi_cleanup(void)
 {
 	int x;
+
+	coretimer_cleanup();
 
 	CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, 253)); /* timer */
 	CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, 254)); /* channel */

Modified: linux/branches/2.2/drivers/dahdi/tor2.c
URL: http://svn.asterisk.org/svn-view/dahdi/linux/branches/2.2/drivers/dahdi/tor2.c?view=diff&rev=6864&r1=6863&r2=6864
==============================================================================
--- linux/branches/2.2/drivers/dahdi/tor2.c (original)
+++ linux/branches/2.2/drivers/dahdi/tor2.c Tue Jul 21 13:11:53 2009
@@ -200,7 +200,7 @@
 	if (debug)
 		printk(KERN_INFO "Tor2: Configuring span %d\n", span->spanno);
 
-	if ((lc->sync < 0) || (lc->sync >= SPANS_PER_CARD)) {
+	if ((lc->sync < 0) || (lc->sync > SPANS_PER_CARD)) {
 		printk(KERN_WARNING "%s %d: invalid span timing value %d.\n",
 				THIS_MODULE->name, span->spanno, lc->sync);
 		return -EINVAL;

Modified: linux/branches/2.2/drivers/dahdi/wct4xxp/base.c
URL: http://svn.asterisk.org/svn-view/dahdi/linux/branches/2.2/drivers/dahdi/wct4xxp/base.c?view=diff&rev=6864&r1=6863&r2=6864
==============================================================================
--- linux/branches/2.2/drivers/dahdi/wct4xxp/base.c (original)
+++ linux/branches/2.2/drivers/dahdi/wct4xxp/base.c Tue Jul 21 13:11:53 2009
@@ -6,7 +6,7 @@
  * written by Jim Dixon <jim at lambdatel.com>.
  *
  * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
- * Copyright (C) 2001-2009, Digium, Inc.
+ * Copyright (C) 2001-2005, Digium, Inc.
  *
  * All rights reserved.
  *
@@ -3547,12 +3547,6 @@
 	__t4_set_timing_source(wc,4, 0, 0);
 	spin_unlock_irqrestore(&wc->reglock, flags);
 	tasklet_init(&wc->t4_tlet, t4_isr_bh, (unsigned long)wc);
-
-	/* Start the first span on the card with the default configuration so
-	 * that it may provide timing to Asterisk before being properly
-	 * configured. */
-	t4_startup(&wc->tspans[0]->span);
-
 	return 0;
 }
 

Modified: linux/branches/2.2/drivers/dahdi/wcte11xp.c
URL: http://svn.asterisk.org/svn-view/dahdi/linux/branches/2.2/drivers/dahdi/wcte11xp.c?view=diff&rev=6864&r1=6863&r2=6864
==============================================================================
--- linux/branches/2.2/drivers/dahdi/wcte11xp.c (original)
+++ linux/branches/2.2/drivers/dahdi/wcte11xp.c Tue Jul 21 13:11:53 2009
@@ -5,7 +5,7 @@
  *            Matthew Fredrickson <creslin at digium.com>
  *            William Meadows <wmeadows at digium.com>
  *
- * Copyright (C) 2004-2009, Digium, Inc.
+ * Copyright (C) 2004, Digium, Inc.
  *
  * All rights reserved.
  */
@@ -1013,11 +1013,6 @@
 		printk(KERN_NOTICE "Unable to register span with DAHDI\n");
 		return -1;
 	}
-
-	/* Start off with the defaults so this card can provide timing to
-	 * Asterisk before being properly configured. */
-	t1xxp_startup(&wc->span);
-
 	return 0;
 }
 

Modified: linux/branches/2.2/drivers/dahdi/wcte12xp/base.c
URL: http://svn.asterisk.org/svn-view/dahdi/linux/branches/2.2/drivers/dahdi/wcte12xp/base.c?view=diff&rev=6864&r1=6863&r2=6864
==============================================================================
--- linux/branches/2.2/drivers/dahdi/wcte12xp/base.c (original)
+++ linux/branches/2.2/drivers/dahdi/wcte12xp/base.c Tue Jul 21 13:11:53 2009
@@ -1317,7 +1317,7 @@
 	chanconfig->MuteToneB = Disabled;
 	chanconfig->FaxCngDetB = Disabled;
 
-	chanconfig->SoftwareCompand = cmpPCMU;
+	chanconfig->SoftwareCompand = cmpNone;
 
 	chanconfig->FrameRate = rate10ms;
 

Modified: linux/branches/2.2/include/dahdi/dahdi_config.h
URL: http://svn.asterisk.org/svn-view/dahdi/linux/branches/2.2/include/dahdi/dahdi_config.h?view=diff&rev=6864&r1=6863&r2=6864
==============================================================================
--- linux/branches/2.2/include/dahdi/dahdi_config.h (original)
+++ linux/branches/2.2/include/dahdi/dahdi_config.h Tue Jul 21 13:11:53 2009
@@ -115,6 +115,12 @@
  */
 /* #define CONFIG_CAC_GROUNDSTART */
 
+/*
+ * Define CONFIG_DAHDI_CORE_TIMER if you would like dahdi to always provide a
+ * timing source regardless of which spans / drivers are configured.
+ */
+/* #define CONFIG_DAHDI_CORE_TIMER */
+
 /* 
  * Uncomment if you happen have an early TDM400P Rev H which 
  * sometimes forgets its PCI ID to have wcfxs match essentially all
@@ -167,4 +173,6 @@
  */
 /* #define	OPTIMIZE_CHANMUTE */
 
+
+
 #endif




More information about the svn-commits mailing list