[svn-commits] tzafrir: branch linux/tzafrir/sysfs r8115 - in /linux/team/tzafrir/sysfs: ./ ...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Feb 25 17:36:15 CST 2010


Author: tzafrir
Date: Thu Feb 25 17:36:11 2010
New Revision: 8115

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=8115
Log:
Merged revisions 8103-8104,8110-8111 via svnmerge from 
http://svn.digium.com/svn/dahdi/linux/trunk

........
  r8103 | sruffell | 2010-02-25 21:10:02 +0200 (Thu, 25 Feb 2010) | 26 lines
  
  dahdi_dynamic: Add TDMoE Multi-Frame support.
  
  Add TDMoE Multi-Frame support as described in the article at the following URL:
  
  http://www.thrallingpenguin.com/articles/tdmoe-mf.htm
  
  TDMoE-MF is known to be implemented in hardware solutions from Redfone
  Communications.
  
  This patch additionally implements RCU within dahdi_dynamic to decrease lock
  contention, latency, and context switching. Because of the use of RCU locking,
  all prior known issues with loading and unloading of the modules are resolved,
  providing the spans are shutdown with "dahdi_cfg -s".
  
  It also contains an attempt, which works, at fixing a kernel change with
  skb_linearize(). The use of kernel version number does not work with SuSE SLES
  10, as it appears they have backported the 2.6.18 change in to their 2.6.16
  version.
  
  This merges in the work Jbenden did at:
  http://svn.digium.com/svn/dahdi/team/jbenden/tdmoe-mf@8102
  
  (issue #13483)
  Patch by: JBenden
  Reported by: JBenden
  Tested by: JBenden
........
  r8104 | sruffell | 2010-02-25 21:10:05 +0200 (Thu, 25 Feb 2010) | 3 lines
  
  dahdi_dynamic: trivial checkpatch.pl formatting changes.
  
  Just removing the errors only.  I left the warnings for now.
........
  r8110 | sruffell | 2010-02-26 00:16:37 +0200 (Fri, 26 Feb 2010) | 1 line
  
  dahdi_dynamic: Another trivial formatting change.
........
  r8111 | sruffell | 2010-02-26 00:16:40 +0200 (Fri, 26 Feb 2010) | 5 lines
  
  voicebus: Only use request_module_nowait on kernels >= 2.6.30.
  
  Request_module_nowait is only useful when asynchronous initialization is used
  (committed to trunk in r8094), and that can only happen in kernel version after
  2.6.30.  Some earlier kernels do not have the request_module_nowait interface.
........

Added:
    linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_dynamic_ethmf.c
      - copied unchanged from r8111, linux/trunk/drivers/dahdi/dahdi_dynamic_ethmf.c
Modified:
    linux/team/tzafrir/sysfs/   (props changed)
    linux/team/tzafrir/sysfs/drivers/dahdi/Kbuild
    linux/team/tzafrir/sysfs/drivers/dahdi/Kconfig
    linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_dynamic.c
    linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_dynamic_eth.c
    linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/voicebus.c
    linux/team/tzafrir/sysfs/include/dahdi/kernel.h

Propchange: linux/team/tzafrir/sysfs/
------------------------------------------------------------------------------
    automerge = YES

Propchange: linux/team/tzafrir/sysfs/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Feb 25 17:36:11 2010
@@ -1,1 +1,1 @@
-/linux/trunk:1-8101
+/linux/trunk:1-8114

Modified: linux/team/tzafrir/sysfs/drivers/dahdi/Kbuild
URL: http://svnview.digium.com/svn/dahdi/linux/team/tzafrir/sysfs/drivers/dahdi/Kbuild?view=diff&rev=8115&r1=8114&r2=8115
==============================================================================
--- linux/team/tzafrir/sysfs/drivers/dahdi/Kbuild (original)
+++ linux/team/tzafrir/sysfs/drivers/dahdi/Kbuild Thu Feb 25 17:36:11 2010
@@ -3,6 +3,7 @@
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC)		+= dahdi_dynamic.o
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_LOC)	+= dahdi_dynamic_loc.o
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETH)	+= dahdi_dynamic_eth.o
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETHMF)	+= dahdi_dynamic_ethmf.o
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TRANSCODE)		+= dahdi_transcode.o
 
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT4XXP)		+= wct4xxp/
@@ -61,6 +62,14 @@
 # as part of an ALSA backport. TODO: Any better way to detect that?
 ifeq (1,$(shell fgrep -q ' hrtimer_set_expires' include/linux/hrtimer.h 2>/dev/null && echo 1))
 EXTRA_CFLAGS+=-DHAVE_HRTIMER_ACCESSORS=1
+endif
+
+# In 2.6.18 skb_linearize changed; however, some distros backported the change
+ifneq (,$(wildcard $(srctree)/include/linux/skbuff.h))
+ifeq ($(shell grep "skb_linearize.*(.*, .* gfp)" $(srctree)/include/linux/skbuff.h),)
+CFLAGS_dahdi_dynamic_eth.o := -DNEW_SKB_LINEARIZE
+CFLAGS_dahdi_dynamic_ethmf.o := -DNEW_SKB_LINEARIZE
+endif
 endif
 
 dahdi-objs := dahdi-base.o dahdi-sysfs.o dahdi-sysfs-chan.o

Modified: linux/team/tzafrir/sysfs/drivers/dahdi/Kconfig
URL: http://svnview.digium.com/svn/dahdi/linux/team/tzafrir/sysfs/drivers/dahdi/Kconfig?view=diff&rev=8115&r1=8114&r2=8115
==============================================================================
--- linux/team/tzafrir/sysfs/drivers/dahdi/Kconfig (original)
+++ linux/team/tzafrir/sysfs/drivers/dahdi/Kconfig Thu Feb 25 17:36:11 2010
@@ -225,6 +225,19 @@
 
 	  If unsure, say Y.
 
+config DAHDI_DYNAMIC_ETHMF
+	tristate "Ethernet (TDMoE) Multi-Frame Span Support"
+	depends on DAHDI && DAHDI_DYNAMIC
+	default DAHDI
+	---help---
+	  This module provides support for spans over Ethernet,
+	  using the TDMoE-Multi-Frame protocol.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called dahdi_dynamic_ethmf.
+
+	  If unsure, say Y.
+
 config DAHDI_DYNAMIC_LOC
 	tristate "Local (loopback) Span Support"
 	depends on DAHDI && DAHDI_DYNAMIC

Modified: linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_dynamic.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_dynamic.c?view=diff&rev=8115&r1=8114&r2=8115
==============================================================================
--- linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_dynamic.c (original)
+++ linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_dynamic.c Thu Feb 25 17:36:11 2010
@@ -31,7 +31,6 @@
 #include <linux/kmod.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
-#include <linux/vmalloc.h>
 #include <linux/moduleparam.h>
 
 #include <dahdi/kernel.h>
@@ -70,15 +69,18 @@
 
 #define ZTD_FLAG_YELLOW_ALARM		(1 << 0)
 #define ZTD_FLAG_SIGBITS_PRESENT	(1 << 1)
-#define ZTD_FLAG_LOOPBACK			(1 << 2)
-
-#define ERR_NSAMP					(1 << 16)
-#define ERR_NCHAN					(1 << 17)
-#define ERR_LEN						(1 << 18)
+#define ZTD_FLAG_LOOPBACK		(1 << 2)
+
+#define ERR_NSAMP			(1 << 16)
+#define ERR_NCHAN			(1 << 17)
+#define ERR_LEN				(1 << 18)
 
 EXPORT_SYMBOL(dahdi_dynamic_register);
 EXPORT_SYMBOL(dahdi_dynamic_unregister);
 EXPORT_SYMBOL(dahdi_dynamic_receive);
+
+static int ztdynamic_init(void);
+static void ztdynamic_cleanup(void);
 
 #ifdef ENABLE_TASKLETS
 static int taskletrun;
@@ -91,8 +93,7 @@
 static void ztd_tasklet(unsigned long data);
 #endif
 
-
-static struct dahdi_dynamic {
+struct dahdi_dynamic {
 	char addr[40];
 	char dname[20];
 	int err;
@@ -103,40 +104,34 @@
 	unsigned short rxcnt;
 	struct dahdi_span span;
 	struct dahdi_chan *chans[DAHDI_DYNAMIC_MAX_CHANS];
-	struct dahdi_dynamic *next;
 	struct dahdi_dynamic_driver *driver;
 	void *pvt;
 	int timing;
 	int master;
 	unsigned char *msgbuf;
-} *dspans;
-
-static struct dahdi_dynamic_driver *drivers =  NULL;
+
+	struct list_head list;
+};
+
+static DEFINE_SPINLOCK(dspan_lock);
+static LIST_HEAD(dspan_list);
+
+static DEFINE_SPINLOCK(driver_lock);
+static LIST_HEAD(driver_list);
 
 static int debug = 0;
 
 static int hasmaster = 0;
-#ifdef DEFINE_SPINLOCK
-static DEFINE_SPINLOCK(dlock); 
-#else
-static spinlock_t dlock = SPIN_LOCK_UNLOCKED;
-#endif
-
-#ifdef DEFINE_RWLOCK
-static DEFINE_RWLOCK(drvlock);
-#else
-static rwlock_t drvlock = RW_LOCK_UNLOCKED;
-#endif
 
 static void checkmaster(void)
 {
-	unsigned long flags;
 	int newhasmaster=0;
 	int best = 9999999;
 	struct dahdi_dynamic *z, *master=NULL;
-	spin_lock_irqsave(&dlock, flags);
-	z = dspans;
-	while(z) {
+
+	rcu_read_lock();
+
+	list_for_each_entry_rcu(z, &dspan_list, list) {
 		if (z->timing) {
 			z->master = 0;
 			if (!(z->span.alarms & DAHDI_ALARM_RED) &&
@@ -148,13 +143,15 @@
 				newhasmaster = 1;
 			}
 		}
-		z = z->next;
-	}
+	}
+
 	hasmaster = newhasmaster;
 	/* Mark the new master if there is one */
 	if (master)
 		master->master = 1;
-	spin_unlock_irqrestore(&dlock, flags);
+
+	rcu_read_unlock();
+
 	if (master)
 		printk(KERN_INFO "TDMoX: New master: %s\n", master->span.name);
 	else
@@ -223,15 +220,13 @@
 
 static void __ztdynamic_run(void)
 {
-	unsigned long flags;
 	struct dahdi_dynamic *z;
 	struct dahdi_dynamic_driver *drv;
 	int y;
-	spin_lock_irqsave(&dlock, flags);
-	z = dspans;
-	while(z) {
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(z, &dspan_list, list) {
 		if (!z->dead) {
-			/* Ignore dead spans */
 			for (y=0;y<z->span.channels;y++) {
 				/* Echo cancel double buffered data */
 				dahdi_ec_chunk(z->span.chans[y], z->span.chans[y]->readchunk, z->span.chans[y]->writechunk);
@@ -239,30 +234,23 @@
 			dahdi_receive(&z->span);
 			dahdi_transmit(&z->span);
 			/* Handle all transmissions now */
-			spin_unlock_irqrestore(&dlock, flags);
 			ztd_sendmessage(z);
-			spin_lock_irqsave(&dlock, flags);
-		}
-		z = z->next;
-	}
-	spin_unlock_irqrestore(&dlock, flags);
-
-	read_lock(&drvlock);
-	drv = drivers;
-	while(drv) {
+		}
+	}
+
+	list_for_each_entry_rcu(drv, &driver_list, list) {
 		/* Flush any traffic still pending in the driver */
 		if (drv->flush) {
 			drv->flush();
 		}
-		drv = drv->next;
-	}
-	read_unlock(&drvlock);
+	}
+	rcu_read_unlock();
 }
 
 #ifdef ENABLE_TASKLETS
 static void ztdynamic_run(void)
 {
-	if (!taskletpending) {
+	if (likely(!taskletpending)) {
 		taskletpending = 1;
 		taskletsched++;
 		tasklet_hi_schedule(&ztd_tlet);
@@ -278,18 +266,17 @@
 {
 	struct dahdi_dynamic *ztd = span->pvt;
 	int newerr=0;
-	unsigned long flags;
 	int sflags;
 	int xlen;
 	int x, bits, sig;
 	int nchans, master;
 	int newalarm;
 	unsigned short rxpos, rxcnt;
-	
-	
-	spin_lock_irqsave(&dlock, flags);
-	if (msglen < 6) {
-		spin_unlock_irqrestore(&dlock, flags);
+
+	rcu_read_lock();
+
+	if (unlikely(msglen < 6)) {
+		rcu_read_unlock();
 		newerr = ERR_LEN;
 		if (newerr != ztd->err) {
 			printk(KERN_NOTICE "Span %s: Insufficient samples for header (only %d)\n", span->name, msglen);
@@ -299,8 +286,8 @@
 	}
 	
 	/* First, check the chunksize */
-	if (*msg != DAHDI_CHUNKSIZE) {
-		spin_unlock_irqrestore(&dlock, flags);
+	if (unlikely(*msg != DAHDI_CHUNKSIZE)) {
+		rcu_read_unlock();
 		newerr = ERR_NSAMP | msg[0];
 		if (newerr != 	ztd->err) {
 			printk(KERN_NOTICE "Span %s: Expected %d samples, but receiving %d\n", span->name, DAHDI_CHUNKSIZE, msg[0]);
@@ -311,14 +298,14 @@
 	msg++;
 	sflags = *msg;
 	msg++;
-	
+
 	rxpos = ntohs(*((unsigned short *)msg));
 	msg++;
 	msg++;
-	
+
 	nchans = ntohs(*((unsigned short *)msg));
-	if (nchans != span->channels) {
-		spin_unlock_irqrestore(&dlock, flags);
+	if (unlikely(nchans != span->channels)) {
+		rcu_read_unlock();
 		newerr = ERR_NCHAN | nchans;
 		if (newerr != ztd->err) {
 			printk(KERN_NOTICE "Span %s: Expected %d channels, but receiving %d\n", span->name, span->channels, nchans);
@@ -328,7 +315,7 @@
 	}
 	msg++;
 	msg++;
-	
+
 	/* Okay now we've accepted the header, lets check our message
 	   length... */
 
@@ -341,9 +328,9 @@
 		/* Account for sigbits -- one short per 4 channels*/
 		xlen += ((nchans + 3) / 4) * 2;
 	}
-	
-	if (xlen != msglen) {
-		spin_unlock_irqrestore(&dlock, flags);
+
+	if (unlikely(xlen != msglen)) {
+		rcu_read_unlock();
 		newerr = ERR_LEN | xlen;
 		if (newerr != ztd->err) {
 			printk(KERN_NOTICE "Span %s: Expected message size %d, but was %d instead\n", span->name, xlen, msglen);
@@ -351,9 +338,9 @@
 		ztd->err = newerr;
 		return;
 	}
-	
+
 	bits = 0;
-	
+
 	/* Record sigbits if present */
 	if (sflags & ZTD_FLAG_SIGBITS_PRESENT) {
 		for (x=0;x<nchans;x++) {
@@ -385,8 +372,11 @@
 	rxcnt = ztd->rxcnt;
 	ztd->rxcnt = rxpos+1;
 
-	spin_unlock_irqrestore(&dlock, flags);
-	
+	/* Keep track of last received packet */
+	ztd->rxjif = jiffies;
+
+	rcu_read_unlock();
+
 	/* Check for Yellow alarm */
 	newalarm = span->alarms & ~(DAHDI_ALARM_YELLOW | DAHDI_ALARM_RED);
 	if (sflags & ZTD_FLAG_YELLOW_ALARM)
@@ -397,18 +387,14 @@
 		dahdi_alarm_notify(span);
 		checkmaster();
 	}
-	
-	/* Keep track of last received packet */
-	ztd->rxjif = jiffies;
 
 	/* note if we had a missing packet */
-	if (rxpos != rxcnt)
+	if (unlikely(rxpos != rxcnt))
 		printk(KERN_NOTICE "Span %s: Expected seq no %d, but received %d instead\n", span->name, rxcnt, rxpos);
 
 	/* If this is our master span, then run everything */
 	if (master)
 		ztdynamic_run();
-	
 }
 
 static void dynamic_destroy(struct dahdi_dynamic *z)
@@ -440,64 +426,61 @@
 
 static struct dahdi_dynamic *find_dynamic(struct dahdi_dynamic_span *zds)
 {
+	struct dahdi_dynamic *z = NULL, *found = NULL;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(z, &dspan_list, list) {
+		if (!strcmp(z->dname, zds->driver) &&
+				!strcmp(z->addr, zds->addr)) {
+			found = z;
+			break;
+		}
+	}
+	rcu_read_unlock();
+
+	return found;
+}
+
+static struct dahdi_dynamic_driver *find_driver(char *name)
+{
+	struct dahdi_dynamic_driver *ztd, *found = NULL;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(ztd, &driver_list, list) {
+		/* here's our driver */
+		if (!strcmp(name, ztd->name)) {
+			found = ztd;
+			break;
+		}
+	}
+	rcu_read_unlock();
+
+	return found;
+}
+
+static int destroy_dynamic(struct dahdi_dynamic_span *zds)
+{
+	unsigned long flags;
 	struct dahdi_dynamic *z;
-	z = dspans;
-	while(z) {
-		if (!strcmp(z->dname, zds->driver) &&
-		    !strcmp(z->addr, zds->addr))
-			break;
-		z = z->next;
-	}
-	return z;
-}
-
-static struct dahdi_dynamic_driver *find_driver(char *name)
-{
-	struct dahdi_dynamic_driver *ztd;
-	ztd = drivers;
-	while(ztd) {
-		/* here's our driver */
-		if (!strcmp(name, ztd->name))
-			break;
-		ztd = ztd->next;
-	}
-	return ztd;
-}
-
-static int destroy_dynamic(struct dahdi_dynamic_span *zds)
-{
-	unsigned long flags;
-	struct dahdi_dynamic *z, *cur, *prev=NULL;
-	spin_lock_irqsave(&dlock, flags);
+
 	z = find_dynamic(zds);
-	if (!z) {
-		spin_unlock_irqrestore(&dlock, flags);
+	if (unlikely(!z)) {
 		return -EINVAL;
 	}
-	/* Don't destroy span until it is in use */
+
 	if (z->usecount) {
-		spin_unlock_irqrestore(&dlock, flags);
 		printk(KERN_NOTICE "Attempt to destroy dynamic span while it is in use\n");
 		return -EBUSY;
 	}
-	/* Unlink it */
-	cur = dspans;
-	while(cur) {
-		if (cur == z) {
-			if (prev)
-				prev->next = z->next;
-			else
-				dspans = z->next;
-			break;
-		}
-		prev = cur;
-		cur = cur->next;
-	}
-	spin_unlock_irqrestore(&dlock, flags);
+
+	spin_lock_irqsave(&dspan_lock, flags);
+	list_del_rcu(&z->list);
+	spin_unlock_irqrestore(&dspan_lock, flags);
+	synchronize_rcu();
 
 	/* Destroy it */
 	dynamic_destroy(z);
-	
+
 	return 0;
 }
 
@@ -508,30 +491,31 @@
 }
 
 static int ztd_open(struct dahdi_chan *chan)
+{
+	struct dahdi_dynamic *z;
+	z = chan->span->pvt;
+	if (likely(z)) {
+		if (unlikely(z->dead))
+			return -ENODEV;
+		z->usecount++;
+	}
+	return 0;
+}
+
+static int ztd_chanconfig(struct dahdi_chan *chan, int sigtype)
+{
+	return 0;
+}
+
+static int ztd_close(struct dahdi_chan *chan)
 {
 	struct dahdi_dynamic *z;
 	z = chan->span->pvt;
 	if (z) {
-		if (z->dead)
-			return -ENODEV;
-		z->usecount++;
-	}
-	return 0;
-}
-
-static int ztd_chanconfig(struct dahdi_chan *chan, int sigtype)
-{
-	return 0;
-}
-
-static int ztd_close(struct dahdi_chan *chan)
-{
-	struct dahdi_dynamic *z;
-	z = chan->span->pvt;
-	if (z) 
 		z->usecount--;
-	if (z->dead && !z->usecount)
-		dynamic_destroy(z);
+		if (z->dead && !z->usecount)
+			dynamic_destroy(z);
+	}
 	return 0;
 }
 
@@ -552,21 +536,13 @@
 		return -EINVAL;
 	}
 
-	spin_lock_irqsave(&dlock, flags);
 	z = find_dynamic(zds);
-	spin_unlock_irqrestore(&dlock, flags);
 	if (z)
 		return -EEXIST;
 
-	/* XXX There is a silly race here.  We check it doesn't exist, but
-	       someone could create it between now and then and we'd end up
-	       with two of them.  We don't want to hold the spinlock
-	       for *too* long though, especially not if there is a possibility
-	       of kmalloc.  XXX */
-
-
 	/* Allocate memory */
-	if (!(z = kmalloc(sizeof(*z), GFP_KERNEL))) {
+	z = (struct dahdi_dynamic *) kmalloc(sizeof(struct dahdi_dynamic), GFP_KERNEL);
+	if (!z) {
 		return -ENOMEM;
 	}
 
@@ -621,24 +597,20 @@
 		z->chans[x]->pvt = z;
 	}
 	
-	spin_lock_irqsave(&dlock, flags);
 	ztd = find_driver(zds->driver);
 	if (!ztd) {
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,70)
 		char fn[80];
 #endif
 
-		spin_unlock_irqrestore(&dlock, flags);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,70)
 		request_module("dahdi_dynamic_%s", zds->driver);
 #else
 		sprintf(fn, "dahdi_dynamic_%s", zds->driver);
 		request_module(fn);
 #endif
-		spin_lock_irqsave(&dlock, flags);
 		ztd = find_driver(zds->driver);
 	}
-	spin_unlock_irqrestore(&dlock, flags);
 
 
 	/* Another race -- should let the module get unloaded while we
@@ -667,11 +639,9 @@
 		return -EINVAL;
 	}
 
-	/* Okay, created and registered. add it to the list */
-	spin_lock_irqsave(&dlock, flags);
-	z->next = dspans;
-	dspans = z;
-	spin_unlock_irqrestore(&dlock, flags);
+	spin_lock_irqsave(&dspan_lock, flags);
+	list_add_rcu(&z->list, &dspan_list);
+	spin_unlock_irqrestore(&dspan_lock, flags);
 
 	checkmaster();
 
@@ -732,70 +702,52 @@
 {
 	unsigned long flags;
 	int res = 0;
-	write_lock_irqsave(&drvlock, flags);
-	if (find_driver(dri->name))
+
+	if (find_driver(dri->name)) {
 		res = -1;
-	else {
-		dri->next = drivers;
-		drivers = dri;
-	}
-	write_unlock_irqrestore(&drvlock, flags);
+	} else {
+		spin_lock_irqsave(&driver_lock, flags);
+		list_add_rcu(&dri->list, &driver_list);
+		spin_unlock_irqrestore(&driver_lock, flags);
+	}
 	return res;
 }
 
 void dahdi_dynamic_unregister(struct dahdi_dynamic_driver *dri)
 {
-	struct dahdi_dynamic_driver *cur, *prev=NULL;
-	struct dahdi_dynamic *z, *zp, *zn;
+	struct dahdi_dynamic *z;
 	unsigned long flags;
-	write_lock_irqsave(&drvlock, flags);
-	cur = drivers;
-	while(cur) {
-		if (cur == dri) {
-			if (prev)
-				prev->next = cur->next;
-			else
-				drivers = cur->next;
-			break;
-		}
-		prev = cur;
-		cur = cur->next;
-	}
-	write_unlock_irqrestore(&drvlock, flags);
-	spin_lock_irqsave(&dlock, flags);
-	z = dspans;
-	zp = NULL;
-	while(z) {
-		zn = z->next;
+
+	spin_lock_irqsave(&driver_lock, flags);
+	list_del_rcu(&dri->list);
+	spin_unlock_irqrestore(&driver_lock, flags);
+	synchronize_rcu();
+
+	list_for_each_entry(z, &dspan_list, list) {
 		if (z->driver == dri) {
-			/* Unlink */
-			if (zp)
-				zp->next = z->next;
-			else
-				dspans = z->next;
+			spin_lock_irqsave(&dspan_lock, flags);
+			list_del_rcu(&z->list);
+			spin_unlock_irqrestore(&dspan_lock, flags);
+			synchronize_rcu();
+
 			if (!z->usecount)
 				dynamic_destroy(z);
 			else
 				z->dead = 1;
-		} else {
-			zp = z;
-		}
-		z = zn;
-	}
-	spin_unlock_irqrestore(&dlock, flags);
+		}
+	}
 }
 
 static struct timer_list alarmcheck;
 
 static void check_for_red_alarm(unsigned long ignored)
 {
-	unsigned long flags;
 	int newalarm;
 	int alarmchanged = 0;
 	struct dahdi_dynamic *z;
-	spin_lock_irqsave(&dlock, flags);
-	z = dspans;
-	while(z) {
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(z, &dspan_list, list) {
 		newalarm = z->span.alarms & ~DAHDI_ALARM_RED;
 		/* If nothing received for a second, consider that RED ALARM */
 		if ((jiffies - z->rxjif) > 1 * HZ) {
@@ -806,20 +758,20 @@
 				alarmchanged++;
 			}
 		}
-		z = z->next;
-	}
-	spin_unlock_irqrestore(&dlock, flags);
+	}
+	rcu_read_unlock();
+
 	if (alarmchanged)
 		checkmaster();
 
 	/* Do the next one */
 	mod_timer(&alarmcheck, jiffies + 1 * HZ);
-	
 }
 
 static int ztdynamic_init(void)
 {
 	dahdi_set_dynamic_ioctl(ztdynamic_ioctl);
+
 	/* Start process to check for RED ALARM */
 	init_timer(&alarmcheck);
 	alarmcheck.expires = 0;

Modified: linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_dynamic_eth.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_dynamic_eth.c?view=diff&rev=8115&r1=8114&r2=8115
==============================================================================
--- linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_dynamic_eth.c (original)
+++ linux/team/tzafrir/sysfs/drivers/dahdi/dahdi_dynamic_eth.c Thu Feb 25 17:36:11 2010
@@ -98,10 +98,12 @@
 #endif	
 	if (span) {
 		skb_pull(skb, sizeof(struct ztdeth_header));
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-		skb_linearize(skb);
-#else
-		skb_linearize(skb, GFP_KERNEL);
+#ifdef NEW_SKB_LINEARIZE
+		if (skb_is_nonlinear(skb))
+			skb_linearize(skb);
+#else
+		if (skb_is_nonlinear(skb))
+			skb_linearize(skb, GFP_KERNEL);
 #endif
 		dahdi_dynamic_receive(span, (unsigned char *)skb->data, skb->len);
 	}

Modified: linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/voicebus.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/voicebus.c?view=diff&rev=8115&r1=8114&r2=8115
==============================================================================
--- linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/voicebus.c (original)
+++ linux/team/tzafrir/sysfs/drivers/dahdi/voicebus/voicebus.c Thu Feb 25 17:36:11 2010
@@ -1569,12 +1569,16 @@
 	spin_unlock(&loader_list_lock);
 
 	if (!loader_present) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
+		ret = request_module("dahdi_vpmadt032_loader");
+#else
 		/* If we use the blocking 'request_module' here and we are
 		 * loading the client boards with async_schedule we will hang
 		 * here. The module loader will wait for our asynchronous tasks
 		 * to finish, but we can't because we're waiting for the load
 		 * the finish. */
 		ret = request_module_nowait("dahdi_vpmadt032_loader");
+#endif
 		if (ret)
 			return ret;
 		stop = jiffies + HZ;

Modified: linux/team/tzafrir/sysfs/include/dahdi/kernel.h
URL: http://svnview.digium.com/svn/dahdi/linux/team/tzafrir/sysfs/include/dahdi/kernel.h?view=diff&rev=8115&r1=8114&r2=8115
==============================================================================
--- linux/team/tzafrir/sysfs/include/dahdi/kernel.h (original)
+++ linux/team/tzafrir/sysfs/include/dahdi/kernel.h Thu Feb 25 17:36:11 2010
@@ -971,7 +971,7 @@
 	/*! Flush any pending messages */
 	int (*flush)(void);
 
-	struct dahdi_dynamic_driver *next;
+	struct list_head list;
 };
 
 /*! \brief Receive a dynamic span message */




More information about the svn-commits mailing list