diff options
author | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2002-09-04 19:02:07 +0000 |
---|---|---|
committer | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2002-09-04 19:02:07 +0000 |
commit | d02d74bf8ef6149dc5da847c7728b38a1d7c3569 (patch) | |
tree | 874f7ab4ce658a2f752e3f86a4af15e6a9354a6d | |
parent | c40b2fa76bb9b59efd40c11dc328440242eee3fe (diff) |
Version 0.3.0 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@101 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-x | zaptel.c | 122 |
1 files changed, 111 insertions, 11 deletions
@@ -323,6 +323,8 @@ static unsigned int in_sig[NUM_SIGS][2] = { { ZT_SIG_FXOKS,0 | (ZT_ABIT << 8)} } ; + /* must have span to begin with */ + if (!chan->span) return(-1); /* if RBS does not apply, return error */ if (!(chan->span->flags & ZT_FLAG_RBS) || !chan->span->rbsbits) return(-1); @@ -670,6 +672,7 @@ static void close_channel(struct zt_chan *chan) unsigned int flags; void *rxgain = NULL; echo_can_state_t *ec = NULL; + int oldconf; #ifdef CONFIG_ZAPATA_PPP struct ppp_channel *ppp; #endif @@ -698,13 +701,15 @@ static void close_channel(struct zt_chan *chan) chan->afterdialingtimer = 0; /* initialize IO MUX mask */ chan->iomask = 0; - /* release conference resource if any */ - if (chan->confna) zt_check_conf(chan->confna); + /* save old conf number, if any */ + oldconf = chan->confna; /* initialize conference variables */ chan->_confn = 0; chan->confna = 0; chan->confmode = 0; chan->confmute = 0; + /* release conference resource, if any to release */ + if (oldconf) zt_check_conf(oldconf); chan->gotgs = 0; reset_conf(chan); @@ -911,7 +916,6 @@ static int zt_chan_reg(struct zt_chan *chan) if (maxchans < x + 1) maxchans = x + 1; chan->channo = x; - chan->flags |= ZT_FLAG_REGISTERED; if (!chan->master) chan->master = chan; if (!chan->readchunk) @@ -920,6 +924,9 @@ static int zt_chan_reg(struct zt_chan *chan) chan->writechunk = chan->swritechunk; zt_set_law(chan, 0); close_channel(chan); + /* set this AFTER running close_channel() so that + HDLC channels wont cause hangage */ + chan->flags |= ZT_FLAG_REGISTERED; res = 0; break; } @@ -1055,7 +1062,7 @@ static int zt_xmit(hdlc_device *hdlc, struct sk_buff *skb) #endif retval = 0; /* Free the SKB */ - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); } spin_unlock_irqrestore(&ss->lock, flags); return retval; @@ -1152,7 +1159,7 @@ static int zt_ppp_xmit(struct ppp_channel *ppp, struct sk_buff *skb) spin_unlock_irqrestore(&ss->lock, flags); if (retval) { /* Get rid of the SKB if we're returning non-zero */ - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); } return retval; } @@ -1435,6 +1442,9 @@ who cares what the sig bits are as long as they are stable */ ZT_ABIT | ZT_BBIT | ZT_CBIT | ZT_DBIT } /* FXO Kewlstart */ } ; int x; + + /* if no span, return doing nothing */ + if (!chan->span) return; if (!chan->span->flags & ZT_FLAG_RBS) { printk("zt_rbs: Tried to set RBS hook state on non-RBS channel %s\n", chan->name); return; @@ -1474,6 +1484,8 @@ who cares what the sig bits are as long as they are stable */ static int zt_cas_setbits(struct zt_chan *chan, int bits) { + /* if no span, return as error */ + if (!chan->span) return -1; if (chan->span->rbsbits) { chan->txsig = bits; chan->span->rbsbits(chan, bits); @@ -1485,13 +1497,15 @@ static int zt_cas_setbits(struct zt_chan *chan, int bits) static int zt_hangup(struct zt_chan *chan) { - int res=0; + int x,res=0; + /* Can't hangup pseudo channels */ if (!chan->span) return 0; /* Can't hang up a clear channel */ if (chan->flags & ZT_FLAG_CLEAR) return -EINVAL; + chan->kewlonhook = 0; if (chan->span->flags & ZT_FLAG_RBS) { if (chan->sig == ZT_SIG_CAS) { @@ -1506,6 +1520,24 @@ static int zt_hangup(struct zt_chan *chan) if (chan->span->sethook) res = chan->span->sethook(chan, ZT_ONHOOK); } + /* if not registered yet, just return here */ + if (!(chan->flags & ZT_FLAG_REGISTERED)) return res; + /* Mark all buffers as empty */ + for (x = 0;x < chan->numbufs;x++) { + chan->writen[x] = + chan->writeidx[x]= + chan->readn[x]= + chan->readidx[x] = 0; + } + chan->inreadbuf = 0; + chan->inwritebuf = 0; + chan->outreadbuf = -1; + chan->outwritebuf = -1; + chan->dialing = 0; + chan->afterdialingtimer = 0; + chan->curtone = NULL; + chan->cadencepos = 0; + chan->txdialbuf[0] = 0; return res; } @@ -1791,6 +1823,7 @@ ioctl_load_zone(unsigned long data) int x; int space; int res; + /* XXX Unnecessary XXX */ memset(samples, 0, sizeof(samples)); /* XXX Unnecessary XXX */ @@ -1879,6 +1912,7 @@ void zt_init_tone_state(struct zt_tone_state *ts, struct zt_tone *zt) struct zt_tone *zt_dtmf_tone(char digit, int mf) { struct zt_tone *z; + if (!mf) z = dtmf_tones; else @@ -1925,6 +1959,7 @@ struct zt_tone *zt_dtmf_tone(char digit, int mf) static inline void do_dtmf(struct zt_chan *chan) { char c; + while (strlen(chan->txdialbuf)) { c = chan->txdialbuf[0]; /* Skooch */ @@ -1960,6 +1995,7 @@ static int zt_release(struct inode *inode, struct file *file) int unit = UNIT(file); int res; struct zt_chan *chan; + if (!unit) return zt_ctl_release(inode, file); if (unit == 254) { @@ -1987,6 +2023,7 @@ void zt_alarm_notify(struct zt_span *span) { int j; int x; + span->alarms &= ~ZT_ALARM_LOOPBACK; /* Determine maint status */ if (span->maintstat || span->mainttimer) @@ -2031,9 +2068,10 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c { struct zt_gains gain; struct zt_spaninfo span; - struct zt_chan *chan; + struct zt_chan *chan,mychan; int i,j; struct zt_params param; + unsigned int flags; switch(cmd) { case ZT_GET_PARAMS: /* get channel timing parameters */ @@ -2203,6 +2241,45 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c span.numchans++; copy_to_user((struct tor_spaninfo *) data,&span,sizeof(span)); break; + 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 */ + spin_lock_irqsave(&chans[j]->lock, flags); + /* make static copy of channel */ + memcpy(&mychan,chans[j],sizeof(struct zt_chan)); + /* let irq's go */ + 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); + printk("flags: %x hex, writechunk: %08x, readchunk: %08x\n", + mychan.flags, (int) mychan.writechunk, (int) mychan.readchunk); + printk("rxgain: %08x, txgain: %08x, gainalloc: %d\n", + (int) mychan.rxgain, (int)mychan.txgain, mychan.gainalloc); + printk("span: %08x, sig: %x hex, sigcap: %x hex\n", + (int)mychan.span, mychan.sig, mychan.sigcap); + printk("inreadbuf: %d, outreadbuf: %d, inwritebuf: %d, outwritebuf: %d\n", + 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); + printk("txdisable: %d, rxdisable: %d, iomask: %d\n", + mychan.txdisable, mychan.rxdisable, mychan.iomask); + printk("curzone: %08x, tonezone: %d, curtone: %08x, tonep: %d\n", + (int) mychan.curzone, mychan.tonezone, (int) 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); + printk("confna: %d, confn: %d, confmode: %d, confmute: %d\n", + mychan.confna, mychan._confn, mychan.confmode, mychan.confmute); + printk("ec: %08x, echocancel: %d, deflaw: %d, xlaw: %08x\n", + (int) mychan.ec, mychan.echocancel, mychan.deflaw, (int) mychan.xlaw); + printk("itimer: %d, otimer: %d\n\n", + mychan.itimer,mychan.otimer); + break; default: return -ENOTTY; } @@ -2220,6 +2297,7 @@ static void recalc_slaves(struct zt_chan *chan) { int x; struct zt_chan *last = chan; + /* Makes no sense if you don't have a span */ if (!chan->span) return; @@ -2259,6 +2337,7 @@ static int zt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd struct zt_maintinfo maint; unsigned int flags; int rv; + switch(cmd) { case ZT_SPANCONFIG: if (copy_from_user(&lc, (struct zt_lineconfig *)data, sizeof(lc))) @@ -2538,9 +2617,10 @@ static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsign switch(cmd) { case ZT_DIALING: spin_lock_irqsave(&chan->lock, flags); - if (copy_to_user((int *)data,&chan->dialing,sizeof(int))) - return -EIO; + j = chan->dialing; spin_unlock_irqrestore(&chan->lock, flags); + if (copy_to_user((int *)data,&j,sizeof(int))) + return -EIO; return 0; case ZT_DIAL: if (copy_from_user(&tdo, (struct zt_dialoperation *)data, sizeof(tdo))) @@ -2945,6 +3025,8 @@ static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsign default: /* Check for common ioctl's and private ones */ rv = zt_common_ioctl(inode, file, cmd, data, unit); + /* if no span, just return with value */ + if (!chan->span) return rv; if ((rv == -ENOTTY) && chan->span->ioctl) rv = chan->span->ioctl(chan, cmd, data); return rv; @@ -3112,6 +3194,8 @@ static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cm return -EINVAL; if (chan->sig == ZT_SIG_CAS) return -EINVAL; + /* if no span, just do nothing */ + if (!chan->span) return(0); get_user(j,(int *)data); if (chan->span->flags & ZT_FLAG_RBS) { switch (j) { @@ -3147,8 +3231,11 @@ static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cm spin_unlock_irqrestore(&chan->lock, flags); if (file->f_flags & O_NONBLOCK) return -EINPROGRESS; +#if 0 rv = schluffen(&chan->txstateq); if (rv) return rv; +#endif + rv = 0; break; case ZT_WINK: spin_lock_irqsave(&chan->lock, flags); @@ -3178,7 +3265,7 @@ static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cm break; case ZT_RINGOFF: spin_lock_irqsave(&chan->lock, flags); - zt_rbs_sethook(chan, ZT_TXSIG_ONHOOK, ZT_TXSTATE_PREFLASH, 0); + zt_rbs_sethook(chan, ZT_TXSIG_ONHOOK, ZT_TXSTATE_ONHOOK, 0); spin_unlock_irqrestore(&chan->lock, flags); break; default: @@ -3214,6 +3301,7 @@ static int zt_prechan_ioctl(struct inode *inode, struct file *file, unsigned int struct zt_chan *chan = file->private_data; int channo; int res; + if (chan) { printk("Huh? Prechan already has private data??\n"); } @@ -3267,6 +3355,7 @@ static int zt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un int zt_register(struct zt_span *span, int prefmaster) { int x; + if (!span) return -EINVAL; if (span->flags & ZT_FLAG_REGISTERED) { @@ -3326,6 +3415,7 @@ int zt_register(struct zt_span *span, int prefmaster) int zt_unregister(struct zt_span *span) { int x; + if (!(span->flags & ZT_FLAG_REGISTERED)) { printk(KERN_ERR "Span %s does not appear to be registered\n", span->name); return -1; @@ -3492,6 +3582,7 @@ static inline short int __init alaw2linear (uint8_t alaw) static void __init zt_conv_init(void) { int i; + /* * Set up mu-law conversion table */ @@ -4097,6 +4188,7 @@ void zt_ec_chunk(struct zt_chan *ss, unsigned char *rxchunk, const unsigned char { short rxlin; int x; + /* Perform echo cancellation on a chunk if necessary */ if (!ss->ec) return; @@ -4483,7 +4575,7 @@ out in the later versions, and is put back now. */ /* Invalid SKB -- drop */ if (tmp) printk("Received invalid SKB (%02x, %02x)\n", tmp[0], tmp[1]); - kfree_skb(skb); + dev_kfree_skb_irq(skb); } else ppp_input(ms->ppp, skb); } @@ -4500,6 +4592,7 @@ zt_chan_poll(struct file *file, struct poll_table_struct *wait_table, int unit) struct zt_chan *chan = chans[unit]; int ret; long flags; + /* do the poll wait */ if (chan) { poll_wait(file, &chan->sel, wait_table); @@ -4550,6 +4643,7 @@ static unsigned int zt_poll(struct file *file, struct poll_table_struct *wait_ta static void zt_transmit_chunk(struct zt_chan *chan, unsigned char *buf) { unsigned char silly[ZT_CHUNKSIZE]; + if (!buf) buf = silly; zt_getbuf_chunk(chan, buf); @@ -4582,6 +4676,7 @@ static void zt_getempty(struct zt_chan *ms, unsigned char *buf) unsigned char *txb = buf; int x; short getlin; + while(bytes) { /* Receive silence, or tone */ if (ms->curtone) { @@ -4622,6 +4717,7 @@ static void zt_getempty(struct zt_chan *ms, unsigned char *buf) static void zt_receive_chunk(struct zt_chan *chan, unsigned char *buf) { char waste[ZT_CHUNKSIZE]; + if (!buf) { memset(waste, ZT_LIN2X(0, chan), sizeof(waste)); buf = waste; @@ -4652,6 +4748,7 @@ int zt_transmit(struct zt_span *span) { int x,y,z; unsigned long flags; + #if 1 for (x=0;x<span->channels;x++) { spin_lock_irqsave(&span->chans[x].lock, flags); @@ -4707,6 +4804,7 @@ int zt_receive(struct zt_span *span) { int x,y,z; unsigned long flags; + #if 1 for (x=0;x<span->channels;x++) { if (span->chans[x].master == &span->chans[x]) { @@ -4832,6 +4930,7 @@ static struct file_operations zt_fops = { static int __init zt_init(void) { int res = 0; + #ifdef CONFIG_DEVFS_FS { umode_t mode = S_IFCHR|S_IRUGO|S_IWUGO; @@ -4860,6 +4959,7 @@ static int __init zt_init(void) { static void __exit zt_cleanup(void) { int x; + printk(KERN_INFO "Zapata Telephony Interface Unloaded\n"); for (x=0;x<ZT_TONE_ZONE_MAX;x++) if (tone_zones[x]) |