[Asterisk-cvs] zaptel zaptel.c,1.56,1.57 zaptel.h,1.26,1.27

markster at lists.digium.com markster at lists.digium.com
Sun Feb 8 11:13:41 CST 2004


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

Modified Files:
	zaptel.c zaptel.h 
Log Message:
Remove "zapfreelock" and replace with "bigzaplock" and make sure we're not performing interrupt routines that effect multiple channels at the same time that other things can be going on.


Index: zaptel.c
===================================================================
RCS file: /usr/cvsroot/zaptel/zaptel.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -d -r1.56 -r1.57
--- zaptel.c	6 Feb 2004 21:18:45 -0000	1.56
+++ zaptel.c	8 Feb 2004 17:22:20 -0000	1.57
@@ -296,9 +296,7 @@
 
 static spinlock_t zaptimerlock = SPIN_LOCK_UNLOCKED;
 
-static spinlock_t zapfreelock = SPIN_LOCK_UNLOCKED;
-
-static int zapneedfree = 0;
+static spinlock_t bigzaplock = SPIN_LOCK_UNLOCKED;
 
 struct zt_zone {
 	char name[40];	/* Informational, only */
@@ -2069,8 +2067,6 @@
 		/* Make sure we're not already open, a net device, or a slave device */
 		if (chans[unit]->flags & ZT_FLAG_OPEN) 
 			res = -EBUSY;
-		else if (chans[unit]->flags & ZT_FLAG_DEAD)
-			res = -EBUSY;
 		else if (chans[unit]->flags & ZT_FLAG_NETDEV)
 			res = -EBUSY;
 		else if (chans[unit]->master != chans[unit])
@@ -2138,7 +2134,7 @@
 	return pseudo;	
 }
 
-static void __zt_free_pseudo(struct zt_chan *pseudo)
+static void zt_free_pseudo(struct zt_chan *pseudo)
 {
 	if (pseudo) {
 		zt_chan_unreg(pseudo);
@@ -2146,19 +2142,7 @@
 	}
 }
 
-static void zt_free_pseudo(struct zt_chan *pseudo)
-{
-	long flags;
-	if (pseudo) {
-		/* Mark as dead for later reaping */
-		pseudo->flags |= ZT_FLAG_DEAD;
-		spin_lock_irqsave(&zapfreelock, flags);
-		zapneedfree = 1;
-		spin_unlock_irqrestore(&zapfreelock, flags);
-	}
-}
-
-static int zt_open(struct inode *inode, struct file *file)
+static int __zt_open(struct inode *inode, struct file *file)
 {
 	int unit = UNIT(file);
 	struct zt_chan *chan;
@@ -2189,6 +2173,16 @@
 	return zt_specchan_open(inode, file, unit, 1);
 }
 
+static int zt_open(struct inode *inode, struct file *file)
+{
+	int res;
+	unsigned long flags;
+	spin_lock_irqsave(&bigzaplock, flags);
+	res = __zt_open(inode, file);
+	spin_unlock_irqrestore(&bigzaplock, flags);
+	return res;
+}
+
 static ssize_t zt_read(struct file *file, char *usrbuf, size_t count, loff_t *ppos)
 {
 	int unit = UNIT(file);
@@ -2443,7 +2437,7 @@
 	__qevent(chan, ZT_EVENT_DIALCOMPLETE);
 }
 
-static int zt_release(struct inode *inode, struct file *file)
+static int __zt_release(struct inode *inode, struct file *file)
 {
 	int unit = UNIT(file);
 	int res;
@@ -2475,6 +2469,17 @@
 	return zt_specchan_release(inode, file, unit);
 }
 
+static int zt_release(struct inode *inode, struct file *file)
+{
+	/* Lock the big zap lock when handling a release */
+	unsigned long flags;
+	int res;
+	spin_lock_irqsave(&bigzaplock, flags);
+	res = __zt_release(inode, file);
+	spin_unlock_irqrestore(&bigzaplock, flags);
+	return res;
+}
+
 void zt_alarm_notify(struct zt_span *span)
 {
 	int j;
@@ -3157,7 +3162,7 @@
 	struct zt_bufferinfo bi;
 	struct zt_confinfo conf;
 	struct zt_ring_cadence cad;
-	unsigned long flags;
+	unsigned long flags, flagso;
 	int i, j, k, rv;
 	int ret, c;
 	
@@ -3363,8 +3368,10 @@
 		break;
 	case ZT_CONFMUTE:  /* set confmute flag */
 		if (!(chan->flags & ZT_FLAG_AUDIO)) return (-EINVAL);
+		spin_lock_irqsave(&bigzaplock, flags);
 		get_user(j,(int *)data);  /* get conf # */
 		chan->confmute = j;
+		spin_unlock_irqrestore(&bigzaplock, flags);
 		break;
 	case ZT_GETCONFMUTE:  /* get confmute flag */
 		if (!(chan->flags & ZT_FLAG_AUDIO)) return (-EINVAL);
@@ -3427,12 +3434,14 @@
 		  /* likewise if 0 mode must have no conf */
 		if ((!conf.confmode) && conf.confno) return (-EINVAL);
 		conf.chan = i;  /* return with real channel # */
+		spin_lock_irqsave(&bigzaplock, flagso);
 		spin_lock_irqsave(&chan->lock, flags);
 		if (conf.confno == -1) 
 			conf.confno = zt_first_empty_conference();
 		if ((conf.confno < 1) && (conf.confmode)) {
 			/* No more empty conferences */
 			spin_unlock_irqrestore(&chan->lock, flags);
+			spin_unlock_irqrestore(&bigzaplock, flagso);
 			return -EBUSY;
 		}
 		  /* if changing confs, clear last added info */
@@ -3454,8 +3463,9 @@
 			/* Get alias */
 			chans[i]->_confn = zt_get_conf_alias(conf.confno);
 		}
-		copy_to_user((struct zt_confinfo *) data,&conf,sizeof(conf));
 		spin_unlock_irqrestore(&chan->lock, flags);
+		spin_unlock_irqrestore(&bigzaplock, flagso);
+		copy_to_user((struct zt_confinfo *) data,&conf,sizeof(conf));
 		break;
 	case ZT_CONFLINK:  /* do conf link stuff */
 		if (!(chan->flags & ZT_FLAG_AUDIO)) return (-EINVAL);
@@ -3465,6 +3475,7 @@
 		if ((conf.confno < 0) || (conf.confno > ZT_MAX_CONF)) return(-EINVAL);
 		  /* cant listen to self!! */
 		if (conf.chan && (conf.chan == conf.confno)) return(-EINVAL);
+		spin_lock_irqsave(&bigzaplock, flagso);
 		spin_lock_irqsave(&chan->lock, flags);
 		  /* if to clear all links */
 		if ((!conf.chan) && (!conf.confno))
@@ -3473,6 +3484,7 @@
 			memset(conf_links,0,sizeof(conf_links));
 			recalc_maxlinks();
 			spin_unlock_irqrestore(&chan->lock, flags);
+			spin_unlock_irqrestore(&bigzaplock, flagso);
 			break;
 		   }
 		rv = 0;  /* clear return value */
@@ -3523,6 +3535,7 @@
 		   }
 		recalc_maxlinks();
 		spin_unlock_irqrestore(&chan->lock, flags);
+		spin_unlock_irqrestore(&bigzaplock, flagso);
 		return(rv);
 	case ZT_CONFDIAG:  /* output diagnostic info to console */
 		if (!(chan->flags & ZT_FLAG_AUDIO)) return (-EINVAL);
@@ -5722,7 +5735,7 @@
 int zt_receive(struct zt_span *span)
 {
 	int x,y,z;
-	unsigned long flags;
+	unsigned long flags, flagso;
 
 #if 1
 #ifdef CONFIG_ZAPTEL_WATCHDOG
@@ -5800,6 +5813,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, flagso);			
 		/* Process any timers */
 		process_timers();
 		/* If we have dynamic stuff, call the ioctl with 0,0 parameters to
@@ -5842,7 +5858,7 @@
 #ifdef CONFIG_ZAPTEL_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 & ZT_FLAG_PSEUDO)) {
@@ -5864,18 +5880,7 @@
 				spin_unlock_irqrestore(&chans[x]->lock, flags);
 			}
 		}
-		spin_lock_irqsave(&zapfreelock, flags);
-		if (zapneedfree) {
-			/* Free any pseudos that might need it */
-			for (x=0;x<maxchans;x++) {
-				if (chans[x] && (chans[x]->flags & ZT_FLAG_DEAD)) {
-					__zt_free_pseudo(chans[x]);
-				}
-			}
-			zapneedfree = 0;
-		}
-		spin_unlock_irqrestore(&zapfreelock, flags);
-
+		spin_unlock_irqrestore(&bigzaplock, flagso);			
 	}
 #endif
 	return 0;

Index: zaptel.h
===================================================================
RCS file: /usr/cvsroot/zaptel/zaptel.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- zaptel.h	6 Feb 2004 21:13:14 -0000	1.26
+++ zaptel.h	8 Feb 2004 17:22:20 -0000	1.27
@@ -1111,7 +1111,6 @@
 #define ZT_FLAG_LINEAR			(1 << 13)	/* Talk to user space in linear */
 #define ZT_FLAG_PPP			(1 << 14)	/* PPP is available */
 #define ZT_FLAG_T1PPP			(1 << 15)
-#define ZT_FLAG_DEAD		(1 << 16)	/* Dead, needs to be removed */
 
 struct zt_span {
 	spinlock_t lock;




More information about the svn-commits mailing list