From 9818f8728ba9432a860131579b920095308ff646 Mon Sep 17 00:00:00 2001 From: markster Date: Thu, 20 Nov 2003 17:30:56 +0000 Subject: Update to support recent fixes git-svn-id: http://svn.digium.com/svn/zaptel/trunk@278 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- zaptel.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 123 insertions(+), 17 deletions(-) diff --git a/zaptel.c b/zaptel.c index 5b77818..4694c01 100755 --- a/zaptel.c +++ b/zaptel.c @@ -9,6 +9,11 @@ * for substantial contributions to signal processing functions * in zaptel and the zapata library. * + * Yury Bokhoncovich + * Adaptation for 2.4.20+ kernels (HDLC API was changed) + * The work has been performed as a part of our move + * from Cisco 3620 to IBM x305 here in F1 Group + * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001 Linux Support Services, Inc. * @@ -1133,10 +1138,21 @@ char *zt_lboname(int x) #endif #ifdef CONFIG_ZAPATA_NET -static int zt_net_open(hdlc_device *hdlc) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) +static int zt_net_open(struct net_device *dev) { + hdlc_device *hdlc = dev_to_hdlc(dev); struct zt_chan *ms = hdlc_to_ztchan(hdlc); + int res = hdlc_open(hdlc); + +/* if (!dev->hard_start_xmit) return res; is this really necessary? --byg */ + if (res) /* this is necessary to avoid kernel panic when UNSPEC link encap, proven --byg */ + return res; +#else +static int zt_net_open(hdlc_device *hdlc) +{ int res; +#endif if (!ms) { printk("zt_net_open: nothing??\n"); return -EINVAL; @@ -1161,29 +1177,79 @@ static int zt_net_open(hdlc_device *hdlc) ms->infcs = PPP_INITFCS; MOD_INC_USE_COUNT; -#if 0 - printk("ZAPNET: Opened channel %d\n", ms->master); +#if CONFIG_ZAPATA_DEBUG + printk("ZAPNET: Opened channel %d name %s\n", ms->channo, ms->name); #endif return 0; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) +static int zt_net_stop(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); +#else static void zt_net_close(hdlc_device *hdlc) { +#endif struct zt_chan *ms = hdlc_to_ztchan(hdlc); if (!ms) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) + printk("zt_net_stop: nothing??\n"); + return 0; +#else printk("zt_net_close: nothing??\n"); return; +#endif } if (!(ms->flags & ZT_FLAG_NETDEV)) { - printk("%s is not a net device!\n", ms->name); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) + printk("zt_net_stop: %s is not a net device!\n", ms->name); + return 0; +#else + printk("zt_net_close: %s is not a net device!\n", ms->name); return; +#endif } /* Not much to do here. Just deallocate the buffers */ zt_reallocbufs(ms, 0, 0); MOD_DEC_USE_COUNT; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) + return 0; +#else return; +#endif } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) +/* kernel 2.4.20+ has introduced attach function, dunno what to do, + just copy sources from dscc4 to be sure and ready for further mastering, + NOOP right now (i.e. really a stub) --byg */ +static int zt_net_attach(hdlc_device *hdlc, unsigned short encoding, + unsigned short parity) +{ +/* struct net_device *dev = hdlc_to_dev(hdlc); + struct dscc4_dev_priv *dpriv = dscc4_priv(dev); + + if (encoding != ENCODING_NRZ && + encoding != ENCODING_NRZI && + encoding != ENCODING_FM_MARK && + encoding != ENCODING_FM_SPACE && + encoding != ENCODING_MANCHESTER) + return -EINVAL; + + if (parity != PARITY_NONE && + parity != PARITY_CRC16_PR0_CCITT && + parity != PARITY_CRC16_PR1_CCITT && + parity != PARITY_CRC32_PR0_CCITT && + parity != PARITY_CRC32_PR1_CCITT) + return -EINVAL; + + dpriv->encoding = encoding; + dpriv->parity = parity;*/ + return 0; +} +#endif + static struct zt_hdlc *zt_hdlc_alloc(void) { struct zt_hdlc *tmp; @@ -1194,10 +1260,18 @@ static struct zt_hdlc *zt_hdlc_alloc(void) return tmp; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) +static int zt_xmit(struct sk_buff *skb, struct net_device *dev) +{ + /* FIXME: this construction seems to be not very optimal for me but I could find nothing better at the moment (Friday, 10PM :( ) --byg */ +/* struct zt_chan *ss = hdlc_to_ztchan(list_entry(dev, struct zt_hdlc, netdev.netdev));*/ + struct zt_chan *ss = (list_entry(dev, struct zt_hdlc, netdev.netdev)->chan); +#else static int zt_xmit(hdlc_device *hdlc, struct sk_buff *skb) { struct zt_chan *ss = hdlc_to_ztchan(hdlc); struct net_device *dev = &ss->hdlcnetdev->netdev.netdev; +#endif int retval = 1; int x,oldbuf; unsigned int fcs; @@ -1241,7 +1315,7 @@ static int zt_xmit(hdlc_device *hdlc, struct sk_buff *skb) dev->trans_start = jiffies; ss->hdlcnetdev->netdev.stats.tx_packets++; ss->hdlcnetdev->netdev.stats.tx_bytes += ss->writen[oldbuf]; -#if 0 +#if CONFIG_ZAPATA_DEBUG printk("Buffered %d bytes to go out in buffer %d\n", ss->writen[oldbuf], oldbuf); for (x=0;xwriten[oldbuf];x++) printk("%02x ", ss->writebuf[oldbuf][x]); @@ -1255,10 +1329,17 @@ static int zt_xmit(hdlc_device *hdlc, struct sk_buff *skb) return retval; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) +static int zt_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + return hdlc_ioctl(dev, ifr, cmd); +} +#else static int zt_net_ioctl(hdlc_device *hdlc, struct ifreq *ifr, int cmd) { return -EIO; } +#endif #endif @@ -1335,7 +1416,7 @@ static int zt_ppp_xmit(struct ppp_channel *ppp, struct sk_buff *skb) some space for us */ ss->outwritebuf = oldbuf; } -#if 0 +#if CONFIG_ZAPATA_DEBUG printk("Buffered %d bytes (skblen = %d) to go out in buffer %d\n", ss->writen[oldbuf], skb->len, oldbuf); for (x=0;xwriten[oldbuf];x++) printk("%02x ", ss->writebuf[oldbuf][x]); @@ -1535,7 +1616,7 @@ static ssize_t zt_chan_write(struct file *file, const char *usrbuf, size_t count amnt = chan->blocksize; } -#if 0 +#if CONFIG_ZAPATA_DEBUG printk("zt_chan_write(unit: %d, inwritebuf: %d, outwritebuf: %d amnt: %d\n", unit, chan->inwritebuf, chan->outwritebuf, amnt); #endif @@ -1702,7 +1783,7 @@ who cares what the sig bits are as long as they are stable */ } else { for (x=0;xsig) { -#if 0 +#if CONFIG_ZAPATA_DEBUG printk("Setting bits to %d for channel %s state %d in %d signalling\n", outs[x][txsig + 1], chan->name, txsig, chan->sig); #endif chan->txhooksig = txsig; @@ -2668,14 +2749,14 @@ static void recalc_slaves(struct zt_chan *chan) if (!chan->span) return; -#if 0 +#if CONFIG_ZAPATA_DEBUG printk("Recalculating slaves on %s\n", chan->name); #endif /* Link all slaves appropriately */ for (x=chan->chanpos;xspan->channels;x++) if (chan->span->chans[x].master == chan) { -#if 0 +#if CONFIG_ZAPATA_DEBUG printk("Channel %s, slave to %s, last is %s, its next will be %d\n", chan->span->chans[x].name, chan->name, last->name, x); #endif @@ -2684,7 +2765,7 @@ static void recalc_slaves(struct zt_chan *chan) } /* Terminate list */ last->nextslave = 0; -#if 0 +#if CONFIG_ZAPATA_DEBUG printk("Done Recalculating slaves on %s (last is %s)\n", chan->name, last->name); #endif } @@ -2843,12 +2924,22 @@ static int zt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd (chans[ch.chan]->sig == ZT_SIG_HDLCNET)) { chans[ch.chan]->hdlcnetdev = zt_hdlc_alloc(); if (chans[ch.chan]->hdlcnetdev) { +/* struct hdlc_device *hdlc = chans[ch.chan]->hdlcnetdev; + struct net_device *d = hdlc_to_dev(hdlc); mmm...get it right later --byg */ chans[ch.chan]->hdlcnetdev->chan = chans[ch.chan]; chans[ch.chan]->hdlcnetdev->netdev.ioctl = zt_net_ioctl; + chans[ch.chan]->hdlcnetdev->netdev.netdev.do_ioctl = zt_net_ioctl; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) + chans[ch.chan]->hdlcnetdev->netdev.netdev.open = zt_net_open; + chans[ch.chan]->hdlcnetdev->netdev.netdev.stop = zt_net_stop; + chans[ch.chan]->hdlcnetdev->netdev.xmit = zt_xmit; + chans[ch.chan]->hdlcnetdev->netdev.attach = zt_net_attach; +#else chans[ch.chan]->hdlcnetdev->netdev.open = zt_net_open; chans[ch.chan]->hdlcnetdev->netdev.close = zt_net_close; chans[ch.chan]->hdlcnetdev->netdev.set_mode = NULL; chans[ch.chan]->hdlcnetdev->netdev.xmit = zt_xmit; +#endif chans[ch.chan]->hdlcnetdev->netdev.netdev.irq = chans[ch.chan]->span->irq; chans[ch.chan]->hdlcnetdev->netdev.netdev.tx_queue_len = 50; res = register_hdlc_device(&chans[ch.chan]->hdlcnetdev->netdev); @@ -2878,7 +2969,7 @@ static int zt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd if (y >= 0) chans[ch.chan]->rxsig = (unsigned char)y; chans[ch.chan]->rxhooksig = ZT_RXSIG_INITIAL; } -#if 0 +#if 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 spin_unlock_irqrestore(&chans[ch.chan]->lock, flags); @@ -4281,6 +4372,12 @@ static inline void __zt_process_getaudio_chunk(struct zt_chan *ss, unsigned char txb[x] = ZT_LIN2X(getlin[x], ms); break; case ZT_CONF_DIGITALMON: + { static int blah = 0; + if (blah++ < 64) { + printk("Got here channel %d, from %d\n", + ms->channo, ms->confna); + } + } /* Real digital monitoring, but still echo cancel if desired */ if (chans[ms->confna]->flags & ZT_FLAG_PSEUDO) { if (ms->ec) { @@ -4658,7 +4755,7 @@ static void __zt_hooksig_pvt(struct zt_chan *chan, zt_rxsig_t rxsig) zt_rbs_sethook(chan,ZT_TXSIG_OFFHOOK, ZT_TXSTATE_AFTERSTART, ZT_AFTERSTART_TIME); } chan->kewlonhook = 0; -#if 0 +#if CONFIG_ZAPATA_DEBUG printk("Off hook on channel %d, itimer = %d, gotgs = %d\n", chan->channo, chan->itimer, chan->gotgs); #endif if (chan->itimer) /* if timer still running */ @@ -5158,13 +5255,13 @@ static inline void __zt_putbuf_chunk(struct zt_chan *ss, unsigned char *rxb) oldbuf = ms->inreadbuf; ms->infcs = PPP_INITFCS; ms->readn[ms->inreadbuf] = ms->readidx[ms->inreadbuf]; -#if 0 +#if CONFIG_ZAPATA_DEBUG printk("EOF, len is %d\n", ms->readn[ms->inreadbuf]); #endif #if defined(CONFIG_ZAPATA_NET) || defined(CONFIG_ZAPATA_PPP) if (ms->flags & (ZT_FLAG_NETDEV | ZT_FLAG_PPP)) { /* Our network receiver logic is MUCH - different. We actually only us a single + different. We actually only use a single buffer */ if (ms->readn[ms->inreadbuf] > 1) { /* Drop the FCS */ @@ -5213,7 +5310,7 @@ static inline void __zt_putbuf_chunk(struct zt_chan *ss, unsigned char *rxb) /* Whoops, we're full, and have no where else to store into at the moment. We'll drop it until there's a buffer available */ -#if 0 +#if CONFIG_ZAPATA_DEBUG printk("Out of storage space\n"); #endif ms->inreadbuf = -1; @@ -5236,7 +5333,7 @@ out in the later versions, and is put back now. */ if (!ms->rxdisable) { /* if receiver enabled */ /* Notify a blocked reader that there is data available to be read, unless we're waiting for it to be full */ -#if 0 +#if CONFIG_ZAPATA_DEBUG printk("Notifying reader data in block %d\n", oldbuf); #endif wake_up_interruptible(&ms->readbufq); @@ -5281,8 +5378,17 @@ out in the later versions, and is put back now. */ break; #ifdef CONFIG_ZAPATA_NET if (skb && (ms->flags & ZT_FLAG_NETDEV)) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) + { + skb->mac.raw = skb->data; + skb->dev = &ms->hdlcnetdev->netdev.netdev; + skb->protocol = hdlc_type_trans(skb, &ms->hdlcnetdev->netdev.netdev); + netif_rx(skb); + } +#else hdlc_netif_rx(&ms->hdlcnetdev->netdev, skb); #endif +#endif #ifdef CONFIG_ZAPATA_PPP if (skb && (ms->flags & ZT_FLAG_PPP)) { unsigned char *tmp; -- cgit v1.2.3