diff options
-rw-r--r-- | zaptel.c | 55 |
1 files changed, 29 insertions, 26 deletions
@@ -2943,10 +2943,8 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c 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 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c 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]); + for (x=0;x<mychan->ec->taps;x++) { + printk("tap %d: %d\n", x, mychan->ec->fir_taps[x]); } } #endif -#endif /* ALLOW_CHAN_DIAG */ + kfree(mychan); break; default: return -ENOTTY; |