[svn-commits] russell: trunk r2384 - /trunk/zaptel.c

svn-commits at lists.digium.com svn-commits at lists.digium.com
Tue Apr 3 16:39:59 MST 2007


Author: russell
Date: Tue Apr  3 18:39:58 2007
New Revision: 2384

URL: http://svn.digium.com/view/zaptel?view=rev&rev=2384
Log:
The ZT_CHANDIAG ioctl was disabled by default because the large zt_chan struct
that was being allocated on the stack is too big for some systems (those with
4k stacks).  So, change the code to allocate the struct on the heap, and let
the ioctl be always enabled.  (issue #9364, patch by tzafrir, with minor mods)

Modified:
    trunk/zaptel.c

Modified: trunk/zaptel.c
URL: http://svn.digium.com/view/zaptel/trunk/zaptel.c?view=diff&rev=2384&r1=2383&r2=2384
==============================================================================
--- trunk/zaptel.c (original)
+++ trunk/zaptel.c Tue Apr  3 18:39:58 2007
@@ -2943,10 +2943,8 @@
 	struct zt_chan *chan;
 	unsigned long flags;
 	unsigned char *txgain, *rxgain;
-#ifdef ALLOW_CHAN_DIAG
 	/* This structure is huge and will bork a 4k stack */
-	struct zt_chan mychan;
-#endif	
+	struct zt_chan *mychan;
 	int i,j;
 	int return_master = 0;
 
@@ -3156,57 +3154,62 @@
 		if (copy_to_user((struct zt_spaninfo *) data,&stack.span,sizeof(stack.span)))
 			return -EFAULT;
 		break;
-#ifdef ALLOW_CHAN_DIAG
 	case ZT_CHANDIAG:
 		get_user(j, (int *)data); /* get channel number from user */
 		/* make sure its a valid channel number */
 		if ((j < 1) || (j >= maxchans))
 			return -EINVAL;
 		/* if channel not mapped, not there */
-		if (!chans[j]) return -EINVAL;
-		/* lock irq state */
+		if (!chans[j]) 
+			return -EINVAL;
+
+		if (!(mychan = kmalloc(sizeof(*mychan), GFP_KERNEL)))
+			return -ENOMEM;
+
+		/* lock channel */
 		spin_lock_irqsave(&chans[j]->lock, flags);
 		/* make static copy of channel */
-		memcpy(&mychan,chans[j],sizeof(struct zt_chan));
-		/* let irq's go */
+		memcpy(mychan, chans[j], sizeof(*mychan));
+		/* release it. */
 		spin_unlock_irqrestore(&chans[j]->lock, flags);
+
 		printk("Dump of Zaptel Channel %d (%s,%d,%d):\n\n",j,
-			mychan.name,mychan.channo,mychan.chanpos);
+			mychan->name,mychan->channo,mychan->chanpos);
 		printk("flags: %x hex, writechunk: %08lx, readchunk: %08lx\n",
-			mychan.flags, (long) mychan.writechunk, (long) mychan.readchunk);
+			mychan->flags, (long) mychan->writechunk, (long) mychan->readchunk);
 		printk("rxgain: %08lx, txgain: %08lx, gainalloc: %d\n",
-			(long) mychan.rxgain, (long)mychan.txgain, mychan.gainalloc);
+			(long) mychan->rxgain, (long)mychan->txgain, mychan->gainalloc);
 		printk("span: %08lx, sig: %x hex, sigcap: %x hex\n",
-			(long)mychan.span, mychan.sig, mychan.sigcap);
+			(long)mychan->span, mychan->sig, mychan->sigcap);
 		printk("inreadbuf: %d, outreadbuf: %d, inwritebuf: %d, outwritebuf: %d\n",
-			mychan.inreadbuf, mychan.outreadbuf, mychan.inwritebuf, mychan.outwritebuf);
+			mychan->inreadbuf, mychan->outreadbuf, mychan->inwritebuf, mychan->outwritebuf);
 		printk("blocksize: %d, numbufs: %d, txbufpolicy: %d, txbufpolicy: %d\n",
-			mychan.blocksize, mychan.numbufs, mychan.txbufpolicy, mychan.rxbufpolicy);
+			mychan->blocksize, mychan->numbufs, mychan->txbufpolicy, mychan->rxbufpolicy);
 		printk("txdisable: %d, rxdisable: %d, iomask: %d\n",
-			mychan.txdisable, mychan.rxdisable, mychan.iomask);
+			mychan->txdisable, mychan->rxdisable, mychan->iomask);
 		printk("curzone: %08lx, tonezone: %d, curtone: %08lx, tonep: %d\n",
-			(long) mychan.curzone, mychan.tonezone, (long) mychan.curtone, mychan.tonep);
+			(long) mychan->curzone, mychan->tonezone, (long) mychan->curtone, mychan->tonep);
 		printk("digitmode: %d, txdialbuf: %s, dialing: %d, aftdialtimer: %d, cadpos. %d\n",
-			mychan.digitmode, mychan.txdialbuf, mychan.dialing,
-				mychan.afterdialingtimer, mychan.cadencepos);
+			mychan->digitmode, mychan->txdialbuf, mychan->dialing,
+				mychan->afterdialingtimer, mychan->cadencepos);
 		printk("confna: %d, confn: %d, confmode: %d, confmute: %d\n",
-			mychan.confna, mychan._confn, mychan.confmode, mychan.confmute);
+			mychan->confna, mychan->_confn, mychan->confmode, mychan->confmute);
 		printk("ec: %08lx, echocancel: %d, deflaw: %d, xlaw: %08lx\n",
-			(long) mychan.ec, mychan.echocancel, mychan.deflaw, (long) mychan.xlaw);
+			(long) mychan->ec, mychan->echocancel, mychan->deflaw, (long) mychan->xlaw);
 		printk("echostate: %02x, echotimer: %d, echolastupdate: %d\n",
-			(int) mychan.echostate, mychan.echotimer, mychan.echolastupdate);
+			(int) mychan->echostate, mychan->echotimer, mychan->echolastupdate);
 		printk("itimer: %d, otimer: %d, ringdebtimer: %d\n\n",
-			mychan.itimer,mychan.otimer,mychan.ringdebtimer);
+			mychan->itimer, mychan->otimer, mychan->ringdebtimer);
 #if 0
-		if (mychan.ec) {
+		if (mychan->ec) {
 			int x;
 			/* Dump the echo canceller parameters */
-			for (x=0;x<mychan.ec->taps;x++) {
-				printk("tap %d: %d\n", x, mychan.ec->fir_taps[x]);
-			}
-		}
-#endif
-#endif /* ALLOW_CHAN_DIAG */
+			for (x=0;x<mychan->ec->taps;x++) {
+				printk("tap %d: %d\n", x, mychan->ec->fir_taps[x]);
+			}
+		}
+#endif
+		kfree(mychan);
 		break;
 	default:
 		return -ENOTTY;



More information about the svn-commits mailing list