[svn-commits] mattf: branch 1.4 r4221 - in /branches/1.4/kernel: ./ wct4xxp/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri May 2 12:31:56 CDT 2008


Author: mattf
Date: Fri May  2 12:31:56 2008
New Revision: 4221

URL: http://svn.digium.com/view/zaptel?view=rev&rev=4221
Log:
Merge stack cleanup branch into 1.4.  Also merge firmware load time fix for wct4xxp driver.  The stack cleanup branch reduces the amound of stack used by zaptel, nice for systems with 4K stacks enabled and where potential stack overflow is found

Modified:
    branches/1.4/kernel/wct4xxp/base.c
    branches/1.4/kernel/wct4xxp/wct4xxp.h
    branches/1.4/kernel/zaptel-base.c

Modified: branches/1.4/kernel/wct4xxp/base.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/kernel/wct4xxp/base.c?view=diff&rev=4221&r1=4220&r2=4221
==============================================================================
--- branches/1.4/kernel/wct4xxp/base.c (original)
+++ branches/1.4/kernel/wct4xxp/base.c Fri May  2 12:31:56 2008
@@ -330,6 +330,9 @@
 	unsigned long memlen;
 	volatile unsigned int *membase;	/* Base address of card */
 
+	/* Add this for our softlockup protector */
+	unsigned int oct_rw_count;
+
 	/* Flags for our bottom half */
 	unsigned long checkflag;
 	struct tasklet_struct t4_tlet;
@@ -416,7 +419,8 @@
 		 * transactions, some host bridges appear to generate them.
 		 * This delay prevents this. 
 		 */
-		udelay(3);
+		if (!test_bit(T4_LOADING_FW, &wc->checkflag))
+			udelay(3);
 	}
 	return res;
 }
@@ -430,7 +434,8 @@
 		 * transactions, some host bridges appear to generate them.
 		 * This delay prevents this. 
 		 */
-		udelay(3);
+		if (!test_bit(T4_LOADING_FW, &wc->checkflag))
+			udelay(3);
 		tmp = __t4_pci_in(wc, WC_VERSION);
 		if ((tmp & 0xffff0000) != 0xc01a0000)
 			printk("TE4XXP: Version Synchronization Error!\n");
@@ -655,6 +660,16 @@
 {
 	unsigned long flags;
 	unsigned int ret;
+
+#if 0
+#ifdef CONFIG_DETECT_SOFTLOCKUP
+	if (!in_irq() && test_bit(T4_LOADING_FW, &wc->checkflag) && !(wc->oct_rw_count++ % 2000)) {
+		//printk("Hit\n");
+		//touch_softlockup_watchdog();
+		//touch_all_softlockup_watchdogs();
+	}
+#endif
+#endif
 	spin_lock_irqsave(&wc->reglock, flags);
 	ret = __t4_oct_in(wc, addr);
 	spin_unlock_irqrestore(&wc->reglock, flags);
@@ -716,6 +731,17 @@
 static inline void t4_oct_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
 {
 	unsigned long flags;
+
+#if 0
+#ifdef CONFIG_DETECT_SOFTLOCKUP
+	if (!in_irq() && test_bit(T4_LOADING_FW, &wc->checkflag) && !(wc->oct_rw_count++ % 2000)) {
+		//printk("Hit\n");
+		//touch_softlockup_watchdog();
+		//touch_all_softlockup_watchdogs();
+	}
+#endif
+#endif
+
 	spin_lock_irqsave(&wc->reglock, flags);
 	__t4_oct_out(wc, addr, value);
 	spin_unlock_irqrestore(&wc->reglock, flags);
@@ -3182,12 +3208,15 @@
 		return;
 	}
 
+	set_bit(T4_LOADING_FW, &wc->checkflag);
 	if (!(wc->vpm450m = init_vpm450m(wc, laws, wc->numspans, firmware))) {
 		printk("VPM450: Failed to initialize\n");
 		if (firmware != &embedded_firmware)
 			release_firmware(firmware);
+		clear_bit(T4_LOADING_FW, &wc->checkflag);
 		return;
 	}
+	clear_bit(T4_LOADING_FW, &wc->checkflag);
 
 	if (firmware != &embedded_firmware)
 		release_firmware(firmware);

Modified: branches/1.4/kernel/wct4xxp/wct4xxp.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/kernel/wct4xxp/wct4xxp.h?view=diff&rev=4221&r1=4220&r2=4221
==============================================================================
--- branches/1.4/kernel/wct4xxp/wct4xxp.h (original)
+++ branches/1.4/kernel/wct4xxp/wct4xxp.h Fri May  2 12:31:56 2008
@@ -106,6 +106,7 @@
 };
 
 #define T4_CHECK_VPM		0
+#define T4_LOADING_FW		1
 
 #define WCT4_GET_REGS	_IOW (ZT_CODE, 60, struct t4_regs)
 

Modified: branches/1.4/kernel/zaptel-base.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/kernel/zaptel-base.c?view=diff&rev=4221&r1=4220&r2=4221
==============================================================================
--- branches/1.4/kernel/zaptel-base.c (original)
+++ branches/1.4/kernel/zaptel-base.c Fri May  2 12:31:56 2008
@@ -3623,26 +3623,26 @@
 {
 	/* I/O CTL's for control interface */
 	int i,j;
-	struct zt_lineconfig lc;
-	struct zt_chanconfig ch;
-	struct zt_sfconfig sf;
 	int sigcap;
 	int res = 0;
 	int x,y;
 	struct zt_chan *newmaster;
-	struct zt_dialparams tdp;
-	struct zt_maintinfo maint;
-	struct zt_indirect_data ind;
-	struct zt_versioninfo vi;
 	unsigned long flags;
 	int rv;
 	switch(cmd) {
 	case ZT_INDIRECT:
+	{
+		struct zt_indirect_data ind;
+
 		if (copy_from_user(&ind, (struct zt_indirect_data *)data, sizeof(ind)))
 			return -EFAULT;
 		VALID_CHANNEL(ind.chan);
 		return zt_chan_ioctl(inode, file, ind.op, (unsigned long) ind.data, ind.chan);
+	}
 	case ZT_SPANCONFIG:
+	{
+		struct zt_lineconfig lc;
+
 		if (copy_from_user(&lc, (struct zt_lineconfig *)data, sizeof(lc)))
 			return -EFAULT;
 		VALID_SPAN(lc.span);
@@ -3657,6 +3657,7 @@
 			return spans[lc.span]->spanconfig(spans[lc.span], &lc);
 		}
 		return 0;
+	}
 	case ZT_STARTUP:
 		CHECK_VALID_SPAN(j);
 		if (spans[j]->flags & ZT_FLAG_RUNNING)
@@ -3683,6 +3684,9 @@
 		spans[j]->flags &= ~ZT_FLAG_RUNNING;
 		return 0;
 	case ZT_CHANCONFIG:
+	{
+		struct zt_chanconfig ch;
+
 		if (copy_from_user(&ch, (struct zt_chanconfig *)data, sizeof(ch)))
 			return -EFAULT;
 		VALID_CHANNEL(ch.chan);
@@ -3718,7 +3722,7 @@
 			free_netdev(chans[ch.chan]->hdlcnetdev->netdev);
 #else
 			unregister_hdlc_device(&chans[ch.chan]->hdlcnetdev->netdev);
-#endif			
+#endif				
 			kfree(chans[ch.chan]->hdlcnetdev);
 			chans[ch.chan]->hdlcnetdev = NULL;
 			chans[ch.chan]->flags &= ~ZT_FLAG_NETDEV;
@@ -3729,7 +3733,7 @@
 				printk(KERN_WARNING "Zaptel networking not supported by this build.\n");
 				return -ENOSYS;
 		}
-#endif		
+#endif			
 		sigcap = chans[ch.chan]->sigcap;
 		/* If they support clear channel, then they support the HDLC and such through
 		   us.  */
@@ -3857,7 +3861,7 @@
 				res = -1;
 			}
 		}
-#endif		
+#endif			
 		if ((chans[ch.chan]->sig == ZT_SIG_HDLCNET) && 
 		    (chans[ch.chan] == newmaster) &&
 		    !(chans[ch.chan]->flags & ZT_FLAG_NETDEV))
@@ -3878,10 +3882,14 @@
 		}
 #ifdef CONFIG_ZAPATA_DEBUG
 		printk("Configured channel %s, flags %04x, sig %04x\n", chans[ch.chan]->name, chans[ch.chan]->flags, chans[ch.chan]->sig);
-#endif		
+#endif			
 		spin_unlock_irqrestore(&chans[ch.chan]->lock, flags);
 		return res;
+	}
 	case ZT_SFCONFIG:
+	{
+		struct zt_sfconfig sf;
+
 		if (copy_from_user(&sf, (struct zt_chanconfig *)data, sizeof(sf)))
 			return -EFAULT;
 		VALID_CHANNEL(sf.chan);
@@ -3908,6 +3916,7 @@
 		}
 		spin_unlock_irqrestore(&chans[sf.chan]->lock, flags);
 		return res;
+	}
 	case ZT_DEFAULTZONE:
 		if (get_user(j,(int *)data))
 			return -EFAULT;
@@ -3918,6 +3927,9 @@
 		get_user(j, (int *) data);
 		return free_tone_zone(j);
 	case ZT_SET_DIALPARAMS:
+	{
+		struct zt_dialparams tdp;
+
 		if (copy_from_user(&tdp, (struct zt_dialparams *) data, sizeof(tdp)))
 			return -EFAULT;
 
@@ -3963,19 +3975,30 @@
 		mfr2_silence.tonesamples = global_dialparams.mfr2_tonelen * ZT_CHUNKSIZE;
 
 		break;
+	}
 	case ZT_GET_DIALPARAMS:
+	{
+		struct zt_dialparams tdp;
+
 		tdp = global_dialparams;
 		if (copy_to_user((struct zt_dialparams *) data, &tdp, sizeof(tdp)))
 			return -EFAULT;
 		break;
+	}
 	case ZT_GETVERSION:
+	{
+		struct zt_versioninfo vi;
+
 		memset(&vi, 0, sizeof(vi));
 		zap_copy_string(vi.version, ZAPTEL_VERSION, sizeof(vi.version));
 		echo_can_identify(vi.echo_canceller, sizeof(vi.echo_canceller) - 1);
 		if (copy_to_user((struct zt_versioninfo *) data, &vi, sizeof(vi)))
 			return -EFAULT;
 		break;
+	}
 	case ZT_MAINT:  /* do maintenance stuff */
+	{
+		struct zt_maintinfo maint;
 		  /* get struct from user */
 		if (copy_from_user(&maint,(struct zt_maintinfo *) data, sizeof(maint)))
 			return -EFAULT;
@@ -4016,6 +4039,7 @@
 		zt_alarm_notify(spans[maint.spanno]);  /* process alarm-related events */
 		spin_unlock_irqrestore(&spans[maint.spanno]->lock, flags);
 		break;
+	}
 	case ZT_DYNAMIC_CREATE:
 	case ZT_DYNAMIC_DESTROY:
 		if (zt_dynamic_ioctl)
@@ -4037,11 +4061,67 @@
 	return 0;
 }
 
+static int ioctl_zt_dial(struct zt_chan *chan, unsigned long data)
+{
+	struct zt_dialoperation *tdo;
+	unsigned long flags;
+	char *s;
+	int rv;
+
+	tdo = kmalloc(sizeof(*tdo), GFP_KERNEL);
+
+	if (!tdo)
+		return -ENOMEM;
+
+	if (copy_from_user(tdo, (struct zt_dialoperation *)data, sizeof(*tdo)))
+		return -EFAULT;
+	rv = 0;
+	/* Force proper NULL termination and uppercase entry */
+	tdo->dialstr[ZT_MAX_DTMF_BUF - 1] = '\0';
+	for (s = tdo->dialstr; *s; s++)
+		*s = toupper(*s);
+	spin_lock_irqsave(&chan->lock, flags);
+	if (!chan->curzone) {
+		spin_unlock_irqrestore(&chan->lock, flags);
+		/* The tone zones are loaded by ztcfg from /etc/zaptel.conf */
+		printk(KERN_WARNING "zaptel: Cannot dial until a tone zone is loaded.\n");
+		return -ENODATA;
+	}
+	switch (tdo->op) {
+	case ZT_DIAL_OP_CANCEL:
+		chan->curtone = NULL;
+		chan->dialing = 0;
+		chan->txdialbuf[0] = '\0';
+		chan->tonep = 0;
+		chan->pdialcount = 0;
+		break;
+	case ZT_DIAL_OP_REPLACE:
+		strcpy(chan->txdialbuf, tdo->dialstr);
+		chan->dialing = 1;
+		__do_dtmf(chan);
+		break;
+	case ZT_DIAL_OP_APPEND:
+		if (strlen(tdo->dialstr) + strlen(chan->txdialbuf) >= (ZT_MAX_DTMF_BUF - 1)) {
+			rv = -EBUSY;
+			break;
+		}
+		zap_copy_string(chan->txdialbuf + strlen(chan->txdialbuf), tdo->dialstr, ZT_MAX_DTMF_BUF - strlen(chan->txdialbuf));
+		if (!chan->dialing) {
+			chan->dialing = 1;
+			__do_dtmf(chan);
+		}
+		break;
+	default:
+		rv = -EINVAL;
+	}
+	spin_unlock_irqrestore(&chan->lock, flags);
+	return rv;
+}
+
 static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit)
 {
 	struct zt_chan *chan = chans[unit];
 	union {
-		struct zt_dialoperation tdo;
 		struct zt_bufferinfo bi;
 		struct zt_confinfo conf;
 		struct zt_ring_cadence cad;
@@ -4049,7 +4129,6 @@
 	unsigned long flags, flagso;
 	int i, j, k, rv;
 	int ret, c;
-	char *s;
 	
 	if (!chan)
 		return -EINVAL;
@@ -4062,49 +4141,7 @@
 			return -EFAULT;
 		return 0;
 	case ZT_DIAL:
-		if (copy_from_user(&stack.tdo, (struct zt_dialoperation *)data, sizeof(stack.tdo)))
-			return -EFAULT;
-		rv = 0;
-		/* Force proper NULL termination and uppercase entry */
-		stack.tdo.dialstr[ZT_MAX_DTMF_BUF - 1] = '\0';
-		for (s = stack.tdo.dialstr; *s; s++)
-			*s = toupper(*s);
-		spin_lock_irqsave(&chan->lock, flags);
-		if (!chan->curzone) {
-			spin_unlock_irqrestore(&chan->lock, flags);
-			/* The tone zones are loaded by ztcfg from /etc/zaptel.conf */
-			printk(KERN_WARNING "zaptel: Cannot dial until a tone zone is loaded.\n");
-			return -ENODATA;
-		}
-		switch (stack.tdo.op) {
-		case ZT_DIAL_OP_CANCEL:
-			chan->curtone = NULL;
-			chan->dialing = 0;
-			chan->txdialbuf[0] = '\0';
-			chan->tonep = 0;
-			chan->pdialcount = 0;
-			break;
-		case ZT_DIAL_OP_REPLACE:
-			strcpy(chan->txdialbuf, stack.tdo.dialstr);
-			chan->dialing = 1;
-			__do_dtmf(chan);
-			break;
-		case ZT_DIAL_OP_APPEND:
-			if (strlen(stack.tdo.dialstr) + strlen(chan->txdialbuf) >= (ZT_MAX_DTMF_BUF - 1)) {
-				rv = -EBUSY;
-				break;
-			}
-			zap_copy_string(chan->txdialbuf + strlen(chan->txdialbuf), stack.tdo.dialstr, ZT_MAX_DTMF_BUF - strlen(chan->txdialbuf));
-			if (!chan->dialing) {
-				chan->dialing = 1;
-				__do_dtmf(chan);
-			}
-			break;
-		default:
-			rv = -EINVAL;
-		}
-		spin_unlock_irqrestore(&chan->lock, flags);
-		return rv;
+		return ioctl_zt_dial(chan, data);
 	case ZT_GET_BUFINFO:
 		stack.bi.rxbufpolicy = chan->rxbufpolicy;
 		stack.bi.txbufpolicy = chan->txbufpolicy;
@@ -4600,7 +4637,7 @@
 static int ioctl_echocancel(struct zt_chan *chan, struct zt_echocanparams *ecp, void *data)
 {
 	struct echo_can_state *ec = NULL, *tec;
-	struct zt_echocanparam params[ZT_MAX_ECHOCANPARAMS];
+	struct zt_echocanparam *params;
 	int ret;
 	unsigned long flags;
 
@@ -4630,10 +4667,17 @@
 	    !chan->span->echocan_with_params)
 		return -EINVAL;
 	
+	params = kmalloc(sizeof(params[0]) * ZT_MAX_ECHOCANPARAMS, GFP_KERNEL);
+	
+	if (!params)
+		return -ENOMEM;
+
 	/* enable mode, need the params */
 	
-	if (copy_from_user(params, (struct zt_echocanparam *) data, sizeof(params[0]) * ecp->param_count))
-		return -EFAULT;
+	if (copy_from_user(params, (struct zt_echocanparam *) data, sizeof(params[0]) * ecp->param_count)) {
+		ret = -EFAULT;
+		goto exit_with_free;
+	}
 	
 	spin_lock_irqsave(&chan->lock, flags);
 	tec = chan->ec;
@@ -4668,7 +4712,7 @@
 		}
 		
 		if ((ret = echo_can_create(ecp, params, &ec)))
-			return ret;
+			goto exit_with_free;
 		
 		spin_lock_irqsave(&chan->lock, flags);
 		chan->echocancel = ecp->tap_length;
@@ -4681,6 +4725,8 @@
 		spin_unlock_irqrestore(&chan->lock, flags);
 	}
 
+exit_with_free:
+	kfree(params);
 	return ret;
 }
 
@@ -4693,7 +4739,6 @@
 	int oldconf;
 	void *rxgain=NULL;
 	struct echo_can_state *ec;
-	struct zt_echocanparams ecp;
 
 	if (!chan)
 		return -ENOSYS;
@@ -4856,6 +4901,9 @@
 		}
 		break;
 	case ZT_ECHOCANCEL_PARAMS:
+	{
+		struct zt_echocanparams ecp;
+
 		if (!(chan->flags & ZT_FLAG_AUDIO))
 			return -EINVAL;
 		if (copy_from_user(&ecp, (struct zt_echocanparams *) data, sizeof(ecp)))
@@ -4864,7 +4912,11 @@
 		if ((ret = ioctl_echocancel(chan, &ecp, (void *) data)))
 			return ret;
 		break;
+	}
 	case ZT_ECHOCANCEL:
+	{
+		struct zt_echocanparams ecp;
+
 		if (!(chan->flags & ZT_FLAG_AUDIO))
 			return -EINVAL;
 		get_user(j, (int *) data);
@@ -4873,6 +4925,7 @@
 		if ((ret = ioctl_echocancel(chan, &ecp, NULL)))
 			return ret;
 		break;
+	}
 	case ZT_ECHOTRAIN:
 		get_user(j, (int *)data); /* get pre-training time from user */
 		if ((j < 0) || (j >= ZT_MAX_PRETRAINING))




More information about the svn-commits mailing list