[Asterisk-Users] FW: Voice/Data mixed routing over Digium E1/T1 Card

Mark Spencer markster at digium.com
Sun Nov 2 10:51:57 MST 2003


> To try and put it simply, the zaptel drivers will not compile with the
> -DZAPTEL_NETWORK flag (as set, not my default, in the Makefile), with any
> stock kernel including and after 2.4.21, which is when the new HDLC structure
> was imported from the development kernel tree.

I have a patch for 2.4.21 that I was supplied, but I haven't tested it and
I don't know if sethdlc also requires patching.  Please try the attached
patch and if it works let me know so I can apply it.  Thanks!

Mark
-------------- next part --------------
--- zaptel/zaptel.c.orig	2003-09-29 11:59:40.000000000 +0700
+++ zaptel.c	2003-10-29 10:15:59.000000000 +0600
@@ -9,6 +9,11 @@
  * for substantial contributions to signal processing functions 
  * in zaptel and the zapata library.
  *
+ * Yury Bokhoncovich <byg at cf1.ru>
+ * 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.
  *
@@ -1121,10 +1126,21 @@
 #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;
@@ -1149,29 +1165,79 @@
 	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;
@@ -1182,10 +1248,18 @@
 	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;
@@ -1229,7 +1303,7 @@
 		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;x<ss->writen[oldbuf];x++)
 		     printk("%02x ", ss->writebuf[oldbuf][x]);
@@ -1243,10 +1317,17 @@
 	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
 
@@ -1323,7 +1404,7 @@
 			   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;x<ss->writen[oldbuf];x++)
 		     printk("%02x ", ss->writebuf[oldbuf][x]);
@@ -1523,7 +1604,7 @@
 			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
@@ -1690,7 +1771,7 @@
 	} else {
 		for (x=0;x<NUM_SIGS;x++) {
 			if (outs[x][0] == chan->sig) {
-#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;
@@ -2647,14 +2728,14 @@
 	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;x<chan->span->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
@@ -2663,7 +2744,7 @@
 		}
 	/* 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
 }
@@ -2811,12 +2892,22 @@
 		        (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);
@@ -2846,7 +2937,7 @@
 			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);
@@ -4593,7 +4684,7 @@
 				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 */
@@ -5062,13 +5153,13 @@
 				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 */
@@ -5117,7 +5208,7 @@
 						/* 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;
@@ -5140,7 +5231,7 @@
 					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);
@@ -5185,8 +5276,17 @@
 			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;


More information about the asterisk-users mailing list