[Pkg-voip-commits] r1749 - in zaptel/trunk/debian: . patches

Tzafrir Cohen tzafrir-guest at costa.debian.org
Tue May 9 05:19:30 UTC 2006


Author: tzafrir-guest
Date: 2006-05-09 05:19:27 +0000 (Tue, 09 May 2006)
New Revision: 1749

Modified:
   zaptel/trunk/debian/changelog
   zaptel/trunk/debian/genzaptelconf
   zaptel/trunk/debian/patches/Makefile_bristuff.dpatch
   zaptel/trunk/debian/patches/bristuff.dpatch
   zaptel/trunk/debian/rules
Log:
* bristuff: 0.3.0-PRE1o
* We have another ZapBRI module: ztgsm
* Experimental support in genzaptelconf for ztgsm (from sample files)


Modified: zaptel/trunk/debian/changelog
===================================================================
--- zaptel/trunk/debian/changelog	2006-05-07 22:19:35 UTC (rev 1748)
+++ zaptel/trunk/debian/changelog	2006-05-09 05:19:27 UTC (rev 1749)
@@ -8,8 +8,13 @@
   * Weed out old unused patches. Add comments which patches have been included
     upstream for next release.
 
- -- Kilian Krause <kilian at debian.org>  Sun, 30 Apr 2006 18:29:16 +0200
+  [ Tzafrir Cohen ]
+  * bristuff: 0.3.0-PRE1o
+  * We have another ZapBRI module: ztgsm
+  * Experimental support in genzaptelconf for ztgsm (from sample files)
 
+ -- Tzafrir Cohen <tzafrir.cohen at xorcom.com>  Mon,  8 May 2006 08:07:38 +0300
+
 zaptel (1:1.2.5-1) unstable; urgency=low
 
   [ Tzafrir Cohen ]

Modified: zaptel/trunk/debian/genzaptelconf
===================================================================
--- zaptel/trunk/debian/genzaptelconf	2006-05-07 22:19:35 UTC (rev 1748)
+++ zaptel/trunk/debian/genzaptelconf	2006-05-09 05:19:27 UTC (rev 1749)
@@ -83,7 +83,7 @@
 # - the list of modules which will be unloaded (in this order)
 # - the list of modules which will be probed (in this order)
 #ALL_MODULES="zaphfc qozap wctdm wctdm24xxp wcfxo wcfxs pciradio tor2 torisa wct1xxp wct4xxp wcte11xp wcusb ztdynamic ztd_eth ztdummy xpp_usb xpd_fxs xpp"
-ALL_MODULES="zaphfc qozap wctdm wctdm24xxp wcfxo wcfxs pciradio tor2 torisa wct1xxp wct4xxp wcte11xp wcusb ztd_eth xpp_usb"
+ALL_MODULES="zaphfc qozap ztgsm wctdm wctdm24xxp wcfxo wcfxs pciradio tor2 torisa wct1xxp wct4xxp wcte11xp wcusb xpp_usb"
 
 # read default configuration from /etc/default/zaptel
 if [ -r $ZAPTEL_BOOT ]; then . $ZAPTEL_BOOT; fi
@@ -491,6 +491,8 @@
 
 #	print_pattern $chan_num $chan_sig_type $mode
 	
+  # if you get syntax error from this line, make sure you use 'bash' 
+  # rather than 'sh'
 	$ztcfg_cmd -c <(print_pattern $chan_num $chan_sig_type zaptel) 2>/dev/null  \
 		|| return 1
 	if head -c1 /dev/zap/$chan_num >/dev/null 2>/dev/null
@@ -630,7 +632,7 @@
 			*XPP_IN/*)
 				print_pattern -a input $chan_num fxo $mode
 				;;
-			*ZTHFC*/*|*ztqoz*/*|*WCT1/*) # should also be used for other PRI channels
+			*ZTHFC*/*|*ztqoz*/*|*ztgsm/*|*WCT1/*) # should also be used for other PRI channels
 				if [ "`cat $tmp_dir/span_begin`" = "-1" ]
 				then
 					echo $chan_num      >$tmp_dir/span_begin
@@ -646,6 +648,11 @@
 							echo 'bri_cpe' >$tmp_dir/span_signalling
 						fi
 						;;
+					*ztgsm*/*)
+						echo 'ccs'          >$tmp_dir/span_framing
+            # what switch type? Any meaning to it?
+						echo 'gsm'          >$tmp_dir/span_signalling
+						;;
 					*WCT1/*)
 						echo 'esf'       >$tmp_dir/span_framing
 						echo 'b8zs'      >$tmp_dir/span_coding
@@ -685,7 +692,7 @@
 			# exactly the same logic is used in asterisk's chan_zap.c.
 			# also not that $(( )) is bash-specific
 			case "$((1+ $span_end - $span_begin))" in
-			3|24) #BRI or T1
+			2|3|24) #ztgsm, BRI or T1
 			  dchan=$span_end
 				bchans="$span_begin-$(($span_end-1))"
 				;;

Modified: zaptel/trunk/debian/patches/Makefile_bristuff.dpatch
===================================================================
--- zaptel/trunk/debian/patches/Makefile_bristuff.dpatch	2006-05-07 22:19:35 UTC (rev 1748)
+++ zaptel/trunk/debian/patches/Makefile_bristuff.dpatch	2006-05-09 05:19:27 UTC (rev 1749)
@@ -13,12 +13,12 @@
  	 ztdynamic ztd-eth wct1xxp wct4xxp wcte11xp pciradio \
           ztd-loc # ztdummy
 +
-+BRIMODS=cwain qozap zaphfc
++BRIMODS=cwain qozap zaphfc ztgsm
 +MODULES+=$(BRIMODS)
  #MODULES+=wcfxsusb
  # build ztdummy by default for 2.6 kernels
  ifeq (${BUILDVER},linux26)
-@@ -228,6 +231,26 @@
+@@ -228,6 +231,29 @@
  
  ztdummy.o: ztdummy.h
  
@@ -32,6 +32,9 @@
 +
 +# copy bristuff files from subdirectories
 +# provide zaphfc.[ch] from zaphfc/zaphfc.[ch] etc. Any better way?
++ztgsm.%: ztgsm/ztgsm.%
++	cp $^ $@
++
 +zaphfc.%: zaphfc/zaphfc.%
 +	cp $^ $@
 +

Modified: zaptel/trunk/debian/patches/bristuff.dpatch
===================================================================
--- zaptel/trunk/debian/patches/bristuff.dpatch	2006-05-07 22:19:35 UTC (rev 1748)
+++ zaptel/trunk/debian/patches/bristuff.dpatch	2006-05-09 05:19:27 UTC (rev 1749)
@@ -2,14 +2,14 @@
 ## bristuff.dpatch by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
 ##
 ## All lines beginning with `## DP:' are a description of the patch.
-## DP: The zapbri modules (cwain, qozap, zaphfc) and zaptel patch from the 
-## DP: bristuff patch by Klaus-Peter Junghanns. Version 0.3.0-PRE1k
+## DP: The zapbri modules (cwain, qozap, zaphfc, ztgsm) and zaptel.patch from
+## DP: the bristuff patch by Klaus-Peter Junghanns. Version 0.3.0-PRE1o
 
 @DPATCH@
-diff -urNad zaptel-1.2.3/cwain/cwain.c /tmp/dpep.Uu0Ujg/zaptel-1.2.3/cwain/cwain.c
---- zaptel-1.2.3/cwain/cwain.c	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/cwain/cwain.c	2006-01-27 05:39:03.000000000 +0200
-@@ -0,0 +1,1492 @@
+diff -urNad zaptel-1.2.5/cwain/cwain.c /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/cwain.c
+--- zaptel-1.2.5/cwain/cwain.c	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/cwain.c	2006-04-25 16:38:17.000000000 +0300
+@@ -0,0 +1,1629 @@
 +/*
 + * cwain.c - Zaptel driver for the Junghanns.NET E1 card
 + *
@@ -138,10 +138,16 @@
 +    spin_unlock_irqrestore(&cwaintmp->lock,flags);
 +
 +    for (i=0;i<cwaintmp->spans;i++) {
++	release_region(cwaintmp->span[i]->ioport, 8);
++	cwaintmp->span[i]->ioport = 0;
 +	iounmap((void *) cwaintmp->span[i]->pci_io);
 +	cwaintmp->span[i]->pci_io = NULL;
++	release_mem_region((unsigned long)cwaintmp->span[i]->pci_io_phys, 256);
 +    }
 +
++    if (cwaintmp->spans == 2) {
++	free_irq(cwaintmp->span[1]->irq,cwaintmp);
++    }
 +    free_irq(cwaintmp->irq,cwaintmp);
 +}
 +
@@ -183,7 +189,7 @@
 +
 +void cwain_reset_span(struct zt_cwain *cwaintmp) {
 +    int i = 0;
-+    pci_write_config_word(cwaintmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY);	// enable memio
++    pci_write_config_word(cwaintmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_IO);	// enable memio
 +
 +    /* FIFO, HDLC reset */
 +    cwain_outb(cwaintmp,cwain_R_CIRM,0x10);
@@ -216,6 +222,7 @@
 +    cwain_outb(cwaintmp,cwain_R_GPIO_OUT1,0x0f);
 +
 +    /* IRQs off */
++    cwain_outb(cwaintmp,cwain_R_IRQMSK_MISC,0x0); 
 +    cwain_outb(cwaintmp,cwain_R_IRQ_CTRL,0x0); 
 +
 +    cwaintmp->leds[0] = 1;    
@@ -289,8 +296,8 @@
 +	cwaintmp->cardID = cwainspan->cardID;
 +	cwain_register_card(cwaintmp);
 +	printk(KERN_INFO
-+	        "cwain: Junghanns.NET singleE1 PCI ISDN card configured at mem %#x IRQ %d HZ %d CardID %d\n",
-+	          (u_int) cwainspan->pci_io,
++	        "cwain: Junghanns.NET singleE1 PCI ISDN card configured at mem %lx IRQ %d HZ %d CardID %d\n",
++	          (unsigned long) cwainspan->pci_io,
 +	        cwaintmp->span[0]->irq, HZ, cwainspan->cardID);
 +    } else {
 +	cwaintmp = cwain_get_card(cwainspan->pcibus);
@@ -321,8 +328,8 @@
 +		cwaintmp->syncs[1] = -1;
 +	    }
 +	    printk(KERN_INFO
-+	        "cwain: Junghanns.NET doubleE1 PCI ISDN card configured at mem (%#x / %#x) IRQ %d HZ %d CardID (%d / %d) bus %#x\n",
-+	          (u_int) cwaintmp->span[0]->pci_io, (u_int) cwaintmp->span[1]->pci_io,
++	        "cwain: Junghanns.NET doubleE1 PCI ISDN card configured at mem (%lx / %lx) IRQ %d HZ %d CardID (%d / %d) bus %#x\n",
++	          (unsigned long) cwaintmp->span[0]->pci_io, (unsigned long) cwaintmp->span[1]->pci_io,
 +	        cwaintmp->span[0]->irq, HZ, cwaintmp->span[0]->cardID, cwaintmp->span[1]->cardID, cwaintmp->pcibus);
 +	}
 +    }
@@ -366,7 +373,7 @@
 +}
 +
 +static int cwain_fifo_tx(struct zt_cwain *cwaintmp, char fifo) {
-+    int chan;
++    int chan,f;
 +    if (fifo >= 15) {
 +	chan = fifo;
 +    } else {
@@ -375,10 +382,10 @@
 +    /* select fifo */
 +    cwain_outb(cwaintmp,cwain_R_FIFO,0x80 | (fifo << 1));    
 +    cwain_waitbusy(cwaintmp);
-+    /* transmit 8 bytes of transparent data */
-+    cwain_outdw(cwaintmp,cwain_A_FIFO_DATA0,*((unsigned int *) &cwaintmp->txbuf[chan][0]));
-+    cwain_outdw(cwaintmp,cwain_A_FIFO_DATA0,*((unsigned int *) &cwaintmp->txbuf[chan][4]));
-+	    
++    
++    for (f=0; f < (cwain_FRAME_SIZE/4); f++) {
++	cwain_outdw(cwaintmp,cwain_A_FIFO_DATA0,*((unsigned int *) &cwaintmp->ftxbuf[chan][f * 4]));
++    }
 +    return 0;
 +}
 +
@@ -453,18 +460,14 @@
 +
 +static int cwain_fifo_rx(struct zt_cwain *cwaintmp, char fifo) {
 +    int chan;
-+    unsigned char data;
-+    int len,i;
++    unsigned int data;
++    int len,i,f,flen;
 +    unsigned short z1=1,z2=1;
 +    unsigned short oz1=0,oz2=0;
 +    int mumbojumbo=0;
 +    int x = 1000;
 +
-+    if (fifo >= 15) {
-+	chan = fifo; /* +1 */
-+    } else {
-+	chan = fifo;
-+    }
++    chan = fifo;
 +
 +    // select rx fifo
 +    
@@ -473,43 +476,46 @@
 +        cwain_waitbusy(cwaintmp);
 +    
 +	while (x-- && ((oz1 != z1) && (oz2 != z2))) {
++	    len = z1 - z2;
++	    if (len < 0) {
++		len += cwain_FIFO_SIZE;
++	    }
++	    flen = len;
++	    if (len > cwain_FIFO_HW) {
++		mumbojumbo = len - (cwain_FIFO_HW - cwain_FRAME_SIZE);
++	        len = cwain_FRAME_SIZE;
++	    }
 +	    oz1 = z1;
 +	    oz2 = z2;
-+	    z1 = cwain_inw(cwaintmp,cwain_A_Z1) & 0x1ff;
-+    	    z2 = cwain_inw(cwaintmp,cwain_A_Z2) & 0x1ff;
++	    z1 = cwain_inw(cwaintmp,cwain_A_Z1) & 0x7f;
++    	    z2 = cwain_inw(cwaintmp,cwain_A_Z2) & 0x7f;
 +	}
 +	if (x < 500) {
 +	    printk(KERN_CRIT "cwain: prevented endless loop\n");
 +	}
 +    
-+	len = z1-(z2 & 0x1ff);
-+	if (len < 0) {
-+	    len += cwain_FIFO_SIZE;
-+	}
-+//	if (len > 2 * ZT_CHUNKSIZE) {
-+	if (len > cwain_FIFO_HW) {
-+//	    mumbojumbo = len - (2 * ZT_CHUNKSIZE);
-+	    mumbojumbo = len - (cwain_FIFO_HW);
-+	    len = ZT_CHUNKSIZE;
-+	    for (i=0;i<mumbojumbo;i++) {
-+    		data = cwain_inb(cwaintmp,cwain_A_FIFO_DATA0);
++	if (mumbojumbo > 0) {
++	    for (i=0;i<(mumbojumbo/4);i++) {
++    		data = cwain_indw(cwaintmp,cwain_A_FIFO_DATA0);
 +	    }
 +	    cwaintmp->clicks++;
 +	}
-+	if (len < ZT_CHUNKSIZE) {
-+	    if (cwaintmp->clicks > 501) {
++	if (len < cwain_FRAME_SIZE) {
++	    /* dont get nervous here */
++	    if ((cwaintmp->clicks > 600) && (cwaintmp->span.alarms == ZT_ALARM_NONE)) {
 +		printk(KERN_INFO "cwain: not enough to receive (%d bytes)\n",len);
 +	    }
 +	    return 0;
 +	} else {
-+	    *((unsigned int *) &cwaintmp->rxbuf[chan][0]) = cwain_indw(cwaintmp,cwain_A_FIFO_DATA0);
-+	    *((unsigned int *) &cwaintmp->rxbuf[chan][4]) = cwain_indw(cwaintmp,cwain_A_FIFO_DATA0);
++	    for (f=0;f<(cwain_FRAME_SIZE / 4);f++) {
++		*((unsigned int *) &cwaintmp->frxbuf[chan][f*4]) = cwain_indw(cwaintmp,cwain_A_FIFO_DATA0);
++	    }
 +	}
 +
-+	zt_ec_chunk(&cwaintmp->span.chans[chan], cwaintmp->span.chans[chan].readchunk, cwaintmp->span.chans[chan].writechunk);
 +
-+	if (cwaintmp->clicks > 500) {
-+	    printk(KERN_INFO "cwain: span %d dropped audio fifo %d mj %d\n", cwaintmp->cardID, fifo, mumbojumbo);
++	/* dont get nervous here */
++	if ((cwaintmp->clicks > 500) && (cwaintmp->span.alarms == ZT_ALARM_NONE)) {
++	    printk(KERN_INFO "cwain: span %d dropped audio fifo %d mj %d flen %d z1 %d z2 %d\n", cwaintmp->cardID, fifo, mumbojumbo, flen, z1, z2);
 +	    cwaintmp->clicks = 0;
 +	}
 +//    printk(KERN_INFO "s/t port %d, channel %d, dbufi=%d, f1=%d, f2=%d, z1=%d, z2=%d  => len = %d stat=%#x, hdlc=%d\n",stport,chan,cwaintmp->st[stport].dbufi,f1,f2,z1,z2,len,stat,hdlc);    
@@ -568,9 +574,17 @@
 +void cwain_check_timing(struct zt_cwain_card *cwaintmp) {
 +    int i=0;
 +    int bestsync = 42;
++    int sync_ok = 0;
 +
 +    for (i=0; i < cwaintmp->spans; i++) {
-+        if ((cwaintmp->syncs[i] > 0) && ((cwaintmp->span[i]->sync_sta & 0x7) == 0x7)) {
++	if (cwaintmp->span[i]->span.lineconfig & ZT_CONFIG_CRC4) {
++	    /* CRC4 requested */
++	    sync_ok = 0x27;
++	} else {
++	    /* doubleframing requested */
++	    sync_ok = 0x07;
++	}    
++        if ((cwaintmp->syncs[i] > 0) && ((cwaintmp->span[i]->sync_sta & sync_ok) == sync_ok)) {
 +    	    if (bestsync < cwaintmp->spans) {
 +		if (cwaintmp->syncs[i] < cwaintmp->syncs[bestsync]) {
 +	    	    bestsync = i;
@@ -632,7 +646,7 @@
 +    }
 +}
 +
-+static inline void cwain_isr_run(struct zt_cwain *cwaintmp) {
++static inline void cwain_isr_run(struct zt_cwain *cwaintmp, int ticks) {
 +    int fifo=0;
 +    if (cwaintmp->span.flags & ZT_FLAG_RUNNING) {
 +        /* oh zaptel! tell us what to transmit... */
@@ -640,8 +654,13 @@
 +	/* B chans 1-15 mapped to fifos 0-14 */
 +	/* B chans 17-31 mapped to fifos 15-29 */
 +	for (fifo=0; fifo < 30; fifo++) {
-+	    /* B xmit */
-+	    cwain_fifo_tx(cwaintmp, fifo);
++	    /* copy to fbuffer */
++	    if ((ticks < 1) || (ticks > 8)) {
++		printk(KERN_INFO "cwain: whicked ticks make whicked tricks (%d)\n",cwaintmp->ticks);
++	    } else {
++		memcpy(&cwaintmp->ftxbuf[fifo][(ticks-1)*8], cwaintmp->txbuf[fifo], ZT_CHUNKSIZE);
++	    }
++
 +	}
 +	if (cwaintmp->sync) {
 +	    cwain_dfifo_tx(cwaintmp);
@@ -653,8 +672,9 @@
 +	cwaintmp->chans[15].eoftx = 0;
 +
 +	for (fifo=0; fifo < 30; fifo++) {
-+	    /* B rx */
-+	    cwain_fifo_rx(cwaintmp, fifo);
++	    /* copy from fbuffer */
++	    memcpy(cwaintmp->rxbuf[fifo], &cwaintmp->frxbuf[fifo][(ticks-1)*8], ZT_CHUNKSIZE);
++	    zt_ec_chunk(&cwaintmp->span.chans[fifo], cwaintmp->span.chans[fifo].readchunk, cwaintmp->span.chans[fifo].writechunk);
 +	}
 +
 +	/* d-chan data */
@@ -668,120 +688,160 @@
 +    }
 +}
 +
-+void cwain_isr_sync(struct zt_cwain *cwainspan) {
++static inline void cwain_isr_err(struct zt_cwain *cwaintmp) {
++    unsigned short crc, vio, ebit, fas;
++
++    crc = (cwain_inb(cwaintmp, cwain_R_CRC_ECH) << 8) | cwain_inb(cwaintmp, cwain_R_CRC_ECL);
++    vio = (cwain_inb(cwaintmp, cwain_R_VIO_ECH) << 8) | cwain_inb(cwaintmp, cwain_R_VIO_ECL);
++    ebit = (cwain_inb(cwaintmp, cwain_R_E_ECH) << 8) | cwain_inb(cwaintmp, cwain_R_E_ECL);
++    fas = (cwain_inb(cwaintmp, cwain_R_FAS_ECH) << 8) | cwain_inb(cwaintmp, cwain_R_FAS_ECL);
++			
++    cwaintmp->span.crc4count += crc;
++    cwaintmp->span.bpvcount += vio;
++    cwaintmp->span.ebitcount += ebit;
++    cwaintmp->span.fascount += fas;
++			
++    if (debug > 2)
++        printk("cwain: CRC4 %d BPVIOL %d EBIT %d FAS %d\n", crc, vio, ebit, fas);
++}
++						    		    
++
++static inline void cwain_audio_run(struct zt_cwain *cwaintmp) {
++    int fifo=0;
++	for (fifo=0; fifo < 30; fifo++) {
++	    /* B xmit */
++	    cwain_fifo_tx(cwaintmp, fifo);
++	}
++
++	for (fifo=0; fifo < 30; fifo++) {
++	    /* B rx */
++	    cwain_fifo_rx(cwaintmp, fifo);
++	}
++}
++
++int cwain_isr_sync(struct zt_cwain *cwainspan) {
 +    unsigned char sync_sta;
 +    unsigned char sync_ok = 0;
 +    unsigned char jatt_sta = 0;
++    int res = 0; /* assume no l1event */
 +
 +    if (!cwainspan->span.flags & ZT_FLAG_RUNNING) {
-+	return;
++	return res;
 +    }
 +
 +    sync_sta = cwain_inb(cwainspan, cwain_R_SYNC_STA);
 +
-+if ((!cwainspan->sync) || (sync_sta != cwainspan->sync_sta)) {
++    if ((!cwainspan->sync) || (sync_sta != cwainspan->sync_sta)) {
 +
-+    if (debug > 2)
-+	printk(KERN_CRIT "cwain: cardID %d R_SYNC_STA =%#x\n", cwainspan->cardID, sync_sta);
++	if (debug > 2)
++	    printk(KERN_CRIT "cwain: cardID %d R_SYNC_STA =%#x\n", cwainspan->cardID, sync_sta);
 +
-+    if (cwainspan->span.lineconfig & ZT_CONFIG_CRC4) {
-+	if ((sync_sta & 0x80) == 0x80) {
-+	    /* reset MFA detection */
-+	    cwain_outb(cwainspan ,cwain_R_RX_SL0_CFG1,0x41);
-+	} else if ((sync_sta & 0x27) == 0x27) {
-+	    if ((cwainspan->sync_sta & 0x27) != 0x27) {
-+		/* sync achieved, restart JATT */
-+		if (debug)
-+		    printk(KERN_INFO "cwain: %d starting jitter attenuator\n", cwainspan->cardID);
-+		cwain_outb(cwainspan, cwain_R_JATT_CFG,0x9c);
++	if (cwainspan->span.lineconfig & ZT_CONFIG_CRC4) {
++	    if ((sync_sta & 0x80) == 0x80) {
++		/* reset MFA detection */
++		cwain_outb(cwainspan ,cwain_R_RX_SL0_CFG1,0x41);
++	    } else if ((sync_sta & 0x27) == 0x27) {
++		if ((cwainspan->sync_sta & 0x27) != 0x27) {
++		    /* sync achieved, restart JATT */
++		    if (debug)
++			printk(KERN_INFO "cwain: %d starting jitter attenuator\n", cwainspan->cardID);
++		    cwain_outb(cwainspan, cwain_R_JATT_CFG,0x9c);
++		}
++		sync_ok = 0x27;
++	    } else {
++		sync_ok = 0x00;
 +	    }
-+	    sync_ok = 0x27;
 +	} else {
-+	    sync_ok = 0x00;
-+	}
-+    } else {
-+	if ((sync_sta & 0x07) == 0x07) {
-+	    if ((cwainspan->sync_sta & 0x7) != 0x7) {
-+		/* sync achieved, restart JATT */
-+		if (debug)
-+		    printk(KERN_INFO "cwain: %d starting jitter attenuator\n", cwainspan->cardID);
-+		cwain_outb(cwainspan, cwain_R_JATT_CFG,0x9c);
++	    if ((sync_sta & 0x07) == 0x07) {
++		if ((cwainspan->sync_sta & 0x7) != 0x7) {
++		    /* sync achieved, restart JATT */
++		    if (debug)
++			printk(KERN_INFO "cwain: %d starting jitter attenuator\n", cwainspan->cardID);
++		    cwain_outb(cwainspan, cwain_R_JATT_CFG,0x9c);
++		}
++		sync_ok = 0x07;
++	    } else {
++		sync_ok = 0x00;
 +	    }
-+	    sync_ok = 0x07;
-+	} else {
-+	    sync_ok = 0x00;
 +	}
-+    }
 +
-+    cwainspan->sync_sta = sync_sta;
++	cwainspan->sync_sta = sync_sta;
 +
-+    jatt_sta = cwain_inb(cwainspan, cwain_R_JATT_STA);
-+    if ((jatt_sta & 0x60) != 0x60) {
-+	if (debug > 2)
-+	    printk(KERN_INFO "cwain: %d jitter attenuator %#x\n", cwainspan->cardID, (jatt_sta & 0x60) >> 5);
-+	sync_ok = 0x00;
-+    } else if (!cwainspan->sync && sync_ok) {
-+	if (debug)
-+	    printk(KERN_CRIT "cwain: %d jitter attenuator %#x ok!\n", cwainspan->cardID, (jatt_sta & 0x60) >> 5);
-+    }
++	jatt_sta = cwain_inb(cwainspan, cwain_R_JATT_STA);
++	if ((jatt_sta & 0x60) != 0x60) {
++	    if (debug > 2)
++		printk(KERN_INFO "cwain: %d jitter attenuator %#x\n", cwainspan->cardID, (jatt_sta & 0x60) >> 5);
++	    sync_ok = 0x00;
++	} else if (!cwainspan->sync && sync_ok) {
++	    if (debug)
++		printk(KERN_CRIT "cwain: %d jitter attenuator %#x ok!\n", cwainspan->cardID, (jatt_sta & 0x60) >> 5);
++	}
 +
-+    if (sync_ok && (!cwainspan->sync)) {
-+	/* elastic buffer offsets */
-+	cwain_outb(cwainspan,cwain_R_RX_OFFS,0x06);
-+	cwain_outb(cwainspan,cwain_R_TX_OFFS,0x06);
++	if (sync_ok && (!cwainspan->sync)) {
++	    /* elastic buffer offsets */
++	    cwain_outb(cwainspan,cwain_R_RX_OFFS,0x06);
++	    cwain_outb(cwainspan,cwain_R_TX_OFFS,0x06);
 +
-+	if (debug > 2)
-+	    printk(KERN_INFO "cwain: enabling D channel fifos\n");
-+	cwain_outb(cwainspan,cwain_R_FIFO,0x1F << 1);
-+	cwain_waitbusy(cwainspan);
-+	cwain_outb(cwainspan,cwain_A_CON_HDLC,0xd);
-+	cwain_outb(cwainspan,cwain_A_IRQ_MSK,0x1);
++	    if (debug > 2)
++		printk(KERN_INFO "cwain: enabling D channel fifos\n");
++	    cwain_outb(cwainspan,cwain_R_FIFO,0x1F << 1);
++	    cwain_waitbusy(cwainspan);
++	    cwain_outb(cwainspan,cwain_A_CON_HDLC,0xd);
++	    cwain_outb(cwainspan,cwain_A_IRQ_MSK,0x1);
 +	
-+	cwain_outb(cwainspan,cwain_R_FIFO,(0x1F << 1) | 1);
-+	cwain_waitbusy(cwainspan);
-+	cwain_outb(cwainspan,cwain_A_CON_HDLC,0xd);
-+	cwain_outb(cwainspan,cwain_A_IRQ_MSK,0x1);
-+	cwainspan->span.alarms = ZT_ALARM_NONE;
-+	zt_alarm_notify(&cwainspan->span);
-+    }
-+    if (!sync_ok && cwainspan->sync) {
-+	if (debug > 2)
-+	    printk(KERN_INFO "cwain: disabling D channel fifos\n");
-+	cwain_outb(cwainspan,cwain_R_FIFO,0x1F << 1);
-+	cwain_waitbusy(cwainspan);
-+	cwain_outb(cwainspan,cwain_A_CON_HDLC,0x1);
-+	cwain_outb(cwainspan,cwain_A_IRQ_MSK,0x0);
-+	cwain_outb(cwainspan,cwain_R_FIFO,(0x1F << 1) | 1);
-+	cwain_waitbusy(cwainspan);
-+	cwain_outb(cwainspan,cwain_A_CON_HDLC,0x1);
-+	cwain_outb(cwainspan,cwain_A_IRQ_MSK,0x0);
-+	cwainspan->span.alarms = ZT_ALARM_RED;
-+	zt_alarm_notify(&cwainspan->span);
-+    }
++	    cwain_outb(cwainspan,cwain_R_FIFO,(0x1F << 1) | 1);
++	    cwain_waitbusy(cwainspan);
++	    cwain_outb(cwainspan,cwain_A_CON_HDLC,0xd);
++	    cwain_outb(cwainspan,cwain_A_IRQ_MSK,0x1);
 +
-+    cwainspan->sync = sync_ok;
-+    if (sync_ok) {
-+	switch (cwainspan->type) {
-+	    case 0xb553:
-+		sprintf(cwainspan->span.desc,"Junghanns.NET singleE1 PCI ISDN Card %d (cardID %d) SYNCED",cwainspan->cardno,cwainspan->cardID);
-+		break;
-+    	    case 0xb554:
-+		sprintf(cwainspan->span.desc,"Junghanns.NET doubleE1 PCI ISDN Card %d (cardID %d) (1 E1 port) SYNCED",cwainspan->cardno,cwainspan->cardID);
-+	        break;
++	    cwainspan->span.crc4count = 0;
++    	    cwainspan->span.bpvcount = 0;
++	    cwainspan->span.ebitcount = 0;
++    	    cwainspan->span.fascount = 0;
++	    cwainspan->span.alarms = ZT_ALARM_NONE;
++	    zt_alarm_notify(&cwainspan->span);
++	    res = 1;
 +	}
-+    } else {
-+	switch (cwainspan->type) {
-+	    case 0xb553:
-+		sprintf(cwainspan->span.desc,"Junghanns.NET singleE1 PCI ISDN Card %d (cardID %d) NO SYNC (sync_sta = %#x)",cwainspan->cardno,cwainspan->cardID, sync_sta);
-+		break;
-+    	    case 0xb554:
-+		sprintf(cwainspan->span.desc,"Junghanns.NET doubleE1 PCI ISDN Card %d (cardID %d) (1 E1 port) NO SYNC (sync_sta = %#x)",cwainspan->cardno,cwainspan->cardID, sync_sta);
-+	        break;
++	if (!sync_ok && cwainspan->sync) {
++	    if (debug > 2)
++		printk(KERN_INFO "cwain: disabling D channel fifos\n");
++	    cwain_outb(cwainspan,cwain_R_FIFO,0x1F << 1);
++	    cwain_waitbusy(cwainspan);
++	    cwain_outb(cwainspan,cwain_A_CON_HDLC,0x1);
++	    cwain_outb(cwainspan,cwain_A_IRQ_MSK,0x0);
++	    cwain_outb(cwainspan,cwain_R_FIFO,(0x1F << 1) | 1);
++	    cwain_waitbusy(cwainspan);
++	    cwain_outb(cwainspan,cwain_A_CON_HDLC,0x1);
++	    cwain_outb(cwainspan,cwain_A_IRQ_MSK,0x0);
++	    cwainspan->span.alarms = ZT_ALARM_RED;
++	    zt_alarm_notify(&cwainspan->span);
++	    res = 1;
 +	}
++
++	cwainspan->sync = sync_ok;
++	if (sync_ok) {
++	    switch (cwainspan->type) {
++		case 0xb553:
++		    sprintf(cwainspan->span.desc,"Junghanns.NET singleE1 PCI ISDN Card %d (cardID %d) SYNCED",cwainspan->cardno,cwainspan->cardID);
++	    	    break;
++    		case 0xb554:
++		    sprintf(cwainspan->span.desc,"Junghanns.NET doubleE1 PCI ISDN Card %d (cardID %d) (1 E1 port) SYNCED",cwainspan->cardno,cwainspan->cardID);
++		    break;
++	    }
++	} else {
++	    switch (cwainspan->type) {
++		case 0xb553:
++		    sprintf(cwainspan->span.desc,"Junghanns.NET singleE1 PCI ISDN Card %d (cardID %d) NO SYNC (sync_sta = %#x)",cwainspan->cardno,cwainspan->cardID, sync_sta);
++		    break;
++    		case 0xb554:
++		    sprintf(cwainspan->span.desc,"Junghanns.NET doubleE1 PCI ISDN Card %d (cardID %d) (1 E1 port) NO SYNC (sync_sta = %#x)",cwainspan->cardno,cwainspan->cardID, sync_sta);
++	    	    break;
++	    }
++	}
++	cwain_doLEDs(cwainspan);
 +    }
-+    cwain_doLEDs(cwainspan);
++    return res;
 +}
-+}
 +
 +int cwain_isr_fifo(struct zt_cwain *cwainspan, unsigned char status) {
 +    unsigned char irq_foview,fi;
@@ -793,7 +853,7 @@
 +	    fi = cwain_inb(cwainspan,cwain_R_IRQ_FIFO_BL7);
 +	    if (fi & 0x80) {
 +		if (debug > 2)
-+		    printk(KERN_CRIT "cwain: fifo 31 RX irq for D channel\n");
++		    printk(KERN_CRIT "cwain: fifo 31 RX irq for D channel cardID %d\n", cwainspan->cardID);
 +		cwainspan->drx += 1;		
 +	    }
 +	}
@@ -803,13 +863,36 @@
 +}
 +
 +#ifdef LINUX26
++static irqreturn_t cwain_dummy_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
++#else
++static void cwain_dummy_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
++#endif
++    struct zt_cwain_card *cwaintmp = dev_id;
++    if (!cwaintmp) {
++#ifdef LINUX26
++		return IRQ_NONE;
++#else
++		return;
++#endif		
++    }
++    if (debug > 3)
++	printk(KERN_INFO "cwain: dummy irq\n");
++#ifdef LINUX26
++	return IRQ_RETVAL(1);
++#endif		
++}
++
++
++#ifdef LINUX26
 +static irqreturn_t cwain_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
 +#else
 +static void cwain_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
 +#endif
 +    struct zt_cwain_card *cwaintmp = dev_id;
-+    unsigned char status, status2, status_tmp, irq_misc, irq_misc2;
++    unsigned char status, status2, status_tmp, irq_misc, irq_misc2 = 0;
++#ifndef RELAXED_LOCKING    
 +    unsigned long flags;
++#endif
 +    int i = 0;
 +    int l1event = 0;
 +    
@@ -821,8 +904,11 @@
 +#endif		
 +    }
 +    
-+    
++#ifdef RELAXED_LOCKING    
++    spin_lock(&(cwaintmp->lock));
++#else
 +    spin_lock_irqsave(&(cwaintmp->lock),flags);
++#endif
 +    status = cwain_inb(cwaintmp->span[0],cwain_R_STATUS);
 +
 +    status2 = 0;
@@ -839,7 +925,11 @@
 +
 +    if (!(status & 0x80) && !(status & 0x40)) {
 +	// it's not us!
++#ifdef RELAXED_LOCKING    
++	spin_unlock(&(cwaintmp->lock));
++#else 
 +	spin_unlock_irqrestore(&(cwaintmp->lock),flags);
++#endif
 +#ifdef LINUX26
 +		return IRQ_NONE;
 +#else
@@ -853,10 +943,15 @@
 +	if (irq_misc & 0x2)  {
 +	    /* cwain timer */
 +	    cwaintmp->ticks++;
++	    if (cwaintmp->ticks == 1) {
++		for (i=0;i<cwaintmp->spans;i++) {
++		    cwain_audio_run(cwaintmp->span[i]);
++		}
++	    }
 +	    for (i=0;i<cwaintmp->spans;i++) {
-+		cwain_isr_run(cwaintmp->span[i]);
++		cwain_isr_run(cwaintmp->span[i], cwaintmp->ticks);
 +	    }
-+	    if (cwaintmp->ticks == 500) {
++	    if (cwaintmp->ticks == (cwain_FRAME_SIZE / 8)) {
 +		cwaintmp->ticks = 0;
 +	    }
 +	} 
@@ -867,9 +962,12 @@
 +	    l1event++;
 +	}
 +	if (irq_misc & 0x10) {
-+    	    for (i=0;i<cwaintmp->spans;i++) {
-+    	        cwain_isr_sync(cwaintmp->span[i]);
-+    	    }
++    	    if (l1event == 0) {
++		/* just in case we missed it */
++		for (i=0;i<cwaintmp->spans;i++) {
++    	    	    l1event += cwain_isr_sync(cwaintmp->span[i]);
++    		}
++	    }
 +	}
 +    }
 +
@@ -888,15 +986,19 @@
 +
 +    if (l1event > 0) {
 +//	printk(KERN_INFO "cwain: l1event %d\n", l1event);
++    	for (i=0;i<cwaintmp->spans;i++) {
++    	    cwain_isr_sync(cwaintmp->span[i]);
++    	}
 +        if (cwaintmp->spans == 2) {
 +    	    cwain_check_timing(cwaintmp);
 +        }
-+    	for (i=0;i<cwaintmp->spans;i++) {
-+    	    cwain_isr_sync(cwaintmp->span[i]);
-+    	}
 +    }
 +
++#ifdef RELAXED_LOCKING    
++    spin_unlock(&(cwaintmp->lock));
++#else
 +    spin_unlock_irqrestore(&(cwaintmp->lock),flags);
++#endif
 +#ifdef LINUX26
 +	return IRQ_RETVAL(1);
 +#endif		
@@ -1106,13 +1208,12 @@
 +    /* setup sync mode */    
 +    if (cwaincard->syncs[span->offset] > 0) {
 +	cwain_outb(cwaintmp,cwain_R_SYNC_CTRL,0x2);
-+	cwain_outb(cwaintmp,cwain_R_SYNC_OUT,0x1);    
++	cwain_outb(cwaintmp,cwain_R_SYNC_OUT,0xe0);
 +	/* layer 1, here we go! */
 +	cwain_outb(cwaintmp,cwain_R_E1_WR_STA,0x00);
 +    } else {
-+//	cwain_outb(cwaintmp,cwain_R_SYNC_CTRL,0x5);
-+	cwain_outb(cwaintmp,cwain_R_SYNC_CTRL,0x7);
-+	cwain_outb(cwaintmp,cwain_R_SYNC_OUT,0x0);
++	cwain_outb(cwaintmp,cwain_R_SYNC_CTRL,0x5);
++	cwain_outb(cwaintmp,cwain_R_SYNC_OUT,0xe0);
 +	/* layer 1, up! */
 +	cwain_outb(cwaintmp,cwain_R_E1_WR_STA,0x11);
 +    }
@@ -1121,9 +1222,12 @@
 +    cwaintmp->sync_sta = 0;
 +    
 +    /* enable irqs */
-+    cwain_outb(cwaintmp,cwain_R_IRQ_CTRL, 8 | 1); 
++    if (!span->offset) {
++	cwain_outb(cwaintmp,cwain_R_IRQ_CTRL, 8 | 1); 
++    } else {
++	cwain_outb(cwaintmp,cwain_R_IRQ_CTRL, 0x1); 
++    }
 +    spin_unlock_irqrestore(&cwaintmp->lock,flags);
-+
 +    return 0;
 +}
 +
@@ -1270,6 +1374,10 @@
 +    	    printk(KERN_WARNING "cwain: unable to register irq\n");
 +	    return -1;
 +	}
++	if (request_irq(cwaintmp->span[1]->irq, cwain_dummy_interrupt, SA_INTERRUPT | SA_SHIRQ, "cwaindummy", cwaintmp)) {
++    	    printk(KERN_WARNING "cwain: unable to register irq\n");
++	    return -1;
++	}
 +    } else {
 +	if (request_irq(cwaintmp->irq, cwain_interrupt, SA_INTERRUPT | SA_SHIRQ, "cwain", cwaintmp)) {
 +    	    printk(KERN_WARNING "cwain: unable to register irq\n");
@@ -1290,13 +1398,14 @@
 +    cwain_outb(cwaintmp->span[0],cwain_R_TI_WD, 0x2);
 +
 +    if (cwaintmp->spans == 2) {
-+	cwain_outb(cwaintmp->span[1],cwain_R_IRQMSK_MISC, 0x1); 
++//	cwain_outb(cwaintmp->span[1],cwain_R_IRQMSK_MISC, 0x1); 
++	cwain_outb(cwaintmp->span[1],cwain_R_IRQMSK_MISC, 0x0); 
 +    }
 +    /* enable timer interrupts */
 +    cwain_outb(cwaintmp->span[0],cwain_R_IRQMSK_MISC, 0x13); 
 +
 +    /* Finally enable IRQ output */
-+    cwain_outb(cwaintmp->span[0],cwain_R_IRQ_CTRL, 0x8 | 0x1); 
++//    cwain_outb(cwaintmp->span[0],cwain_R_IRQ_CTRL, 0x8 | 0x1); 
 +
 +    spin_unlock_irqrestore(&(cwaintmp->lock),flags);
 +    return 0;
@@ -1333,8 +1442,8 @@
 +	cwaintmp->pcidevfn = tmp->devfn; 
 +
 +
-+	cwaintmp->pci_io = (char *) tmp->resource[1].start;
-+	if (!cwaintmp->pci_io) {
++	cwaintmp->pci_io_phys = (char *) tmp->resource[1].start;
++	if (!cwaintmp->pci_io_phys) {
 +	    printk(KERN_WARNING "cwain: no iomem!\n");
 +	    pci_disable_device(tmp);
 +	    multi_cwain = NULL;
@@ -1348,12 +1457,34 @@
 +	    return -EIO;
 +	}
 +
++	cwaintmp->ioport = tmp->resource[0].start;
++	if (!cwaintmp->ioport) {
++	    printk(KERN_WARNING "cwain: no ioport!\n");
++	    pci_disable_device(tmp);
++	    multi_cwain = NULL;
++	    return -EIO;
++	}
++	if (!request_region(cwaintmp->ioport, 8, "cwain")) {
++	    printk(KERN_WARNING "cwain: couldnt request io range!\n");
++	    pci_disable_device(tmp);
++	    multi_cwain = NULL;
++	    return -EIO;
++	}
++
++	if (!request_mem_region((unsigned long) cwaintmp->pci_io_phys, 256, "cwain")) {
++	    printk(KERN_WARNING "cwain: couldnt request io mem range!\n");
++	    release_region(cwaintmp->ioport, 8);
++	    pci_disable_device(tmp);
++	    multi_cwain = NULL;
++	    return -EIO;
++	}
++
 +        cwaintmp->irq = tmp->irq;
 +
-+	cwaintmp->pci_io = ioremap((ulong) cwaintmp->pci_io, 256);
++	cwaintmp->pci_io = ioremap((ulong) cwaintmp->pci_io_phys, 256);
 +			       
 +	/* enable memio */
-+	pci_write_config_word(cwaintmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY);	
++	pci_write_config_word(cwaintmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_IO);	
 +
 +	/* disable interrupts */
 +	cwain_outb(cwaintmp,cwain_R_IRQ_CTRL, 0); 
@@ -1495,26 +1626,35 @@
 +}
 +#endif
 +
++#ifdef LINUX26
++module_param(ports, int, 0600);
++module_param(debug, int, 0600);
++#else
 +MODULE_PARM(ports,"i");
 +MODULE_PARM(debug,"i");
++#endif
++
 +MODULE_DESCRIPTION("cwain zaptel driver");
 +MODULE_AUTHOR("Klaus-Peter Junghanns <kpj at junghanns.net>");
 +#ifdef MODULE_LICENSE
 +MODULE_LICENSE("GPL");
 +#endif	
-diff -urNad zaptel-1.2.3/cwain/cwain.h /tmp/dpep.Uu0Ujg/zaptel-1.2.3/cwain/cwain.h
---- zaptel-1.2.3/cwain/cwain.h	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/cwain/cwain.h	2005-09-26 09:59:05.000000000 +0300
-@@ -0,0 +1,238 @@
+diff -urNad zaptel-1.2.5/cwain/cwain.h /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/cwain.h
+--- zaptel-1.2.5/cwain/cwain.h	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/cwain.h	2006-03-31 13:58:41.000000000 +0300
+@@ -0,0 +1,245 @@
 +#define cwain_FIFO_SIZE	128
 +#define cwain_DFIFO_SIZE	4096
-+#define cwain_FIFO_HW	13
++#define cwain_FRAME_SIZE 16	/* has to be %4==0 */
++#define cwain_FIFO_HW cwain_FRAME_SIZE * 2 + ZT_CHUNKSIZE
 +
 +typedef struct zt_cwain {
 +    /* pci resources */
 +    unsigned int irq;
 +    unsigned int iomem;
++    unsigned long ioport;
 +    unsigned char *pci_io;
++    void *pci_io_phys;
 +    unsigned int pcibus;
 +    unsigned int pcidevfn;
 +    struct pci_dev *pcidev;
@@ -1539,6 +1679,10 @@
 +    /* B chan buffers */
 +    unsigned char rxbuf[30][ZT_CHUNKSIZE];
 +    unsigned char txbuf[30][ZT_CHUNKSIZE];
++
++    /* buffers */
++    unsigned char frxbuf[30][cwain_FRAME_SIZE];
++    unsigned char ftxbuf[30][cwain_FRAME_SIZE];
 +    
 +    /* number of RXed dchan frames */
 +    unsigned char drx;
@@ -1744,9 +1888,9 @@
 +#define CLKDEL_TE	0xe	/* CLKDEL in TE mode */
 +#define CLKDEL_NT	0xc	/* CLKDEL in NT mode */
 +
-diff -urNad zaptel-1.2.3/cwain/LICENSE /tmp/dpep.Uu0Ujg/zaptel-1.2.3/cwain/LICENSE
---- zaptel-1.2.3/cwain/LICENSE	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/cwain/LICENSE	2005-09-26 09:59:05.000000000 +0300
+diff -urNad zaptel-1.2.5/cwain/LICENSE /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/LICENSE
+--- zaptel-1.2.5/cwain/LICENSE	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/LICENSE	2005-09-26 09:59:05.000000000 +0300
 @@ -0,0 +1,341 @@
 +
 +		    GNU GENERAL PUBLIC LICENSE
@@ -2089,21 +2233,21 @@
 +consider it more useful to permit linking proprietary applications with the
 +library.  If this is what you want to do, use the GNU Library General
 +Public License instead of this License.
-diff -urNad zaptel-1.2.3/cwain/Makefile /tmp/dpep.Uu0Ujg/zaptel-1.2.3/cwain/Makefile
---- zaptel-1.2.3/cwain/Makefile	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/cwain/Makefile	2006-02-02 18:48:02.000000000 +0200
+diff -urNad zaptel-1.2.5/cwain/Makefile /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/Makefile
+--- zaptel-1.2.5/cwain/Makefile	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/Makefile	2006-02-10 12:28:37.000000000 +0200
 @@ -0,0 +1,90 @@
 +KINCLUDES = /usr/src/linux/include
 +BRISTUFFBASE = $(shell dirname `pwd`)
 +
-+ZAP = $(shell [ -f $(BRISTUFFBASE)/zaptel-1.2.3/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel-1.2.3")
++ZAP = $(shell [ -f $(BRISTUFFBASE)/zaptel/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel")
 +
 +HOSTCC=gcc
 +
-+CFLAGS+=-I. $(ZAP) -O4 -g -Wall #-DBLINKYBLINK
++CFLAGS+=-I. $(ZAP) -DRELAXED_LOCKING -O4 -g -Wall #-DBLINKYBLINK
 +CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi)
 +
-+KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP)
++KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -DRELAXED_LOCKING -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP) 
 +KFLAGS+=$(shell [ -f $(KINCLUDES)/linux/modversions.h ] && echo "-DMODVERSIONS -include $(KINCLUDES)/linux/modversions.h")
 +KFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-msoft-float -fsigned-char"; fi)
 +
@@ -2183,14 +2327,89 @@
 +
 +unload: 
 +	rmmod cwain zaptel
-diff -urNad zaptel-1.2.3/cwain/TODO /tmp/dpep.Uu0Ujg/zaptel-1.2.3/cwain/TODO
---- zaptel-1.2.3/cwain/TODO	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/cwain/TODO	2005-09-26 09:59:05.000000000 +0300
+diff -urNad zaptel-1.2.5/cwain/TODO /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/TODO
+--- zaptel-1.2.5/cwain/TODO	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/TODO	2005-09-26 09:59:05.000000000 +0300
 @@ -0,0 +1 @@
 +
-diff -urNad zaptel-1.2.3/cwain/zaptel.conf /tmp/dpep.Uu0Ujg/zaptel-1.2.3/cwain/zaptel.conf
---- zaptel-1.2.3/cwain/zaptel.conf	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/cwain/zaptel.conf	2005-10-27 11:26:41.000000000 +0200
+diff -urNad zaptel-1.2.5/cwain/zapata.conf /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/zapata.conf
+--- zaptel-1.2.5/cwain/zapata.conf	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/zapata.conf	2006-04-10 12:56:05.000000000 +0300
+@@ -0,0 +1,32 @@
++;
++; Zapata telephony interface
++;
++; Configuration file
++
++[channels]
++;
++; Default language
++;
++;language=en
++;
++; Default context
++;
++;
++switchtype = euroisdn
++
++signalling = pri_cpe
++
++pridialplan = local
++prilocaldialplan = dynamic
++nationalprefix = 0
++internationalprefix = 00
++
++priindication = passthrough
++
++echocancel = yes
++
++context=demo
++
++group = 1
++channel => 1-15,17-31
++
+diff -urNad zaptel-1.2.5/cwain/zapata.conf.doubleE1 /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/zapata.conf.doubleE1
+--- zaptel-1.2.5/cwain/zapata.conf.doubleE1	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/zapata.conf.doubleE1	2006-04-10 12:56:25.000000000 +0300
+@@ -0,0 +1,35 @@
++;
++; Zapata telephony interface
++;
++; Configuration file
++
++[channels]
++;
++; Default language
++;
++;language=en
++;
++; Default context
++;
++;
++switchtype = euroisdn
++
++signalling = pri_cpe
++
++pridialplan = local
++prilocaldialplan = dynamic
++nationalprefix = 0
++internationalprefix = 00
++
++priindication = passthrough
++
++echocancel = yes
++
++context=demo
++
++group = 1
++channel => 1-15,17-31
++
++group = 2
++channel => 32-46,48-62
++
+diff -urNad zaptel-1.2.5/cwain/zaptel.conf /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/zaptel.conf
+--- zaptel-1.2.5/cwain/zaptel.conf	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/zaptel.conf	2005-10-27 11:26:41.000000000 +0200
 @@ -0,0 +1,11 @@
 +loadzone=nl
 +defaultzone=nl
@@ -2203,9 +2422,27 @@
 +bchan=17-31
 +
 +
-diff -urNad zaptel-1.2.3/qozap/LICENSE /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/LICENSE
---- zaptel-1.2.3/qozap/LICENSE	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/LICENSE	2005-06-13 10:03:36.000000000 +0300
+diff -urNad zaptel-1.2.5/cwain/zaptel.conf.doubleE1 /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/zaptel.conf.doubleE1
+--- zaptel-1.2.5/cwain/zaptel.conf.doubleE1	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/cwain/zaptel.conf.doubleE1	2006-04-05 23:16:12.000000000 +0300
+@@ -0,0 +1,14 @@
++loadzone=nl
++defaultzone=nl
++span=1,1,3,ccs,hdb3,crc4
++span=2,2,3,ccs,hdb3,crc4
++
++alaw=1-62
++
++bchan=1-15
++dchan=16
++bchan=17-31
++
++bchan=32-46
++dchan=47
++bchan=48-62
+diff -urNad zaptel-1.2.5/qozap/LICENSE /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/LICENSE
+--- zaptel-1.2.5/qozap/LICENSE	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/LICENSE	2006-02-22 20:41:09.000000000 +0200
 @@ -0,0 +1,341 @@
 +
 +		    GNU GENERAL PUBLIC LICENSE
@@ -2548,21 +2785,21 @@
 +consider it more useful to permit linking proprietary applications with the
 +library.  If this is what you want to do, use the GNU Library General
 +Public License instead of this License.
-diff -urNad zaptel-1.2.3/qozap/Makefile /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/Makefile
---- zaptel-1.2.3/qozap/Makefile	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/Makefile	2006-02-02 18:47:49.000000000 +0200
+diff -urNad zaptel-1.2.5/qozap/Makefile /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/Makefile
+--- zaptel-1.2.5/qozap/Makefile	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/Makefile	2006-02-22 20:41:09.000000000 +0200
 @@ -0,0 +1,91 @@
 +KINCLUDES = /usr/src/linux/include
 +BRISTUFFBASE = $(shell dirname `pwd`)
 +
-+ZAP = $(shell [ -f $(BRISTUFFBASE)/zaptel-1.2.3/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel-1.2.3")
++ZAP = $(shell [ -f $(BRISTUFFBASE)/zaptel/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel")
 +
 +HOSTCC=gcc
 +
-+CFLAGS+=-I. $(ZAP) -O4 -g -Wall -DBUILDING_TONEZONE  #-DTONEZONE_DRIVER
++CFLAGS+=-I. $(ZAP) -DRELAXED_LOCKING -O4 -g -Wall -DBUILDING_TONEZONE  #-DTONEZONE_DRIVER
 +CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi)
 +
-+KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP)
++KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -DRELAXED_LOCKING -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP)
 +KFLAGS+=$(shell [ -f $(KINCLUDES)/linux/modversions.h ] && echo "-DMODVERSIONS -include $(KINCLUDES)/linux/modversions.h")
 +KFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-msoft-float -fsigned-char"; fi)
 +
@@ -2643,10 +2880,10 @@
 +
 +installlinux24:
 +	install -D -m 644 qozap.o $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/qozap.o
-diff -urNad zaptel-1.2.3/qozap/qozap.c /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/qozap.c
---- zaptel-1.2.3/qozap/qozap.c	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/qozap.c	2005-08-01 09:58:20.000000000 +0300
-@@ -0,0 +1,1493 @@
+diff -urNad zaptel-1.2.5/qozap/qozap.c /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/qozap.c
+--- zaptel-1.2.5/qozap/qozap.c	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/qozap.c	2006-04-25 16:37:39.000000000 +0300
+@@ -0,0 +1,1545 @@
 +/*
 + * qozap.c - Zaptel driver for the quadBRI PCI ISDN card
 + * and the octoBRI PCI ISDN card!
@@ -2671,6 +2908,7 @@
 +
 +static int doubleclock=0;
 +static int ports=-1; /* autodetect */
++static int pcmslave=0;
 +static int bloop=0;
 +static int debug=0;
 +static struct qoz_card *qoz_dev_list = NULL;
@@ -2725,7 +2963,6 @@
 +    qoz_outb(qoztmp,qoz_R_IRQMSK_MISC, 0); 
 +    qoz_outb(qoztmp,qoz_R_SCI_MSK, 0); 
 +
-+    free_irq(qoztmp->irq,qoztmp);
 +
 +    // softreset
 +    qoz_outb(qoztmp,qoz_R_CIRM,0x8);
@@ -2736,8 +2973,9 @@
 +    qoz_outb(qoztmp,qoz_R_SCI_MSK, 0); 
 +    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 0); 
 +
-+    release_region(qoztmp->ioport, 7);
++    release_region(qoztmp->ioport, 8);
 +    iounmap((void *) qoztmp->pci_io);
++    release_mem_region((unsigned long) qoztmp->pci_io_phys, 256);
 +
 +    qoztmp->pci_io = NULL;
 +    qoztmp->ioport = 0;
@@ -2747,6 +2985,7 @@
 +    }
 +    pci_write_config_word(qoztmp->pcidev, PCI_COMMAND, 0);	
 +    
++    free_irq(qoztmp->irq,qoztmp);
 +    spin_unlock_irqrestore(&qoztmp->lock,flags);
 +
 +    if (qoztmp->ztdev != NULL) {
@@ -2863,8 +3102,13 @@
 +    /* set up the timer */
 +    qoz_outb(qoztmp,qoz_R_TI_WD, 0x2); 
 +    qoz_outb(qoztmp,qoz_R_IRQMSK_MISC, 0x2); 
-+    qoz_outb(qoztmp,qoz_R_PCM_MD0, 0x1);
 +
++    if (pcmslave) {
++	qoz_outb(qoztmp,qoz_R_PCM_MD0, 0x0);
++    } else {
++	qoz_outb(qoztmp,qoz_R_PCM_MD0, 0x1);
++    }
++
 +    /* all state changes */
 +    qoz_outb(qoztmp,qoz_R_SCI_MSK, 0xff); 
 +
@@ -2903,7 +3147,7 @@
 +    qoztmp->leds[7] = 0x0;
 +
 +    /* Finally enable IRQ output */
-+    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 0x8 | 0x1); 
++//    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 0x8 | 0x1); 
 +    if (qoztmp->type == 0xb552) {
 +	qoztmp->stports = 8;
 +    } else {
@@ -3130,7 +3374,7 @@
 +    		data = qoz_inb(qoztmp,qoz_A_FIFO_DATA0);
 +	    }
 +	    qoztmp->clicks++;
-+	    if ((qoztmp->clicks > 1) || (debug == 4)) {
++	    if ((qoztmp->clicks > 10) && (debug > 0)) {
 +		printk(KERN_CRIT "qozap: dropped audio card %d cardid %d bytes %d z1 %d z2 %d\n", qoztmp->cardno, qoztmp->cardID, mumbojumbo, z1, z2);
 +		qoztmp->clicks = 0;
 +	    }
@@ -3255,7 +3499,9 @@
 +#endif
 +    struct qoz_card *qoztmp = dev_id;
 +    struct zt_qoz *ztqoz = qoztmp->ztdev;
++#ifndef RELAXED_LOCKING
 +    unsigned long flags;
++#endif
 +    unsigned char irq_misc,irq_sci,status,l1state,irq_foview,fi;
 +    int st=0,i=0,offset=0;
 +    int j=0;
@@ -3276,15 +3522,31 @@
 +		return;
 +#endif		
 +    }
++    if (qoztmp->dead) {
++#ifdef LINUX26
++	return IRQ_RETVAL(1);
++#else
++	return;
++#endif		
++    }
++
 +    
-+    spin_lock_irqsave(&(qoztmp->lock),flags);
++#ifdef RELAXED_LOCKING
++    spin_lock(&(qoztmp->lock));
++#else
++    spin_lock_irqsave(&(qoztmp->lock), flags);
++#endif
 +    status = qoz_inb(qoztmp,qoz_R_STATUS);
 +    irq_sci = qoz_inb(qoztmp,qoz_R_SCI);
 +
 +    if (!(status & 0x80) && !(status & 0x40) && (irq_sci == 0)) {
 +//	printk(KERN_CRIT "qozap: status %#x\n", status);
 +	// it's not us!
-+	spin_unlock_irqrestore(&(qoztmp->lock),flags);
++#ifdef RELAXED_LOCKING
++	spin_unlock(&(qoztmp->lock));
++#else
++	spin_unlock_irqrestore(&(qoztmp->lock), flags);
++#endif
 +#ifdef LINUX26
 +		return IRQ_NONE;
 +#else
@@ -3493,7 +3755,11 @@
 +	}
 +    }
 +    
-+    spin_unlock_irqrestore(&(qoztmp->lock),flags);
++#ifdef RELAXED_LOCKING
++    spin_unlock(&(qoztmp->lock));
++#else
++    spin_unlock_irqrestore(&(qoztmp->lock), flags);
++#endif
 +#ifdef LINUX26
 +	return IRQ_RETVAL(1);
 +#endif		
@@ -3668,10 +3934,9 @@
 +    } else {
 +	qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x0); 
 +    }
-+    /* enable irqs */
-+    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 8 | 1); 
 +    spin_unlock_irqrestore(&qoztmp->lock,flags);
 +
++
 +    qoz_outb(qoztmp,qoz_R_ST_SEL,span->offset);
 +    if (qoztmp->st[span->offset].nt_mode == 1) {
 +	qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x60 | 0x80); // ACT, G2->G3 EN
@@ -3679,6 +3944,8 @@
 +	qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x60); // start Activation
 +    }
 +
++    /* enable irqs */
++    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 8 | 1); 
 +    return 0;
 +}
 +
@@ -3876,8 +4143,8 @@
 +	    qoztmp->irq = tmp->irq;
 +	}
 +
-+	qoztmp->pci_io = (char *) tmp->resource[1].start;
-+	if (!qoztmp->pci_io) {
++	qoztmp->pci_io_phys = (char *) tmp->resource[1].start;
++	if (!qoztmp->pci_io_phys) {
 +	    printk(KERN_WARNING "qozap: no iomem!\n");
 +	    pci_disable_device(tmp);
 +	    multi_qoz = NULL;
@@ -3891,12 +4158,19 @@
 +	    multi_qoz = NULL;
 +	    return -EIO;
 +	}
-+	if (!request_region(qoztmp->ioport, 7, "qozap")) {
++	if (!request_region(qoztmp->ioport, 8, "qozap")) {
 +	    printk(KERN_WARNING "qozap: couldnt request io range!\n");
 +	    pci_disable_device(tmp);
 +	    multi_qoz = NULL;
 +	    return -EIO;
 +	}
++	if (!request_mem_region((unsigned long) qoztmp->pci_io_phys, 256, "qozap")) {
++	    printk(KERN_WARNING "qozap: couldnt request io mem range!\n");
++	    release_region(qoztmp->ioport, 8);
++	    pci_disable_device(tmp);
++	    multi_qoz = NULL;
++	    return -EIO;
++	}
 +	
 +	if (request_irq(qoztmp->irq, qoz_interrupt, SA_INTERRUPT | SA_SHIRQ, "qozap", qoztmp)) {
 +	    printk(KERN_WARNING "qozap: unable to register irq\n");
@@ -3906,7 +4180,7 @@
 +	    return -EIO;
 +	}
 +
-+	qoztmp->pci_io = ioremap((ulong) qoztmp->pci_io, 256);
++	qoztmp->pci_io = ioremap((ulong) qoztmp->pci_io_phys, 256);
 +	
 +	pci_write_config_word(qoztmp->pcidev, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
 +
@@ -4006,6 +4280,8 @@
 +		       qoztmp->irq, HZ);
 +	        break;
 +		default:
++		    printk(KERN_INFO
++		       "qozap: wtf\n");
 +		    if (qoztmp->pcidev != NULL) {
 +    			pci_disable_device(qoztmp->pcidev);
 +		    }
@@ -4098,13 +4374,14 @@
 +int init_module(void) {
 +    multi_qoz = NULL;
 +    qoz_findCards(PCI_DEVICE_ID_CCD_M4);
++    multi_qoz = NULL;
 +    qoz_findCards(PCI_DEVICE_ID_CCD_M);
 +    qoz_sortCards();
 +    qoz_zapCards();
 +    if (qoz_dev_count == 0) {
 +	printk(KERN_INFO "qozap: no multiBRI cards found.\n");
 +    } else {
-+	printk(KERN_INFO "qozap: %d multiBRI card(s) in this box, %d BRI ports total, bloop %d.\n",qoz_dev_count, totalBRIs, bloop);
++	printk(KERN_INFO "qozap: %d multiBRI card(s) in this box, %d BRI ports total, bloop %d, pcmslave %d.\n",qoz_dev_count, totalBRIs, bloop, pcmslave);
 +    }
 +    return 0;
 +}
@@ -4114,6 +4391,7 @@
 +    int i=0;
 +    tmplist = qoz_dev_list;
 +    while (tmplist != NULL) {
++	tmplist->dead = 1;
 +	qoz_undoWD(tmplist);
 +	qoz_shutdownCard(tmplist);
 +	tmplist = tmplist->next;
@@ -4131,19 +4409,30 @@
 +}
 +#endif
 +
++#ifdef LINUX26
++module_param(doubleclock, int, 0600);
++module_param(ports, int, 0600);
++module_param(pcmslave, int, 0600);
++module_param(bloop, int, 0600);
++module_param(debug, int, 0600);
++#else
 +MODULE_PARM(doubleclock,"i");
 +MODULE_PARM(ports,"i");
++MODULE_PARM(pcmslave,"i");
 +MODULE_PARM(bloop,"i");
 +MODULE_PARM(debug,"i");
++#endif
++
++
 +MODULE_DESCRIPTION("quad/octo BRI zaptel driver");
 +MODULE_AUTHOR("Klaus-Peter Junghanns <kpj at junghanns.net>");
 +#ifdef MODULE_LICENSE
 +MODULE_LICENSE("GPL");
 +#endif	
-diff -urNad zaptel-1.2.3/qozap/qozap.h /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/qozap.h
---- zaptel-1.2.3/qozap/qozap.h	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/qozap.h	2005-06-13 11:56:43.000000000 +0300
-@@ -0,0 +1,237 @@
+diff -urNad zaptel-1.2.5/qozap/qozap.h /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/qozap.h
+--- zaptel-1.2.5/qozap/qozap.h	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/qozap.h	2006-02-22 20:41:09.000000000 +0200
+@@ -0,0 +1,239 @@
 +#define qoz_SPANS 8	
 +#define qoz_FIFO_SIZE	128
 +#define qoz_DFIFO_SIZE4	2048
@@ -4175,11 +4464,13 @@
 +typedef struct qoz_card {
 +    spinlock_t lock;
 +    int cardID;
++    unsigned char dead;
 +    unsigned char leds[8];
 +    unsigned char cardno;
 +    unsigned int irq;
 +    unsigned int iomem;
 +    unsigned char *pci_io;
++    void *pci_io_phys;
 +    unsigned long ioport;
 +    struct qoz_span st[qoz_SPANS];
 +    unsigned int pcibus;
@@ -4381,9 +4672,9 @@
 +#define qoz_T4		1
 +
 +
-diff -urNad zaptel-1.2.3/qozap/TODO /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/TODO
---- zaptel-1.2.3/qozap/TODO	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/TODO	2005-06-13 10:03:36.000000000 +0300
+diff -urNad zaptel-1.2.5/qozap/TODO /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/TODO
+--- zaptel-1.2.5/qozap/TODO	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/TODO	2006-02-22 20:41:09.000000000 +0200
 @@ -0,0 +1,9 @@
 +- native-native bridging
 +- onchip dtmf
@@ -4394,10 +4685,10 @@
 +
 +t4 (500ms) layer 1 down/up
 +
-diff -urNad zaptel-1.2.3/qozap/zapata.conf /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/zapata.conf
---- zaptel-1.2.3/qozap/zapata.conf	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/zapata.conf	2005-06-13 10:03:36.000000000 +0300
-@@ -0,0 +1,49 @@
+diff -urNad zaptel-1.2.5/qozap/zapata.conf /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/zapata.conf
+--- zaptel-1.2.5/qozap/zapata.conf	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/zapata.conf	2006-04-10 12:56:52.000000000 +0300
+@@ -0,0 +1,51 @@
 +;
 +; Zapata telephony interface
 +;
@@ -4424,10 +4715,12 @@
 +;signalling = bri_net
 +
 +pridialplan = local
-+prilocaldialplan = local
++prilocaldialplan = dynamic
 +nationalprefix = 0
 +internationalprefix = 00
 +
++priindication = passthrough
++
 +echocancel = yes
 +
 +context=demo
@@ -4447,10 +4740,10 @@
 +; S/T port 4
 +channel => 10-11
 +
-diff -urNad zaptel-1.2.3/qozap/zapata.conf.octoBRI /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/zapata.conf.octoBRI
---- zaptel-1.2.3/qozap/zapata.conf.octoBRI	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/zapata.conf.octoBRI	2005-06-13 10:03:36.000000000 +0300
-@@ -0,0 +1,65 @@
+diff -urNad zaptel-1.2.5/qozap/zapata.conf.octoBRI /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/zapata.conf.octoBRI
+--- zaptel-1.2.5/qozap/zapata.conf.octoBRI	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/zapata.conf.octoBRI	2006-04-10 12:57:02.000000000 +0300
+@@ -0,0 +1,67 @@
 +;
 +; Zapata telephony interface
 +;
@@ -4477,10 +4770,12 @@
 +;signalling = bri_net
 +
 +pridialplan = local
-+prilocaldialplan = local
++prilocaldialplan = dynamic
 +nationalprefix = 0
 +internationalprefix = 00
 +
++priindication = passthrough
++
 +echocancel = yes
 +
 +context=demo
@@ -4516,9 +4811,9 @@
 +; S/T port 8
 +channel => 22-23
 +
-diff -urNad zaptel-1.2.3/qozap/zaptel.conf /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/zaptel.conf
---- zaptel-1.2.3/qozap/zaptel.conf	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/zaptel.conf	2005-11-20 16:35:32.000000000 +0200
+diff -urNad zaptel-1.2.5/qozap/zaptel.conf /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/zaptel.conf
+--- zaptel-1.2.5/qozap/zaptel.conf	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/zaptel.conf	2006-02-22 20:41:09.000000000 +0200
 @@ -0,0 +1,18 @@
 +loadzone=nl
 +defaultzone=nl
@@ -4538,9 +4833,9 @@
 +bchan=10,11
 +dchan=12
 +
-diff -urNad zaptel-1.2.3/qozap/zaptel.conf.octoBRI /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/zaptel.conf.octoBRI
---- zaptel-1.2.3/qozap/zaptel.conf.octoBRI	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/qozap/zaptel.conf.octoBRI	2005-06-13 10:03:36.000000000 +0300
+diff -urNad zaptel-1.2.5/qozap/zaptel.conf.octoBRI /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/zaptel.conf.octoBRI
+--- zaptel-1.2.5/qozap/zaptel.conf.octoBRI	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/qozap/zaptel.conf.octoBRI	2006-02-22 20:41:09.000000000 +0200
 @@ -0,0 +1,30 @@
 +loadzone=nl
 +defaultzone=nl
@@ -4572,9 +4867,9 @@
 +bchan=22,23
 +dchan=24
 +
-diff -urNad zaptel-1.2.3/zaphfc/LICENSE /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaphfc/LICENSE
---- zaptel-1.2.3/zaphfc/LICENSE	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaphfc/LICENSE	2003-08-19 04:24:43.000000000 +0300
+diff -urNad zaptel-1.2.5/zaphfc/LICENSE /tmp/dpep.7X7WfC/zaptel-1.2.5/zaphfc/LICENSE
+--- zaptel-1.2.5/zaphfc/LICENSE	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/zaphfc/LICENSE	2003-08-19 04:24:43.000000000 +0300
 @@ -0,0 +1,341 @@
 +
 +		    GNU GENERAL PUBLIC LICENSE
@@ -4917,14 +5212,14 @@
 +consider it more useful to permit linking proprietary applications with the
 +library.  If this is what you want to do, use the GNU Library General
 +Public License instead of this License.
-diff -urNad zaptel-1.2.3/zaphfc/Makefile /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaphfc/Makefile
---- zaptel-1.2.3/zaphfc/Makefile	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaphfc/Makefile	2006-02-02 18:48:12.000000000 +0200
+diff -urNad zaptel-1.2.5/zaphfc/Makefile /tmp/dpep.7X7WfC/zaptel-1.2.5/zaphfc/Makefile
+--- zaptel-1.2.5/zaphfc/Makefile	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/zaphfc/Makefile	2006-02-09 11:11:05.000000000 +0200
 @@ -0,0 +1,118 @@
 +KINCLUDES = /usr/src/linux/include
 +BRISTUFFBASE = $(shell dirname `pwd`)
 +
-+ZAP = $(shell [ -f $(BRISTUFFBASE)/zaptel-1.2.3/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel-1.2.3")
++ZAP = $(shell [ -f $(BRISTUFFBASE)/zaptel/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel")
 +RTAI = $(shell [ -f /usr/realtime/include/rtai.h ] && echo "-DRTAITIMING -I/usr/realtime/include")
 +
 +HOSTCC=gcc
@@ -5039,9 +5334,9 @@
 +installlinux24:
 +	install -D -m 644 zaphfc.o $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/zaphfc.o
 +
-diff -urNad zaptel-1.2.3/zaphfc/zapata.conf /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaphfc/zapata.conf
---- zaptel-1.2.3/zaphfc/zapata.conf	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaphfc/zapata.conf	2005-02-26 19:24:32.000000000 +0200
+diff -urNad zaptel-1.2.5/zaphfc/zapata.conf /tmp/dpep.7X7WfC/zaptel-1.2.5/zaphfc/zapata.conf
+--- zaptel-1.2.5/zaphfc/zapata.conf	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/zaphfc/zapata.conf	2005-02-26 19:24:32.000000000 +0200
 @@ -0,0 +1,38 @@
 +;
 +; Zapata telephony interface
@@ -5081,10 +5376,10 @@
 +group = 1
 +context=demo
 +channel => 1-2
-diff -urNad zaptel-1.2.3/zaphfc/zaphfc.c /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaphfc/zaphfc.c
---- zaptel-1.2.3/zaphfc/zaphfc.c	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaphfc/zaphfc.c	2005-11-20 19:58:16.000000000 +0200
-@@ -0,0 +1,1149 @@
+diff -urNad zaptel-1.2.5/zaphfc/zaphfc.c /tmp/dpep.7X7WfC/zaptel-1.2.5/zaphfc/zaphfc.c
+--- zaptel-1.2.5/zaphfc/zaphfc.c	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/zaphfc/zaphfc.c	2006-04-25 16:38:47.000000000 +0300
+@@ -0,0 +1,1155 @@
 +/*
 + * zaphfc.c - Zaptel driver for HFC-S PCI A based ISDN BRI cards
 + *
@@ -6084,7 +6379,7 @@
 +	    return -ENOMEM;
 +	} else {
 +	    memset(hfctmp->fifomem, 0x0, 65536);
-+	    hfctmp->fifos = (((ulong) hfctmp->fifomem) & ~0x7FFF) + 0x8000;
++	    hfctmp->fifos = (void *)(((ulong) hfctmp->fifomem) & ~0x7FFF) + 0x8000;
 +	    pci_write_config_dword(hfctmp->pcidev, 0x80, (u_int) virt_to_bus(hfctmp->fifos));
 +	    hfctmp->pci_io = ioremap((ulong) hfctmp->pci_io, 256);
 +	}
@@ -6108,10 +6403,10 @@
 +	rtai_register_hfc(hfctmp);
 +#endif
 +	printk(KERN_INFO
-+		       "zaphfc: %s %s configured at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n",
++		       "zaphfc: %s %s configured at mem %lx fifo %lx(%#x) IRQ %d HZ %d\n",
 +			vendor_name, card_name,
-+		       (u_int) hfctmp->pci_io,
-+		       (u_int) hfctmp->fifos,
++		       (unsigned long) hfctmp->pci_io,
++		       (unsigned long) hfctmp->fifos,
 +		       (u_int) virt_to_bus(hfctmp->fifos),
 +		       hfctmp->irq, HZ); 
 +	pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY);	// enable memio
@@ -6227,16 +6522,22 @@
 +#endif
 +
 +
++#ifdef LINUX26
++module_param(modes, int, 0600);
++module_param(debug, int, 0600);
++#else
++MODULE_PARM(modes,"i");
++MODULE_PARM(debug,"i");
++#endif
++
 +MODULE_DESCRIPTION("HFC-S PCI A Zaptel Driver");
 +MODULE_AUTHOR("Klaus-Peter Junghanns <kpj at junghanns.net>");
 +#ifdef MODULE_LICENSE
 +MODULE_LICENSE("GPL");
 +#endif	
-+MODULE_PARM(modes,"i");
-+MODULE_PARM(debug,"i");
-diff -urNad zaptel-1.2.3/zaphfc/zaphfc.h /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaphfc/zaphfc.h
---- zaptel-1.2.3/zaphfc/zaphfc.h	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaphfc/zaphfc.h	2005-02-27 00:30:32.000000000 +0200
+diff -urNad zaptel-1.2.5/zaphfc/zaphfc.h /tmp/dpep.7X7WfC/zaptel-1.2.5/zaphfc/zaphfc.h
+--- zaptel-1.2.5/zaphfc/zaphfc.h	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/zaphfc/zaphfc.h	2005-02-27 00:30:32.000000000 +0200
 @@ -0,0 +1,289 @@
 +/*
 + * zaphfc.h - Zaptel driver for HFC-S PCI A based ISDN BRI cards
@@ -6527,9 +6828,9 @@
 +/* tune this */
 +#define hfc_BCHAN_BUFFER	8
 +#define hfc_MAX_CARDS		8
-diff -urNad zaptel-1.2.3/zaphfc/zaptel.conf /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaphfc/zaptel.conf
---- zaptel-1.2.3/zaphfc/zaptel.conf	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaphfc/zaptel.conf	2004-03-24 16:35:12.000000000 +0200
+diff -urNad zaptel-1.2.5/zaphfc/zaptel.conf /tmp/dpep.7X7WfC/zaptel-1.2.5/zaphfc/zaptel.conf
+--- zaptel-1.2.5/zaphfc/zaptel.conf	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/zaphfc/zaptel.conf	2004-03-24 16:35:12.000000000 +0200
 @@ -0,0 +1,8 @@
 +# hfc-s pci a span definition
 +# most of the values should be bogus because we are not really zaptel
@@ -6539,9 +6840,9 @@
 +span=1,1,3,ccs,ami
 +bchan=1-2
 +dchan=3
-diff -urNad zaptel-1.2.3/zaptel.c /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaptel.c
---- zaptel-1.2.3/zaptel.c	2005-12-17 04:04:05.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaptel.c	2006-02-06 13:54:07.000000000 +0200
+diff -urNad zaptel-1.2.5/zaptel.c /tmp/dpep.7X7WfC/zaptel-1.2.5/zaptel.c
+--- zaptel-1.2.5/zaptel.c	2005-12-17 04:04:05.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/zaptel.c	2006-05-08 07:07:41.000000000 +0300
 @@ -4913,11 +4913,40 @@
  					*(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc);
  				}
@@ -6601,6 +6902,15 @@
  #ifdef CONFIG_ZAPATA_NET
  				if (ms->flags & ZT_FLAG_NETDEV)
  					netif_wake_queue(ztchan_to_dev(ms));
+@@ -4972,7 +5012,7 @@
+ 					tasklet_schedule(&ms->ppp_calls);
+ 				}
+ #endif
+-			}
++			} 
+ 		} else if (ms->curtone && !(ms->flags & ZT_FLAG_PSEUDO)) {
+ 			left = ms->curtone->tonesamples - ms->tonep;
+ 			if (left > bytes)
 @@ -5018,6 +5058,10 @@
  				memset(txb, 0xFF, bytes);
  			}
@@ -6646,9 +6956,9 @@
  			} else {
  				/* Not HDLC */
  				memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left);
-diff -urNad zaptel-1.2.3/zaptel.h /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaptel.h
---- zaptel-1.2.3/zaptel.h	2005-12-17 04:04:05.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zaptel.h	2006-02-06 13:54:07.000000000 +0200
+diff -urNad zaptel-1.2.5/zaptel.h /tmp/dpep.7X7WfC/zaptel-1.2.5/zaptel.h
+--- zaptel-1.2.5/zaptel.h	2005-12-17 04:04:05.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/zaptel.h	2006-05-08 07:07:41.000000000 +0300
 @@ -994,6 +994,13 @@
  	int do_ppp_error;
  	struct sk_buff_head ppp_rq;
@@ -6663,6 +6973,15 @@
  	spinlock_t lock;
  	char name[40];		/* Name */
  	/* Specified by zaptel */
+@@ -1068,7 +1075,7 @@
+ 	int		txbufpolicy;			/* Buffer policy */
+ 	int		rxbufpolicy;			/* Buffer policy */
+ 	int		txdisable;				/* Disable transmitter */
+-	int 	rxdisable;				/* Disable receiver */
++	int 		rxdisable;				/* Disable receiver */
+ 	
+ 	
+ 	/* Tone zone stuff */
 @@ -1231,6 +1238,10 @@
  #define ZT_FLAG_T1PPP			(1 << 15)
  #define ZT_FLAG_SIGFREEZE		(1 << 16)	/* Freeze signalling */
@@ -6674,9 +6993,9 @@
  struct zt_span {
  	spinlock_t lock;
  	void *pvt;			/* Private stuff */
-diff -urNad zaptel-1.2.3/zconfig.h /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zconfig.h
---- zaptel-1.2.3/zconfig.h	2005-11-29 20:42:08.000000000 +0200
-+++ /tmp/dpep.Uu0Ujg/zaptel-1.2.3/zconfig.h	2006-02-06 13:54:07.000000000 +0200
+diff -urNad zaptel-1.2.5/zconfig.h /tmp/dpep.7X7WfC/zaptel-1.2.5/zconfig.h
+--- zaptel-1.2.5/zconfig.h	2005-11-29 20:42:08.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/zconfig.h	2006-05-08 07:07:41.000000000 +0300
 @@ -152,4 +152,10 @@
   */
  /* #define FXSFLASH */
@@ -6688,3 +7007,1811 @@
 +#define CONFIG_ZAPATA_BRI_DCHANS
 +
  #endif
+diff -urNad zaptel-1.2.5/ztgsm/LICENSE /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/LICENSE
+--- zaptel-1.2.5/ztgsm/LICENSE	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/LICENSE	2006-04-10 12:22:33.000000000 +0300
+@@ -0,0 +1,341 @@
++
++		    GNU GENERAL PUBLIC LICENSE
++		       Version 2, June 1991
++
++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
++                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ Everyone is permitted to copy and distribute verbatim copies
++ of this license document, but changing it is not allowed.
++
++			    Preamble
++
++  The licenses for most software are designed to take away your
++freedom to share and change it.  By contrast, the GNU General Public
++License is intended to guarantee your freedom to share and change free
++software--to make sure the software is free for all its users.  This
++General Public License applies to most of the Free Software
++Foundation's software and to any other program whose authors commit to
++using it.  (Some other Free Software Foundation software is covered by
++the GNU Library General Public License instead.)  You can apply it to
++your programs, too.
++
++  When we speak of free software, we are referring to freedom, not
++price.  Our General Public Licenses are designed to make sure that you
++have the freedom to distribute copies of free software (and charge for
++this service if you wish), that you receive source code or can get it
++if you want it, that you can change the software or use pieces of it
++in new free programs; and that you know you can do these things.
++
++  To protect your rights, we need to make restrictions that forbid
++anyone to deny you these rights or to ask you to surrender the rights.
++These restrictions translate to certain responsibilities for you if you
++distribute copies of the software, or if you modify it.
++
++  For example, if you distribute copies of such a program, whether
++gratis or for a fee, you must give the recipients all the rights that
++you have.  You must make sure that they, too, receive or can get the
++source code.  And you must show them these terms so they know their
++rights.
++
++  We protect your rights with two steps: (1) copyright the software, and
++(2) offer you this license which gives you legal permission to copy,
++distribute and/or modify the software.
++
++  Also, for each author's protection and ours, we want to make certain
++that everyone understands that there is no warranty for this free
++software.  If the software is modified by someone else and passed on, we
++want its recipients to know that what they have is not the original, so
++that any problems introduced by others will not reflect on the original
++authors' reputations.
++
++  Finally, any free program is threatened constantly by software
++patents.  We wish to avoid the danger that redistributors of a free
++program will individually obtain patent licenses, in effect making the
++program proprietary.  To prevent this, we have made it clear that any
++patent must be licensed for everyone's free use or not licensed at all.
++
++  The precise terms and conditions for copying, distribution and
++modification follow.
++
++		    GNU GENERAL PUBLIC LICENSE
++   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
++
++  0. This License applies to any program or other work which contains
++a notice placed by the copyright holder saying it may be distributed
++under the terms of this General Public License.  The "Program", below,
++refers to any such program or work, and a "work based on the Program"
++means either the Program or any derivative work under copyright law:
++that is to say, a work containing the Program or a portion of it,
++either verbatim or with modifications and/or translated into another
++language.  (Hereinafter, translation is included without limitation in
++the term "modification".)  Each licensee is addressed as "you".
++
++Activities other than copying, distribution and modification are not
++covered by this License; they are outside its scope.  The act of
++running the Program is not restricted, and the output from the Program
++is covered only if its contents constitute a work based on the
++Program (independent of having been made by running the Program).
++Whether that is true depends on what the Program does.
++
++  1. You may copy and distribute verbatim copies of the Program's
++source code as you receive it, in any medium, provided that you
++conspicuously and appropriately publish on each copy an appropriate
++copyright notice and disclaimer of warranty; keep intact all the
++notices that refer to this License and to the absence of any warranty;
++and give any other recipients of the Program a copy of this License
++along with the Program.
++
++You may charge a fee for the physical act of transferring a copy, and
++you may at your option offer warranty protection in exchange for a fee.
++
++  2. You may modify your copy or copies of the Program or any portion
++of it, thus forming a work based on the Program, and copy and
++distribute such modifications or work under the terms of Section 1
++above, provided that you also meet all of these conditions:
++
++    a) You must cause the modified files to carry prominent notices
++    stating that you changed the files and the date of any change.
++
++    b) You must cause any work that you distribute or publish, that in
++    whole or in part contains or is derived from the Program or any
++    part thereof, to be licensed as a whole at no charge to all third
++    parties under the terms of this License.
++
++    c) If the modified program normally reads commands interactively
++    when run, you must cause it, when started running for such
++    interactive use in the most ordinary way, to print or display an
++    announcement including an appropriate copyright notice and a
++    notice that there is no warranty (or else, saying that you provide
++    a warranty) and that users may redistribute the program under
++    these conditions, and telling the user how to view a copy of this
++    License.  (Exception: if the Program itself is interactive but
++    does not normally print such an announcement, your work based on
++    the Program is not required to print an announcement.)
++
++These requirements apply to the modified work as a whole.  If
++identifiable sections of that work are not derived from the Program,
++and can be reasonably considered independent and separate works in
++themselves, then this License, and its terms, do not apply to those
++sections when you distribute them as separate works.  But when you
++distribute the same sections as part of a whole which is a work based
++on the Program, the distribution of the whole must be on the terms of
++this License, whose permissions for other licensees extend to the
++entire whole, and thus to each and every part regardless of who wrote it.
++
++Thus, it is not the intent of this section to claim rights or contest
++your rights to work written entirely by you; rather, the intent is to
++exercise the right to control the distribution of derivative or
++collective works based on the Program.
++
++In addition, mere aggregation of another work not based on the Program
++with the Program (or with a work based on the Program) on a volume of
++a storage or distribution medium does not bring the other work under
++the scope of this License.
++
++  3. You may copy and distribute the Program (or a work based on it,
++under Section 2) in object code or executable form under the terms of
++Sections 1 and 2 above provided that you also do one of the following:
++
++    a) Accompany it with the complete corresponding machine-readable
++    source code, which must be distributed under the terms of Sections
++    1 and 2 above on a medium customarily used for software interchange; or,
++
++    b) Accompany it with a written offer, valid for at least three
++    years, to give any third party, for a charge no more than your
++    cost of physically performing source distribution, a complete
++    machine-readable copy of the corresponding source code, to be
++    distributed under the terms of Sections 1 and 2 above on a medium
++    customarily used for software interchange; or,
++
++    c) Accompany it with the information you received as to the offer
++    to distribute corresponding source code.  (This alternative is
++    allowed only for noncommercial distribution and only if you
++    received the program in object code or executable form with such
++    an offer, in accord with Subsection b above.)
++
++The source code for a work means the preferred form of the work for
++making modifications to it.  For an executable work, complete source
++code means all the source code for all modules it contains, plus any
++associated interface definition files, plus the scripts used to
++control compilation and installation of the executable.  However, as a
++special exception, the source code distributed need not include
++anything that is normally distributed (in either source or binary
++form) with the major components (compiler, kernel, and so on) of the
++operating system on which the executable runs, unless that component
++itself accompanies the executable.
++
++If distribution of executable or object code is made by offering
++access to copy from a designated place, then offering equivalent
++access to copy the source code from the same place counts as
++distribution of the source code, even though third parties are not
++compelled to copy the source along with the object code.
++
++  4. You may not copy, modify, sublicense, or distribute the Program
++except as expressly provided under this License.  Any attempt
++otherwise to copy, modify, sublicense or distribute the Program is
++void, and will automatically terminate your rights under this License.
++However, parties who have received copies, or rights, from you under
++this License will not have their licenses terminated so long as such
++parties remain in full compliance.
++
++  5. You are not required to accept this License, since you have not
++signed it.  However, nothing else grants you permission to modify or
++distribute the Program or its derivative works.  These actions are
++prohibited by law if you do not accept this License.  Therefore, by
++modifying or distributing the Program (or any work based on the
++Program), you indicate your acceptance of this License to do so, and
++all its terms and conditions for copying, distributing or modifying
++the Program or works based on it.
++
++  6. Each time you redistribute the Program (or any work based on the
++Program), the recipient automatically receives a license from the
++original licensor to copy, distribute or modify the Program subject to
++these terms and conditions.  You may not impose any further
++restrictions on the recipients' exercise of the rights granted herein.
++You are not responsible for enforcing compliance by third parties to
++this License.
++
++  7. If, as a consequence of a court judgment or allegation of patent
++infringement or for any other reason (not limited to patent issues),
++conditions are imposed on you (whether by court order, agreement or
++otherwise) that contradict the conditions of this License, they do not
++excuse you from the conditions of this License.  If you cannot
++distribute so as to satisfy simultaneously your obligations under this
++License and any other pertinent obligations, then as a consequence you
++may not distribute the Program at all.  For example, if a patent
++license would not permit royalty-free redistribution of the Program by
++all those who receive copies directly or indirectly through you, then
++the only way you could satisfy both it and this License would be to
++refrain entirely from distribution of the Program.
++
++If any portion of this section is held invalid or unenforceable under
++any particular circumstance, the balance of the section is intended to
++apply and the section as a whole is intended to apply in other
++circumstances.
++
++It is not the purpose of this section to induce you to infringe any
++patents or other property right claims or to contest validity of any
++such claims; this section has the sole purpose of protecting the
++integrity of the free software distribution system, which is
++implemented by public license practices.  Many people have made
++generous contributions to the wide range of software distributed
++through that system in reliance on consistent application of that
++system; it is up to the author/donor to decide if he or she is willing
++to distribute software through any other system and a licensee cannot
++impose that choice.
++
++This section is intended to make thoroughly clear what is believed to
++be a consequence of the rest of this License.
++
++  8. If the distribution and/or use of the Program is restricted in
++certain countries either by patents or by copyrighted interfaces, the
++original copyright holder who places the Program under this License
++may add an explicit geographical distribution limitation excluding
++those countries, so that distribution is permitted only in or among
++countries not thus excluded.  In such case, this License incorporates
++the limitation as if written in the body of this License.
++
++  9. The Free Software Foundation may publish revised and/or new versions
++of the General Public License from time to time.  Such new versions will
++be similar in spirit to the present version, but may differ in detail to
++address new problems or concerns.
++
++Each version is given a distinguishing version number.  If the Program
++specifies a version number of this License which applies to it and "any
++later version", you have the option of following the terms and conditions
++either of that version or of any later version published by the Free
++Software Foundation.  If the Program does not specify a version number of
++this License, you may choose any version ever published by the Free Software
++Foundation.
++
++  10. If you wish to incorporate parts of the Program into other free
++programs whose distribution conditions are different, write to the author
++to ask for permission.  For software which is copyrighted by the Free
++Software Foundation, write to the Free Software Foundation; we sometimes
++make exceptions for this.  Our decision will be guided by the two goals
++of preserving the free status of all derivatives of our free software and
++of promoting the sharing and reuse of software generally.
++
++			    NO WARRANTY
++
++  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
++REPAIR OR CORRECTION.
++
++  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
++POSSIBILITY OF SUCH DAMAGES.
++
++		     END OF TERMS AND CONDITIONS
++
++	    How to Apply These Terms to Your New Programs
++
++  If you develop a new program, and you want it to be of the greatest
++possible use to the public, the best way to achieve this is to make it
++free software which everyone can redistribute and change under these terms.
++
++  To do so, attach the following notices to the program.  It is safest
++to attach them to the start of each source file to most effectively
++convey the exclusion of warranty; and each file should have at least
++the "copyright" line and a pointer to where the full notice is found.
++
++    <one line to give the program's name and a brief idea of what it does.>
++    Copyright (C) 19yy  <name of author>
++
++    This program is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++    GNU General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++
++
++Also add information on how to contact you by electronic and paper mail.
++
++If the program is interactive, make it output a short notice like this
++when it starts in an interactive mode:
++
++    Gnomovision version 69, Copyright (C) 19yy name of author
++    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
++    This is free software, and you are welcome to redistribute it
++    under certain conditions; type `show c' for details.
++
++The hypothetical commands `show w' and `show c' should show the appropriate
++parts of the General Public License.  Of course, the commands you use may
++be called something other than `show w' and `show c'; they could even be
++mouse-clicks or menu items--whatever suits your program.
++
++You should also get your employer (if you work as a programmer) or your
++school, if any, to sign a "copyright disclaimer" for the program, if
++necessary.  Here is a sample; alter the names:
++
++  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
++  `Gnomovision' (which makes passes at compilers) written by James Hacker.
++
++  <signature of Ty Coon>, 1 April 1989
++  Ty Coon, President of Vice
++
++This General Public License does not permit incorporating your program into
++proprietary programs.  If your program is a subroutine library, you may
++consider it more useful to permit linking proprietary applications with the
++library.  If this is what you want to do, use the GNU Library General
++Public License instead of this License.
+diff -urNad zaptel-1.2.5/ztgsm/Makefile /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/Makefile
+--- zaptel-1.2.5/ztgsm/Makefile	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/Makefile	2006-04-10 12:23:31.000000000 +0300
+@@ -0,0 +1,53 @@
++KINCLUDES = /usr/src/linux/include
++BRISTUFFBASE = $(shell dirname `pwd`)
++
++ZAP = $(shell [ -f $(BRISTUFFBASE)/zaptel/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel")
++
++HOSTCC=gcc
++
++CFLAGS+=-I. $(ZAP) -O4 -g -Wall -DBUILDING_TONEZONE  #-DTONEZONE_DRIVER
++CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi)
++
++KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP)
++KFLAGS+=$(shell [ -f $(KINCLUDES)/linux/modversions.h ] && echo "-DMODVERSIONS -include $(KINCLUDES)/linux/modversions.h")
++KFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-msoft-float -fsigned-char"; fi)
++
++OBJS=ztgsm.o
++
++BUILDVER=$(shell if uname -r | grep -q ^2.6; then echo "linux26"; else echo "linux24"; fi)
++
++MODCONF=$(shell if [ -d $(INSTALL_PREFIX)/etc/modprobe.d ]; then echo "$(INSTALL_PREFIX)/etc/modprobe.d/zaptel"; elif [ -d $(INSTALL_PREFIX)/etc/modutils ]; then echo "$(INSTALL_PREFIX)/etc/modutils/zaptel"; elif [ -f $(INSTALL_PREFIX)/etc/modprobe.conf ]; then echo "$(INSTALL_PREFIX)/modprobe.conf"; elif [ -f $(INSTALL_PREFIX)/etc/modules.conf ]; then echo "$(INSTALL_PREFIX)/etc/modules.conf"; else echo $(INSTALL_PREFIX)/etc/conf.modules ; fi)
++
++MODULES=ztgsm
++
++MODULESO=$(shell for x in $(MODULES); do echo "$$x.o "; done )
++MODULESKO=$(shell for x in $(MODULES); do echo "$$x.ko "; done )
++
++PWD=$(shell pwd)
++
++obj-m := $(MODULESO)
++
++all: $(BUILDVER)
++
++linux24: $(OBJS)
++	sync
++
++linux26:
++	@if ! [ -d /usr/src/linux-2.6 ]; then echo "Link /usr/src/linux-2.6 to your kernel sources first!"; exit 1 ; fi
++	make -C /usr/src/linux-2.6 SUBDIRS=$(PWD) ZAP=$(ZAP) modules
++obj-m := $(OBJS)
++
++ztgsm.o: ztgsm.c ztgsm.h 
++	$(CC) -c ztgsm.c $(KFLAGS)
++
++clean:	
++	rm -f $(OBJS) *.ko *.mod.c *.mod.o .*o.cmd *~
++	rm -rf .tmp_versions
++
++install:	install$(BUILDVER)
++
++installlinux26: all
++	install -D -m 644 ztgsm.ko $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/ztgsm.ko
++
++installlinux24: all
++	install -D -m 644 ztgsm.o $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/ztgsm.o
+diff -urNad zaptel-1.2.5/ztgsm/zapata.conf.duoGSM /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/zapata.conf.duoGSM
+--- zaptel-1.2.5/ztgsm/zapata.conf.duoGSM	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/zapata.conf.duoGSM	2006-04-10 13:30:26.000000000 +0300
+@@ -0,0 +1,23 @@
++[channels]
++txgain = -10.0
++rxgain = 0.0
++
++signalling = gsm
++context = from-gsm
++
++;group=1
++
++; phone number for SIM card in slot A
++;exten=016012345671
++; PIN for SIM card in slot A
++;pin=1234
++
++;channel => 1
++
++; phone number for SIM card in slot B
++;exten=016012345672
++; PIN for SIM card in slot B
++;pin=1234
++
++;channel => 3
++
+diff -urNad zaptel-1.2.5/ztgsm/zapata.conf.quadGSM /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/zapata.conf.quadGSM
+--- zaptel-1.2.5/ztgsm/zapata.conf.quadGSM	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/zapata.conf.quadGSM	2006-04-10 13:30:13.000000000 +0300
+@@ -0,0 +1,36 @@
++[channels]
++txgain = -10.0
++rxgain = 0.0
++
++signalling = gsm
++context = from-gsm
++
++;group=1
++
++; phone number for SIM card in slot A
++;exten=016012345671
++; PIN for SIM card in slot A
++;pin=1234
++
++;channel => 1
++
++; phone number for SIM card in slot B
++;exten=016012345672
++; PIN for SIM card in slot B
++;pin=1234
++
++;channel => 3
++
++; phone number for SIM card in slot C
++;exten=016012345673
++; PIN for SIM card in slot C
++;pin=1234
++
++;channel => 5
++
++; phone number for SIM card in slot D
++;exten=016012345674
++; PIN for SIM card in slot D
++;pin=1234
++
++;channel => 7
+diff -urNad zaptel-1.2.5/ztgsm/zapata.conf.unoGSM /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/zapata.conf.unoGSM
+--- zaptel-1.2.5/ztgsm/zapata.conf.unoGSM	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/zapata.conf.unoGSM	2006-04-10 13:30:41.000000000 +0300
+@@ -0,0 +1,15 @@
++[channels]
++txgain = -10.0
++rxgain = 0.0
++
++signalling = gsm
++context = from-gsm
++
++;group=1
++
++; phone number for SIM card in slot A
++;exten=016012345671
++; PIN for SIM card in slot A
++;pin=1234
++
++;channel => 1
+diff -urNad zaptel-1.2.5/ztgsm/zaptel.conf.duoGSM /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/zaptel.conf.duoGSM
+--- zaptel-1.2.5/ztgsm/zaptel.conf.duoGSM	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/zaptel.conf.duoGSM	2006-04-10 13:26:59.000000000 +0300
+@@ -0,0 +1,11 @@
++loadzone=nl
++defaultzone=nl
++
++alaw=1,3
++
++span=1,1,3,ccs,ami
++span=2,2,3,ccs,ami
++
++bchan=1,3
++dchan=2,4
++
+diff -urNad zaptel-1.2.5/ztgsm/zaptel.conf.quadGSM /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/zaptel.conf.quadGSM
+--- zaptel-1.2.5/ztgsm/zaptel.conf.quadGSM	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/zaptel.conf.quadGSM	2006-04-10 13:27:04.000000000 +0300
+@@ -0,0 +1,13 @@
++loadzone=nl
++defaultzone=nl
++
++alaw=1,3,5,7
++
++span=1,1,3,ccs,ami
++span=2,2,3,ccs,ami
++span=3,3,3,ccs,ami
++span=4,4,3,ccs,ami
++
++bchan=1,3,5,7
++dchan=2,4,6,8
++
+diff -urNad zaptel-1.2.5/ztgsm/zaptel.conf.unoGSM /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/zaptel.conf.unoGSM
+--- zaptel-1.2.5/ztgsm/zaptel.conf.unoGSM	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/zaptel.conf.unoGSM	2006-04-10 13:27:20.000000000 +0300
+@@ -0,0 +1,10 @@
++loadzone=nl
++defaultzone=nl
++
++alaw=1
++
++span=1,1,3,ccs,ami
++
++bchan=1
++dchan=2
++
+diff -urNad zaptel-1.2.5/ztgsm/ztgsm.c /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/ztgsm.c
+--- zaptel-1.2.5/ztgsm/ztgsm.c	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/ztgsm.c	2006-04-25 16:48:02.000000000 +0300
+@@ -0,0 +1,1133 @@
++/*
++ * ztgsm.c - Zaptel driver for the uno/duo/quad GSM PCI cards
++ *
++ * Copyright (C) 2005, 2006 Junghanns.NET GmbH
++ *
++ * Klaus-Peter Junghanns <kpj at junghanns.net>
++ *
++ * This program is free software and may be modified and
++ * distributed under the terms of the GNU Public License.
++ *
++ */
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <zaptel.h>
++#include "ztgsm.h"
++
++#if CONFIG_PCI
++
++static int debug=0;
++static int pcm_xbar=0;
++static struct ztgsm_card *ztgsm_dev_list = NULL;
++static int ztgsm_dev_count = 0;
++static int ztgsm_spans = 0;
++// static struct pci_dev *multi_gsm = NULL;
++static spinlock_t registerlock = SPIN_LOCK_UNLOCKED;
++
++void ztgsm_init_xbar(struct ztgsm_card *gsmtmp) {
++    int i = 0;
++    for (i=0; i <= 0x01FF; i++) {
++	ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x00000182 | i);
++    }
++}
++
++void ztgsm_switch_on(struct ztgsm_card *gsmtmp, int span) {
++    unsigned int dtr_on_off = 0;
++    unsigned int rts_o = 0;
++    unsigned long flags;
++    
++    printk(KERN_INFO "ztgsm: Powering up span %d ...", span);
++    spin_lock_irqsave(&(gsmtmp->lock),flags);
++	dtr_on_off = ztgsm_indw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF);
++	dtr_on_off |= (1 << span) | (1 << (span+4));
++	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, dtr_on_off);
++    
++	rts_o = ztgsm_indw_io(gsmtmp, ztgsm_SER_RTS_O);
++	rts_o |= (1 << span);
++	ztgsm_outdw_io(gsmtmp, ztgsm_SER_RTS_O, rts_o);
++    spin_unlock_irqrestore(&(gsmtmp->lock),flags);
++
++    set_current_state(TASK_UNINTERRUPTIBLE);
++    schedule_timeout((1000 * HZ) / 1000);
++
++    spin_lock_irqsave(&(gsmtmp->lock),flags);
++	dtr_on_off = ztgsm_indw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF);
++        dtr_on_off &= ~(1 << span);
++        dtr_on_off |= 1 << (span+4);
++	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, dtr_on_off);
++    spin_unlock_irqrestore(&(gsmtmp->lock),flags);
++
++    set_current_state(TASK_UNINTERRUPTIBLE);
++    schedule_timeout((800 * HZ) / 1000);
++
++    spin_lock_irqsave(&(gsmtmp->lock),flags);
++	dtr_on_off = ztgsm_indw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF);
++	dtr_on_off |= (1 << span) | (1 << (span+4));
++        ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, dtr_on_off);
++    spin_unlock_irqrestore(&(gsmtmp->lock),flags);
++
++    set_current_state(TASK_UNINTERRUPTIBLE);
++    schedule_timeout((8000 * HZ) / 1000);
++
++    spin_lock_irqsave(&(gsmtmp->lock),flags);
++	dtr_on_off = ztgsm_indw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF);
++	dtr_on_off &= ~(1 << (span+4));
++        dtr_on_off |= (1 << span);
++	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, dtr_on_off);
++
++        rts_o = ztgsm_indw_io(gsmtmp, ztgsm_SER_RTS_O);
++	rts_o &= ~(1 << span);
++        ztgsm_outdw_io(gsmtmp, ztgsm_SER_RTS_O, 0x0);
++	gsmtmp->power[span] = 1;
++    spin_unlock_irqrestore(&(gsmtmp->lock),flags);
++
++    printk(" done.\n");
++}
++
++void ztgsm_switch_off(struct ztgsm_card *gsmtmp, int span) {
++    unsigned int dtr_on_off = 0;
++    unsigned long flags;
++
++    spin_lock_irqsave(&(gsmtmp->lock),flags);
++	dtr_on_off = ztgsm_indw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF);
++	printk(KERN_INFO "ztgsm: Powering down span %d (SER_DTR_ON_OFF %x)...", span, dtr_on_off);
++    
++	dtr_on_off &= ~ (1 << span);
++	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, dtr_on_off);
++    spin_unlock_irqrestore(&(gsmtmp->lock),flags);
++
++    set_current_state(TASK_UNINTERRUPTIBLE);
++    schedule_timeout((5000 * HZ) / 1000);
++
++    spin_lock_irqsave(&(gsmtmp->lock),flags);
++	dtr_on_off = ztgsm_indw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF);
++        dtr_on_off |= (1 << span);
++	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, dtr_on_off);
++	gsmtmp->power[span] = 0;
++    spin_unlock_irqrestore(&(gsmtmp->lock),flags);
++    printk(" done.\n");
++}
++
++void ztgsm_switch_on_all(struct ztgsm_card *gsmtmp) {
++    printk(KERN_INFO "ztgsm: Powering up all spans...");
++
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0xff);
++    
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_RTS_O, 0x0f);
++
++    set_current_state(TASK_UNINTERRUPTIBLE);
++    schedule_timeout((1000 * HZ) / 1000);
++
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0xf0);
++
++    set_current_state(TASK_UNINTERRUPTIBLE);
++    schedule_timeout((800 * HZ) / 1000);
++
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0xff);
++
++    set_current_state(TASK_UNINTERRUPTIBLE);
++    schedule_timeout((8000 * HZ) / 1000);
++
++//    ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0x0f);
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0xff);
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_RTS_O, 0x0); /* 1 == -12 v */
++    
++/* new
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0x00);
++
++    set_current_state(TASK_UNINTERRUPTIBLE);
++    schedule_timeout((1000 * HZ) / 1000);
++
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0x0f);
++*/    
++
++    printk(" done.\n");
++
++    gsmtmp->power[0] = 1;
++    gsmtmp->power[1] = 1;
++    gsmtmp->power[2] = 1;
++    gsmtmp->power[3] = 1;
++}
++
++void ztgsm_switch_off_all(struct ztgsm_card *gsmtmp) {
++    if (gsmtmp->power[0] || gsmtmp->power[1] || gsmtmp->power[2] || gsmtmp->power[3]) { 
++	printk(KERN_INFO "ztgsm: Powering down all spans...");
++	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0x0);
++
++	set_current_state(TASK_UNINTERRUPTIBLE);
++	schedule_timeout((5000 * HZ) / 1000);
++
++	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0xf);
++	printk(" done.\n");
++
++	gsmtmp->power[0] = 0;
++	gsmtmp->power[1] = 0;
++        gsmtmp->power[2] = 0;
++	gsmtmp->power[3] = 0;
++    }
++}
++
++
++void ztgsm_shutdownCard(struct ztgsm_card *gsmtmp) {
++    unsigned long flags;
++    struct ztgsm_span *gsmspan = NULL;
++    int i = 0;
++    if (gsmtmp == NULL) {
++	printk(KERN_INFO "ztgsm: shutting down NULL card!\n");
++	return;
++    }
++
++    spin_lock_irqsave(&gsmtmp->lock,flags);
++
++    gsmtmp->dead = 1;
++
++    if ((!gsmtmp->pci_io) || (gsmtmp->ioport == 0)) {
++	return;
++    }
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_INT_MASK, 0x0);
++    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_FC_TOG_BIT, 0x0);
++    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_SAP_EN, 0x0);
++
++    ztgsm_switch_off_all(gsmtmp);
++
++/*    for (i=0; i < gsmtmp->gsmspans; i++) {
++	ztgsm_switch_off(gsmtmp, i);
++    }  */
++
++
++    ztgsm_outdw_io(gsmtmp, ztgsm_LED_DUAL, 0xFF00);
++
++
++
++    // turn off irqs
++
++    free_irq(gsmtmp->irq,gsmtmp);
++
++    // softreset
++
++    release_region(gsmtmp->ioport, 0x100);
++    iounmap((void *) gsmtmp->pci_io);
++    release_mem_region(gsmtmp->pci_io_phys, gsmtmp->iomem_size);
++
++    gsmtmp->pci_io = 0;
++    gsmtmp->ioport = 0;
++
++    pci_write_config_word(gsmtmp->pcidev, PCI_COMMAND, 0);	
++
++    if (gsmtmp->pcidev != NULL) {
++        pci_disable_device(gsmtmp->pcidev);
++    }
++    
++    spin_unlock_irqrestore(&gsmtmp->lock,flags);
++
++    for (i=0; i < gsmtmp->gsmspans; i++) {
++	gsmspan = &gsmtmp->gsmspan[i];
++        if(gsmspan->span.flags & ZT_FLAG_RUNNING) {
++//	    ztgsm_shutdown(&gsmspan->span);
++	    if (debug)
++	        printk(KERN_INFO "ztgsm: shutdown card %d span %d.\n",gsmtmp->cardno,i);
++	}
++        if(gsmspan->span.flags & ZT_FLAG_REGISTERED) {
++	    zt_unregister(&gsmspan->span);
++	    if (debug)
++	        printk(KERN_INFO "ztgsm: unregistered card %d span %d.\n",gsmtmp->cardno,i);
++	}
++    }
++
++}
++
++
++void ztgsm_resetCard(struct ztgsm_card *gsmtmp) {
++    unsigned long flags;
++    spin_lock_irqsave(&(gsmtmp->lock),flags);
++//    pci_write_config_word(gsmtmp->pcidev, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
++    
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_CLK_DIV, 0x12);
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_CLK_PRE_DIV, 0x06);
++//    ztgsm_outdw_io(gsmtmp, ztgsm_SER_CLK_PRE_DIV, 0x03);
++//    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_CLK_PRE_DIV, 0x06);
++    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_CLK_PRE_DIV, 0x0C);
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_INT_MASK, 0x0);
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_IDLE_VAL, 0x01);
++
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_TX_EN, 0x0);
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_RX_EN, 0x0);
++
++
++    gsmtmp->ticks = 0;
++    gsmtmp->clicks = 0;
++
++    spin_unlock_irqrestore(&(gsmtmp->lock),flags);
++}
++
++void ztgsm_startCard(struct ztgsm_card *gsmtmp) {
++    unsigned long flags;
++    spin_lock_irqsave(&(gsmtmp->lock),flags);
++    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_FC_TOG_BIT, 0x03);
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_INT_MASK, 0x1FFFF);
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_RX_WATERMARK, 0x0A);
++    ztgsm_outdw_io(gsmtmp, ztgsm_SIM_SEL, 0x0);
++    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_SAP_EN, 0x0);
++    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_MASK_LAST, 0x001F0000 | 0x1F); /* PCM32 0x100 frames */
++//    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_MASK_LAST, (0x001FC000 | 0x1F)); /* PCM32 0x40 frames */
++
++    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_SAP_EN, 0x1F);
++    switch (gsmtmp->gsmspans) {
++	case 4:
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x01010186); /* GSM_A (alaw) -> pci slot 0x01 */
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x01840101); /* pci slot 0x01 -> GSM_A */
++
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x0103018A); /* GSM_B (alaw) -> pci slot 0x03 */
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x01880103); /* pci slot 0x03 -> GSM_B */
++
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x0105018E); /* GSM_C (alaw) -> pci slot 0x05 */
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x018C0105); /* pci slot 0x05 -> GSM_C */
++
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x01070192); /* GSM_D (alaw) -> pci slot 0x07 */
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x01900107); /* pci slot 0x07 -> GSM_D */
++	    break;
++	case 2:
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x01010186); /* GSM_A (alaw) -> pci slot 0x01 */
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x01840101); /* pci slot 0x01 -> GSM_A */
++
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x0103018A); /* GSM_B (alaw) -> pci slot 0x03 */
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x01880103); /* pci slot 0x03 -> GSM_B */
++	    break;
++	case 1:
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x01010186); /* GSM_A (alaw) -> pci slot 0x01 */
++	    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG, 0x01840101); /* pci slot 0x01 -> GSM_A */
++	    break;
++    }
++
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_RX_EN, 0x0F);
++    ztgsm_outdw_io(gsmtmp, ztgsm_SER_TX_EN, 0x0F);
++    if (debug)
++	printk(KERN_INFO "ztgsm: SER_TX_EN %d SER_RX_EN %d \n", ztgsm_indw_io(gsmtmp, ztgsm_SER_TX_EN), ztgsm_indw_io(gsmtmp, ztgsm_SER_RX_EN));
++    spin_unlock_irqrestore(&(gsmtmp->lock),flags);
++}
++
++static void ztgsm_xbar(struct ztgsm_card *gsmtmp, int dst, int src, int slin) {
++    unsigned long flags;
++    int format = 0;
++    
++    if (!gsmtmp) return;
++
++    if (slin) format = 0x2000;
++    spin_lock_irqsave(&(gsmtmp->lock), flags);
++	if (debug > 1)
++	    printk(KERN_INFO "ztgsm: ztgsm_PCM_VECTOR_CFG %4x \n", (dst << 16) | src | format);
++	ztgsm_outdw_io(gsmtmp, ztgsm_PCM_VECTOR_CFG,  (dst << 16) | src | format);
++    spin_unlock_irqrestore(&(gsmtmp->lock), flags);
++}
++
++static int ztgsm_dacs(struct zt_chan *dst, struct zt_chan *src) {
++    struct ztgsm_span *src_span;
++    struct ztgsm_span *dst_span;
++    
++    dst_span = dst->pvt;
++    if (dst->chanpos == 2) return -1;
++
++    if (src) {
++	if (src->chanpos == 2) return -1;
++	src_span = src->pvt;
++	if (debug > 1)
++	    printk(KERN_INFO "linking channel %d span %d to channel %d span %d\n", src->chanpos, src_span->span.offset, dst->chanpos, dst_span->span.offset);
++	/* ALAW */
++	ztgsm_xbar(dst->span->pvt, 0x184 + (4 * dst_span->span.offset), 0x186 + (4 * src_span->span.offset), 0);
++
++	/* SLIN */
++/*	ztgsm_xbar(dst->span->pvt, 0x184 + (4 * dst_span->span.offset), 0x184 + (4 * src_span->span.offset), 1);
++	ztgsm_xbar(dst->span->pvt, 0x185 + (4 * dst_span->span.offset), 0x185 + (4 * src_span->span.offset), 1); */
++
++    } else {
++	if (debug > 1)
++	    printk(KERN_INFO "unlinking channel %d span %d\n", dst->chanpos, dst_span->span.offset);
++	/* reassign pci source */
++	ztgsm_xbar(dst->span->pvt, 0x184 + (4 * dst_span->span.offset), 0x100 | ((dst_span->span.offset * 2)+1), 0);
++	/* reassign pci destination */
++	ztgsm_xbar(dst->span->pvt, 0x100 | ((dst_span->span.offset * 2)+1), 0x186 + (4 * dst_span->span.offset), 0);
++    }
++
++    return 0;
++}
++
++static int ztgsm_ser_rx(struct ztgsm_card *gsmtmp, int span) {
++    unsigned int rxcreg = 0;
++    unsigned int rxdreg = 0;
++    int rx_count = 0;
++    int i = 0;
++    unsigned char data = 0;
++    unsigned int count_reg = 0;
++    int rd_ptr = 0;
++    int wr_ptr = 0;
++    switch (span) {
++	case 0:	rxcreg = ztgsm_SER_RX_COUNT_A;
++		rxdreg = ztgsm_SER_RX_DATA_A;
++		break;
++	case 1:	rxcreg = ztgsm_SER_RX_COUNT_B;
++		rxdreg = ztgsm_SER_RX_DATA_B;
++		break;
++	case 2:	rxcreg = ztgsm_SER_RX_COUNT_C;
++		rxdreg = ztgsm_SER_RX_DATA_C;
++		break;
++	case 3:	rxcreg = ztgsm_SER_RX_COUNT_D;
++		rxdreg = ztgsm_SER_RX_DATA_D;
++		break;
++    }
++    count_reg = ztgsm_indw_io(gsmtmp, rxcreg);
++    rx_count = count_reg & 0x1F;
++    if (rx_count) {
++	rd_ptr = (count_reg & 0x03E0) >> 5;
++	wr_ptr = (count_reg & 0x7C00) >> 10;
++//	if (debug) 
++//	    printk(KERN_CRIT "ztgsm: SER_RX_COUNT_%d [wr_ptr %d rd_ptr %d count %d]\n", span, wr_ptr, rd_ptr, rx_count);
++	if ((gsmtmp->ser_rx_idx[span] + rx_count) < ztgsm_SER_BUF_SIZE) {
++	    if (debug) printk(KERN_CRIT "ztgsm: SER_RX span %d [", span);
++	    for (i=0;i<rx_count; i++) {
++		data = ztgsm_indw_io(gsmtmp, rxdreg);
++		if (debug) printk(" %#x", data);
++		if (gsmtmp->gsmspan[span].span.flags & ZT_FLAG_RUNNING)
++		    gsmtmp->ser_rx_buf[span][gsmtmp->ser_rx_idx[span]++] = data;
++	    }
++    	    if (debug) printk("]\n");
++	} else {
++	    printk(KERN_INFO "ztgsm: RX buffer overflow on span %d\n", span);
++	}
++    }
++    return rx_count;
++}
++
++static int ztgsm_zap_rx(struct ztgsm_card *gsmtmp, int span) {
++    int i = 0;
++        
++    if (gsmtmp->ser_rx_idx[span]) {
++	memcpy(gsmtmp->drxbuf[span], &gsmtmp->ser_rx_buf[span], gsmtmp->ser_rx_idx[span]);
++	if (debug) {
++	    printk(KERN_INFO "ztgsm: span %d RX [ \n", span);
++	    for (i=0;i<gsmtmp->ser_rx_idx[span]; i++) {
++		if (gsmtmp->ser_rx_buf[span][i] != 0x0d)
++		    printk("%c", gsmtmp->ser_rx_buf[span][i]);
++	    }
++    	    printk("]\n");
++	}
++	gsmtmp->gsmspan[span].chans[1].eofrx = 1;
++	gsmtmp->gsmspan[span].chans[1].bytes2receive = gsmtmp->ser_rx_idx[span];
++	gsmtmp->ser_rx_idx[span] = 0;
++    }
++    return 0;
++}
++
++static int ztgsm_ser_tx(struct ztgsm_card *gsmtmp, int span) {
++    unsigned int txcreg = 0;
++    unsigned int txdreg = 0;
++    unsigned int tx_wm_sen = 0;
++    int left = 0;
++    int i = 0;
++    int count = 0;
++    unsigned int count_reg = 0;
++    int rd_ptr = 0;
++    int wr_ptr = 0;
++    struct ztgsm_span *gsmspan = NULL;
++
++    switch (span) {
++	case 0:	txcreg = ztgsm_SER_TX_COUNT_A;
++		txdreg = ztgsm_SER_TX_DATA_A;
++		break;
++	case 1:	txcreg = ztgsm_SER_TX_COUNT_B;
++		txdreg = ztgsm_SER_TX_DATA_B;
++		break;
++	case 2:	txcreg = ztgsm_SER_TX_COUNT_C;
++		txdreg = ztgsm_SER_TX_DATA_C;
++		break;
++	case 3:	txcreg = ztgsm_SER_TX_COUNT_D;
++		txdreg = ztgsm_SER_TX_DATA_D;
++		break;
++    }
++    gsmspan = &gsmtmp->gsmspan[span];
++    if (gsmspan) {
++	count_reg = ztgsm_indw_io(gsmtmp, txcreg);
++	left = ztgsm_FIFO_SIZE - (count_reg & 0x1F);
++	if (left >= 1 ) {
++	    rd_ptr = (count_reg & 0x03E0) >> 5;
++	    wr_ptr = (count_reg & 0x7C00) >> 10;
++	    if (debug) 
++		printk(KERN_CRIT "ztgsm: SER_TX_COUNT_%d [wr_ptr %d rd_ptr %d free %d]\n", span, wr_ptr, rd_ptr, left);
++	    if (gsmtmp->ser_tx_idx[span] < left) {
++		count = gsmtmp->ser_tx_idx[span];
++    	    } else {
++		count = left;
++	    }
++	    if (debug)
++		printk(KERN_INFO "ztgsm: span %d SER_TX [ ", span);
++	    for (i=0;i<count; i++) {
++		if (debug)
++	    	    printk("%c", gsmtmp->ser_tx_buf[span][i]);
++		ztgsm_outdw_io(gsmtmp, txdreg, gsmtmp->ser_tx_buf[span][i]);
++	    }
++	    if (debug)
++	        printk("]\n");
++	    gsmtmp->ser_tx_idx[span] -= count;
++	    if (gsmtmp->ser_tx_idx[span] > 0) {
++		memmove(&gsmtmp->ser_tx_buf[span][0], &gsmtmp->ser_tx_buf[span][i], gsmtmp->ser_tx_idx[span]);
++	    }
++	    tx_wm_sen = (ztgsm_indw_io(gsmtmp, ztgsm_SER_TX_WM_SEN) & 0xF) | (1 << span);
++	    ztgsm_outdw_io(gsmtmp, ztgsm_SER_TX_WM_SEN, tx_wm_sen);
++//	    printk(KERN_INFO "ztgsm: span %d TX_IDX %d count %d tx_wm_send %d\n", span, gsmtmp->ser_tx_idx[span], count, tx_wm_sen);
++	}
++    }
++    return i;
++}
++
++static int ztgsm_zap_tx(struct ztgsm_card *gsmtmp, int span) {
++    struct ztgsm_span *gsmspan = NULL;
++    int i = 0;
++
++    gsmspan = &gsmtmp->gsmspan[span];
++    if (!gsmspan)
++	 return -1;
++	if (gsmspan->chans[1].bytes2transmit) {
++	    if (debug) {
++		printk(KERN_INFO "ztgsm: span %d TX [ ", span);
++		for (i=0;i<gsmspan->chans[1].bytes2transmit; i++) {
++		    printk("%c ", gsmtmp->dtxbuf[span][i]);
++		}
++	        printk("]\n");
++	    }
++	    if (gsmtmp->ser_tx_idx[span] + gsmspan->chans[1].bytes2transmit < ztgsm_SER_BUF_SIZE) {
++		memcpy(&gsmtmp->ser_tx_buf[span][gsmtmp->ser_tx_idx[span]], gsmtmp->dtxbuf[span], gsmspan->chans[1].bytes2transmit);
++		gsmtmp->ser_tx_idx[span] += gsmspan->chans[1].bytes2transmit;
++		ztgsm_ser_tx(gsmtmp, span);
++	    } else {
++		printk(KERN_INFO "ztgsm: TX buffer overflow on span %d (TX_IDX %d BTT %d)\n", span, gsmtmp->ser_tx_idx[span] , gsmspan->chans[1].bytes2transmit);
++	    }
++	}
++		
++	gsmspan->chans[1].bytes2receive = 0;
++	gsmspan->chans[1].bytes2transmit = 0;
++	gsmspan->chans[1].eofrx = 0;
++	gsmspan->chans[1].eoftx = 0;
++    return 0;
++}
++
++
++static int ztgsm_span_rx(struct ztgsm_card *gsmtmp, int span) {
++    struct ztgsm_span *gsmspan = NULL;
++    unsigned int addr = 0;
++    unsigned int framecnt = 0;
++    unsigned int pcmframecnt = 0;
++    unsigned int fraddr = 0;
++    unsigned int data = 0;
++    int start = 0;
++    int len = 0;
++    int i = 0;
++    unsigned int slot = 0;
++    
++    switch(span) {
++	case 0: 
++	    slot = 1;
++	    break;
++	case 1: 
++	    slot = 3;
++	    break;
++	case 2: 
++	    slot = 5;
++	    break;
++	case 3: 
++	    slot = 7;
++	    break;
++    }
++//    slot = span;
++    gsmspan = &gsmtmp->gsmspan[span];
++    if (gsmspan) {
++	framecnt = gsmtmp->framecnt;
++	pcmframecnt = framecnt;
++    	framecnt &= ztgsm_FRAMES - 1;
++	start = framecnt - 16;
++	if (start < 0) {
++	    len = -start;
++	    if (len > ZT_CHUNKSIZE) len = ZT_CHUNKSIZE;
++	    fraddr = ztgsm_FRAMES + start;
++	} else {
++	    len = ZT_CHUNKSIZE;
++	    fraddr = start;
++	}
++
++	if (fraddr & 3) {
++	    printk(KERN_EMERG "ztgsm: RX span %d unaligned word address %#x (fraddr & 3 = %d)\n", span, fraddr, (fraddr & 3));
++	    fraddr -= fraddr & 3; /* align */
++	} 
++	if (len == ZT_CHUNKSIZE) {
++    	    addr = (slot << 8) | fraddr;
++//    	    addr = ((span+1) << 8) | fraddr;
++//    ztgsm_outdw_io(gsmtmp, ztgsm_LED_DUAL, addr & 0x4);
++	    data = ztgsm_indw(gsmtmp, addr);
++	    *((unsigned int *)&gsmtmp->rxbuf[span][0]) = data;
++
++
++//    ztgsm_outdw_io(gsmtmp, ztgsm_LED_DUAL, addr & 0x4);
++    	    addr = (slot << 8) | (fraddr + 4);
++//    	    addr = ((span+1) << 8) | (fraddr + 4);
++	    data = ztgsm_indw(gsmtmp, addr);
++	    *((unsigned int *)&gsmtmp->rxbuf[span][4]) = data;
++//    ztgsm_outdw_io(gsmtmp, ztgsm_LED_DUAL, 0xf);
++	} else {
++	    printk(KERN_EMERG "ztgsm: dropped audio span %d fraddr %d addr %d\n", span, fraddr, addr);
++	}
++if (!(gsmtmp->ticks % 1000) && (debug > 4)) {
++	printk(KERN_EMERG "ztgsm: RX DATA:");
++	for (i=0; i < ZT_CHUNKSIZE; i++) {
++	    printk("%x", gsmtmp->rxbuf[span][i]);
++	}
++	printk("\n");
++}
++
++    }
++    return 0;
++}
++
++static int ztgsm_span_tx(struct ztgsm_card *gsmtmp, int span) {
++    struct ztgsm_span *gsmspan = NULL;
++    unsigned int addr = 0;
++    unsigned int framecnt = 0;
++    unsigned int fraddr = 0;
++    int start = 0;
++    int len = 0;
++    unsigned int slot = 0;
++    
++    switch(span) {
++	case 0: 
++	    slot = 1;
++	    break;
++	case 1: 
++	    slot = 3;
++	    break;
++	case 2: 
++	    slot = 5;
++	    break;
++	case 3: 
++	    slot = 7;
++	    break; 
++    }
++//    slot = span;
++
++    gsmspan = &gsmtmp->gsmspan[span];
++    if (gsmspan) {
++	framecnt = gsmtmp->framecnt;
++    	framecnt &= ztgsm_FRAMES - 1;
++	start = framecnt + 16;
++
++	if (start < 0x0) {
++	    len = -start;
++	    if (len > ZT_CHUNKSIZE) len = ZT_CHUNKSIZE;
++	    fraddr = ztgsm_FRAMES + start;
++	} else {
++	    len = ZT_CHUNKSIZE;
++	    fraddr = start;
++	}
++	fraddr -= fraddr & 3; /* align */
++
++	if (fraddr & 3) {
++//	    printk(KERN_EMERG "ztgsm: unaligned word address %#x\n", addr);
++	} else if (len == ZT_CHUNKSIZE) {
++	    addr =(slot << 8 ) | fraddr;
++//	    addr =( (span+1) << 8 ) | fraddr;
++	    ztgsm_outdw(gsmtmp, addr, *((unsigned int*)&(gsmtmp->txbuf[span][0])));
++//    	    addr =( (span+1) << 8 ) | (fraddr + 4);
++    	    addr =(slot << 8 ) | (fraddr + 4);
++	    ztgsm_outdw(gsmtmp, addr, *((unsigned int*)&(gsmtmp->txbuf[span][4])));
++	}
++
++    }
++    return 0;
++}
++
++static void ztgsm_leds(struct ztgsm_card *gsmtmp, int leds) {
++    ztgsm_outdw_io(gsmtmp, ztgsm_LED_DUAL, leds);
++}
++
++static inline void ztgsm_run(struct ztgsm_card *gsmtmp) {
++    int s=0;
++    struct ztgsm_span *gsmspan = NULL;
++    for (s=0;s<gsmtmp->gsmspans;s++) {
++        gsmspan = &gsmtmp->gsmspan[s];
++        if (gsmspan) {
++	    if (gsmspan->span.flags & ZT_FLAG_RUNNING) {
++		if (!(gsmtmp->ticks % 1000)) {
++		    gsmtmp->ticks = 0;
++    	        }
++		if (gsmtmp->ticks >= 300)
++		    ztgsm_leds(gsmtmp, 0x000f);
++		if (gsmtmp->ticks >= 600)
++		    ztgsm_leds(gsmtmp, 0x0000);
++		if (gsmtmp->ticks == 900)
++		    ztgsm_leds(gsmtmp, 0xff00);
++		/* oh zaptel! tell us what to transmit... */
++    		zt_transmit(&gsmspan->span);
++		if (debug && (gsmspan->chans[1].bytes2transmit > 0))
++		    printk(KERN_CRIT "ztgsm: span %d bytes2transmit = %d\n", s, gsmspan->chans[1].bytes2transmit);
++		ztgsm_span_tx(gsmtmp, s);
++		ztgsm_zap_tx(gsmtmp, s);
++	    }
++
++	    if (gsmspan->span.flags & ZT_FLAG_RUNNING) {
++	        ztgsm_zap_rx(gsmtmp, s);
++	    	ztgsm_span_rx(gsmtmp, s);
++		/* oh zaptel! thou shall receive! */
++		zt_receive(&gsmspan->span);
++	    }
++	} 
++    }
++}
++
++
++
++#ifdef LINUX26
++static irqreturn_t ztgsm_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
++#else
++static void ztgsm_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
++#endif
++    struct ztgsm_card *gsmtmp = dev_id;
++    unsigned int ser_status = 0;
++    unsigned char mods = 0;
++    int s = 0;
++    int rx_count = 0;
++    unsigned long flags;
++
++    if (!gsmtmp || gsmtmp->dead) {
++#ifdef LINUX26
++		return IRQ_NONE;
++#else
++		return;
++#endif		
++    }
++
++    if ((!gsmtmp->pci_io) || (!gsmtmp->ioport)) {
++	    printk(KERN_CRIT "ztgsm: no pci mem/io\n");
++#ifdef LINUX26
++		return IRQ_NONE;
++#else
++		return;
++#endif		
++    }
++    
++    spin_lock_irqsave(&(gsmtmp->lock),flags);
++//	    printk(KERN_INFO "gsm: irq\n");
++    gsmtmp->last_framecnt = gsmtmp->framecnt;
++    gsmtmp->framecnt = ztgsm_indw_io(gsmtmp, ztgsm_PCM_FRAME_CNT);
++    ser_status = ztgsm_indw_io(gsmtmp, ztgsm_SER_STATUS);
++    if (ser_status) {
++	if (ser_status & 0x10000) {
++	    if (gsmtmp->framecnt - gsmtmp->last_framecnt != 8) {
++//		printk(KERN_INFO "ztgsm: missed IRQ, framecnt %d last_framecnt %d (diff %d)\n", gsmtmp->framecnt, gsmtmp->last_framecnt, (gsmtmp->framecnt - gsmtmp->last_framecnt));
++	    }
++	    gsmtmp->ticks++;
++	    if (!(gsmtmp->ticks % 1000)) {
++//		printk(KERN_INFO "ztgsm: pcm framce counter  %d\n", ztgsm_indw_io(gsmtmp, ztgsm_PCM_FRAME_CNT) & 0x1f);
++	    }
++	    if (!(gsmtmp->ticks % 300)) {
++		for (s=0; s<gsmtmp->gsmspans; s++) {
++		    rx_count = ztgsm_ser_rx(gsmtmp, s);
++		    if (debug && rx_count) 
++			printk(KERN_INFO "ztgsm: RX %d bytes on span %d\n", rx_count, s);
++		}
++	    }
++	    ztgsm_run(gsmtmp);
++	} else if (ser_status & 0x0F) {
++	    mods = (ser_status & 0x0F);
++	    for (s=0; s<gsmtmp->gsmspans; s++) {
++		if (mods & (1 << s)) {
++		    rx_count = ztgsm_ser_rx(gsmtmp, s);
++		    if (debug) 
++			printk(KERN_INFO "ztgsm: TX fifo overrun on span %d\n", s);
++		}
++	    }
++	} else if (ser_status & 0xF0) {
++	    mods = (ser_status & 0xF0) >> 4;
++		    if (debug) 
++			printk(KERN_INFO "ztgsm: RX mods %d\n", mods);
++	    for (s=0; s<gsmtmp->gsmspans; s++) {
++		if (mods & (1 << s)) {
++		    rx_count = ztgsm_ser_rx(gsmtmp, s);
++		    if (debug) 
++			printk(KERN_INFO "ztgsm: RX %d bytes on span %d\n", rx_count, s);
++		}
++	    }
++	} else if (ser_status & 0xF00) {
++	    mods = (ser_status & 0xF00) >> 8;
++	    for (s=0; s<gsmtmp->gsmspans; s++) {
++		if (mods & (1 << s)) {
++		    rx_count = ztgsm_ser_rx(gsmtmp, s);
++		    if (debug) 
++			printk(KERN_INFO "ztgsm: RX fifo overrun on span %d\n", s);
++		}
++	    }
++	} else if (ser_status & 0xF000) {
++	    mods = (ser_status & 0xF000) >> 12;
++	    for (s=0; s<gsmtmp->gsmspans; s++) {
++		if (mods & (1 << s)) {
++		    if (gsmtmp->ser_tx_idx[s]) {
++			/* sumfin left to transmit */
++			ztgsm_ser_tx(gsmtmp, s);
++		    }
++		    if (debug) 
++			printk(KERN_INFO "ztgsm: TX low water status %#x\n", ser_status);
++		}
++	    }
++	} else {
++	    if (debug) {
++		printk(KERN_INFO "ztgsm: SER_STATUS = %#x\n", ser_status);
++	    }
++	}
++    }
++    spin_unlock_irqrestore(&(gsmtmp->lock),flags);
++#ifdef LINUX26
++	return IRQ_RETVAL(1);
++#endif		
++}
++
++
++static int ztgsm_open(struct zt_chan *chan) {
++//    printk(KERN_INFO "ztgsm: channel %d opened.\n",chan->channo);
++#ifndef LINUX26
++    MOD_INC_USE_COUNT;
++#else
++    try_module_get(THIS_MODULE);
++#endif
++    return 0;
++}
++
++static int ztgsm_close(struct zt_chan *chan) {
++//    printk(KERN_INFO "ztgsm: channel %d closed.\n",chan->channo);
++#ifndef LINUX26
++    MOD_DEC_USE_COUNT;
++#else
++    module_put(THIS_MODULE);
++#endif
++    return 0;
++}
++
++static int ztgsm_chanconfig(struct zt_chan *chan,int sigtype) {
++//    printk(KERN_INFO "chan_config sigtype=%d\n",sigtype);
++    return 0;
++}
++
++static int ztgsm_spanconfig(struct zt_span *span,struct zt_lineconfig *lc) {
++//    span->lineconfig = lc->lineconfig;
++    return 0;
++}
++
++
++static int ztgsm_startup(struct zt_span *span) {
++    struct ztgsm_card *gsmtmp = span->pvt;
++    int running;
++    
++    if (gsmtmp == NULL) {
++	printk(KERN_INFO "ztgsm: no card for span at startup!\n");
++    }
++    
++    running = span->flags & ZT_FLAG_RUNNING;
++    span->chans[1].flags &= ~ZT_FLAG_HDLC;
++    span->chans[1].flags |= ZT_FLAG_BRIDCHAN;
++
++    if (!running) {
++	if (!gsmtmp->power[span->offset]) 
++	    ztgsm_switch_on(gsmtmp, span->offset);
++	span->flags |= ZT_FLAG_RUNNING;
++
++    } else {
++	printk(KERN_CRIT "already running\n");
++	return 0;
++    }
++    return 0;
++}
++
++static int ztgsm_shutdown(struct zt_span *span) {
++    int running;
++    struct ztgsm_card *gsmtmp = span->pvt;
++
++    if (gsmtmp == NULL) {
++	printk(KERN_INFO "ztgsm: no card for span at shutdown!\n");
++    }
++
++    running = span->flags & ZT_FLAG_RUNNING;
++
++    if (running) {
++	span->flags |= ZT_FLAG_RUNNING;
++	if (gsmtmp->power[span->offset]) 
++	    ztgsm_switch_off(gsmtmp, span->offset);
++    }
++    return 0;
++}
++
++static int ztgsm_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) {
++        switch(cmd) {
++        default:
++                return -ENOTTY;
++        }
++        return 0;
++}
++
++
++static int ztgsm_init(struct ztgsm_span *gsmspan, struct ztgsm_card *gsmtmp, int offset) {
++    memset(&gsmspan->span,0,sizeof(struct zt_span)); // you never can tell...
++    sprintf(gsmspan->span.name,"ztgsm/%d",gsmtmp->cardno);
++    switch (gsmtmp->type) {
++        case 0xb55d:
++		sprintf(gsmspan->span.desc,"Junghanns.NET unoGSM PCI Card %d",gsmtmp->cardno);
++	    break;
++	case 0xb55e:
++		sprintf(gsmspan->span.desc,"Junghanns.NET duoGSM PCI Card %d",gsmtmp->cardno);
++	    break;
++	case 0xb55f:
++		sprintf(gsmspan->span.desc,"Junghanns.NET quadGSM PCI Card %d",gsmtmp->cardno);
++	    break;
++    }
++    
++    gsmspan->span.spanconfig = ztgsm_spanconfig;
++    gsmspan->span.chanconfig = ztgsm_chanconfig;
++    gsmspan->span.startup = ztgsm_startup;
++    gsmspan->span.shutdown = ztgsm_shutdown;
++    gsmspan->span.maint = NULL;
++    gsmspan->span.rbsbits = NULL;
++    gsmspan->span.open = ztgsm_open;
++    gsmspan->span.close = ztgsm_close;
++    gsmspan->span.ioctl = ztgsm_ioctl;
++
++    if (pcm_xbar == 1) 
++	gsmspan->span.dacs = ztgsm_dacs;
++
++    gsmspan->span.chans = gsmspan->chans;
++    gsmspan->span.channels = 2;
++    gsmspan->span.deflaw = ZT_LAW_ALAW;
++    gsmspan->span.linecompat = ZT_CONFIG_CCS | ZT_CONFIG_AMI; 
++    init_waitqueue_head(&gsmspan->span.maintq);
++    gsmspan->span.pvt = gsmtmp;
++    gsmspan->span.offset = offset;
++
++    memset(&(gsmspan->chans[0]),0x0,sizeof(struct zt_chan));
++    sprintf(gsmspan->chans[0].name,"ztgsm/%d", 0);
++    gsmspan->chans[0].pvt = gsmspan;
++    gsmspan->chans[0].sigcap =  ZT_SIG_CLEAR;
++    gsmspan->chans[0].chanpos = 1; 
++
++    memset(&(gsmspan->chans[1]),0x0,sizeof(struct zt_chan));
++    sprintf(gsmspan->chans[1].name,"ztgsm/%d", 1);
++    gsmspan->chans[1].pvt = gsmspan;
++    gsmspan->chans[1].sigcap =  ZT_SIG_CLEAR;
++    gsmspan->chans[1].chanpos = 2; 
++
++	
++    if (zt_register(&gsmspan->span,0)) {
++        printk(KERN_INFO "ztgm: unable to register zaptel span!\n");
++        return -1;
++    }
++
++    /* setup B channel buffers (8 bytes each) */
++    memset(gsmtmp->rxbuf[offset],0x0,sizeof(gsmtmp->rxbuf[offset]));
++    gsmspan->span.chans[0].readchunk = gsmtmp->rxbuf[offset];
++    memset(gsmtmp->txbuf[offset],0x0,sizeof(gsmtmp->txbuf[offset]));
++    gsmspan->span.chans[0].writechunk = gsmtmp->txbuf[offset];
++
++    /* setup D channel buffer */
++    memset(gsmtmp->dtxbuf[offset],0x0,sizeof(gsmtmp->dtxbuf[offset]));
++    gsmspan->span.chans[1].writechunk = gsmtmp->dtxbuf[offset];
++    gsmspan->span.chans[1].maxbytes2transmit = sizeof(gsmtmp->dtxbuf[offset]);
++
++    memset(gsmtmp->drxbuf[offset],0x0,sizeof(gsmtmp->drxbuf[offset]));
++    gsmspan->span.chans[1].readchunk = gsmtmp->drxbuf[offset];
++
++    return 0;
++}
++
++
++int ztgsm_findCards(unsigned int pcidid) {
++    struct pci_dev *tmp;
++    struct ztgsm_card *gsmtmp = NULL;
++    struct ztgsm_span *gsmspan = NULL;
++    unsigned int ioport_size = 0;
++    int i=0;
++    int cid=0;
++    tmp = pci_find_device(PCI_VENDOR_ID_CCD,pcidid,NULL);
++    if (tmp != NULL) {
++
++	if (pci_enable_device(tmp)) {
++	    return -1;
++	}
++
++	gsmtmp = kmalloc(sizeof(struct ztgsm_card),GFP_KERNEL);
++	if (!gsmtmp) {
++	    printk(KERN_WARNING "ztgsm: unable to kmalloc!\n");
++	    pci_disable_device(tmp);
++	    return -ENOMEM;
++	}
++	memset(gsmtmp, 0x0, sizeof(struct ztgsm_card));
++	
++	spin_lock_init(&gsmtmp->lock);
++	gsmtmp->pcidev = tmp;
++	gsmtmp->pcibus = tmp->bus->number;
++	gsmtmp->pcidevfn = tmp->devfn; 
++
++	if (!tmp->irq) {
++	    printk(KERN_WARNING "ztgsm: no irq!\n");
++	} else {
++	    gsmtmp->irq = tmp->irq;
++	}
++
++	gsmtmp->pci_io_phys = tmp->resource[1].start;
++	if (!gsmtmp->pci_io_phys) {
++	    printk(KERN_WARNING "ztgsm: no iomem!\n");
++	    pci_disable_device(tmp);
++	    return -EIO;
++	}
++	gsmtmp->iomem_size = (tmp->resource[1].end - tmp->resource[1].start + 1);
++	printk(KERN_INFO "ztgsm: iomem at %lx size %ld\n", gsmtmp->pci_io_phys, gsmtmp->iomem_size);
++
++	if (check_mem_region(gsmtmp->pci_io_phys, gsmtmp->iomem_size)) {
++	    printk(KERN_INFO "ztgsm: iomem already in use!\n");;
++	    pci_disable_device(tmp);
++	    return -EBUSY;
++	}
++	
++	request_mem_region(gsmtmp->pci_io_phys, gsmtmp->iomem_size, "ztgsm");
++
++	gsmtmp->pci_io = ioremap(gsmtmp->pci_io_phys, gsmtmp->iomem_size); /* 8kb */
++
++	gsmtmp->ioport = tmp->resource[0].start;
++	if (!gsmtmp->ioport) {
++	    printk(KERN_WARNING "ztgsm: no ioport!\n");
++	    pci_disable_device(tmp);
++	    return -EIO;
++	}
++	ioport_size = (tmp->resource[0].end - tmp->resource[0].start + 1);
++	printk(KERN_INFO "ztgsm: ioport size %d\n", ioport_size);
++
++	if (!request_region(gsmtmp->ioport, 0x100, "ztgsm")) {
++	    printk(KERN_WARNING "ztgsm: couldnt request io range!\n");
++	    release_mem_region(gsmtmp->pci_io_phys, gsmtmp->iomem_size);
++	    pci_disable_device(tmp);
++	    return -EIO;
++	}
++	
++	if (request_irq(gsmtmp->irq, ztgsm_interrupt, SA_INTERRUPT | SA_SHIRQ, "ztgsm", gsmtmp)) {
++	    printk(KERN_WARNING "ztgsm: unable to register irq\n");
++	    release_region(gsmtmp->ioport, 0x100);
++	    release_mem_region(gsmtmp->pci_io_phys, gsmtmp->iomem_size);
++	    kfree(gsmtmp);
++	    pci_disable_device(tmp);
++	    return -EIO;
++	}
++	
++	pci_write_config_word(gsmtmp->pcidev, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
++
++	// disable ints
++
++	gsmtmp->type = tmp->subsystem_device;
++
++	ztgsm_dev_list = gsmtmp;
++	ztgsm_dev_count++;
++
++	switch (gsmtmp->type) {
++	    case 0xb55d:
++		    printk(KERN_INFO
++    			"ztgsm: Junghanns.NET unoGSM card configured at io port %x IRQ %d io mem %lx HZ %d CardID %d\n",
++        		 (u_int) gsmtmp->ioport, gsmtmp->irq, (u_long) gsmtmp->pci_io, HZ, cid);
++		break;
++	    case 0xb55e:
++		    printk(KERN_INFO
++    			"ztgsm: Junghanns.NET duoGSM card configured at io port %x IRQ %d io mem %lx HZ %d CardID %d\n",
++        		 (u_int) gsmtmp->ioport, gsmtmp->irq, (u_long) gsmtmp->pci_io, HZ, cid);
++		break;
++	    case 0xb55f:
++		    printk(KERN_INFO
++    			"ztgsm: Junghanns.NET quadGSM card configured at io port %x IRQ %d io mem %lx HZ %d CardID %d\n",
++        		 (u_int) gsmtmp->ioport, gsmtmp->irq, (u_long) gsmtmp->pci_io, HZ, cid);
++		break;
++	}
++
++	ztgsm_resetCard(gsmtmp);
++	ztgsm_init_xbar(gsmtmp);
++
++	switch (ztgsm_indw_io(gsmtmp, ztgsm_SER_G20_ACTIVATED)) {
++	    case 0xf:
++		gsmtmp->gsmspans = 4;
++		break;
++	    case 0x3:
++		gsmtmp->gsmspans = 2;
++		break;
++	    case 0x1:
++		gsmtmp->gsmspans = 1;
++		break;
++	}
++	ztgsm_spans += gsmtmp->gsmspans;
++	
++	for (i=0; i < gsmtmp->gsmspans; i++) {
++	    gsmspan = &gsmtmp->gsmspan[i];
++	    ztgsm_init(gsmspan, gsmtmp, i);
++	}
++
++	ztgsm_switch_on_all(gsmtmp);
++
++	gsmtmp->version = ztgsm_indw_io(gsmtmp, ztgsm_VERS_A);
++	printk(KERN_INFO "ztgsm: VERSION %x\n", gsmtmp->version);
++	if (debug) {
++	    printk(KERN_INFO "ztgsm: G20_ACTIVATED %d\n", ztgsm_indw_io(gsmtmp, ztgsm_SER_G20_ACTIVATED));
++	    printk(KERN_INFO "ztgsm: DIPS %#x\n", ztgsm_indw_io(gsmtmp, ztgsm_DIP_SWITCH));
++	    printk(KERN_INFO "ztgsm: tx_wm_sen %d\n", ztgsm_indw_io(gsmtmp, ztgsm_SER_TX_WM_SEN));
++	}
++	
++	ztgsm_outdw_io(gsmtmp, ztgsm_LED_DUAL, 0xf);
++
++	ztgsm_startCard(gsmtmp);
++
++    }
++    return 0;
++}
++
++
++int init_module(void) {
++    ztgsm_findCards(0xf001);
++    if (ztgsm_dev_count == 0) {
++	printk(KERN_INFO "ztgsm: no multiGSM cards found.\n");
++    } else {
++	printk(KERN_INFO "ztgsm: %d multiGSM card(s) in this box, %d GSM spans total.\n",ztgsm_dev_count, ztgsm_spans);
++    }
++    return 0;
++}
++
++void cleanup_module(void) {
++    struct ztgsm_card *tmpcard,*tmplist;
++    int i=0;
++    tmplist = ztgsm_dev_list;
++    while (tmplist != NULL) {
++	ztgsm_shutdownCard(tmplist);
++	tmplist = tmplist->next;
++    }
++    tmplist = ztgsm_dev_list;
++    spin_lock(&registerlock);
++    while (tmplist != NULL) {
++	tmpcard = tmplist->next;
++	kfree(tmplist);
++	i++;
++	tmplist = tmpcard;
++    }
++    spin_unlock(&registerlock);
++    printk(KERN_INFO "ztgsm: shutdown %d multiGSM cards.\n", i);
++}
++#endif
++
++#ifdef LINUX26
++module_param(debug, int, 0600);
++module_param(pcm_xbar, int, 0600);
++#else
++MODULE_PARM(debug,"i");
++MODULE_PARM(pcm_xbar,"i");
++#endif
++
++MODULE_DESCRIPTION("uno/duao/quad GSM zaptel driver");
++MODULE_AUTHOR("Klaus-Peter Junghanns <kpj at junghanns.net>");
++#ifdef MODULE_LICENSE
++MODULE_LICENSE("GPL");
++#endif	
+diff -urNad zaptel-1.2.5/ztgsm/ztgsm.h /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/ztgsm.h
+--- zaptel-1.2.5/ztgsm/ztgsm.h	1970-01-01 02:00:00.000000000 +0200
++++ /tmp/dpep.7X7WfC/zaptel-1.2.5/ztgsm/ztgsm.h	2006-04-10 12:22:33.000000000 +0300
+@@ -0,0 +1,133 @@
++#define ztgsm_RX_MAX	1000
++#define ztgsm_FIFO_SIZE	16
++#define ztgsm_SPANS	4
++#define ztgsm_SER_BUF_SIZE	1000
++#define ztgsm_FRAMES	0x100
++
++typedef struct ztgsm_span {
++    /* zaptel resources */
++    struct zt_span span;
++    struct zt_chan chans[2];
++
++    /* more zaptel stuff */
++    unsigned int usecount;
++    int spantype;
++    int spanflags;
++} ztgsm_span;
++
++typedef struct ztgsm_card {
++    spinlock_t lock;
++    unsigned char power[ztgsm_SPANS];
++    int cardID;
++    int dead;
++    unsigned char cardno;
++    unsigned int irq;
++    unsigned int iomem;
++    void *pci_io;
++    unsigned int framecnt;
++    unsigned int last_framecnt;
++    unsigned long pci_io_phys;
++    unsigned int version;
++//    unsigned char *pci_io;
++//    unsigned char *pci_io_phys;
++    unsigned long iomem_size;
++    unsigned long ioport;
++    struct ztgsm_span gsmspan[ztgsm_SPANS];
++    unsigned int gsmspans;
++    unsigned int pcibus;
++    unsigned int pcidevfn;
++    struct pci_dev *pcidev;
++    unsigned char gsms;
++    unsigned int ticks;
++    unsigned int clicks;
++    unsigned int type;
++    unsigned char rxbuf[ztgsm_SPANS][ZT_CHUNKSIZE];
++    unsigned char txbuf[ztgsm_SPANS][ZT_CHUNKSIZE];
++    unsigned char drxbuf[ztgsm_SPANS][ztgsm_SER_BUF_SIZE];
++    unsigned char dtxbuf[ztgsm_SPANS][ztgsm_FIFO_SIZE];
++    unsigned short rxbufi[ztgsm_SPANS];
++
++    unsigned char ser_rx_buf[ztgsm_SPANS][ztgsm_SER_BUF_SIZE];
++    unsigned char ser_tx_buf[ztgsm_SPANS][ztgsm_SER_BUF_SIZE];
++    unsigned short ser_rx_idx[ztgsm_SPANS];
++    unsigned short ser_tx_idx[ztgsm_SPANS];
++    unsigned char tx_wm_sen;
++    struct ztgsm_card *next;
++    struct ztgsm_card *prev;
++} ztgsm_card;
++
++#define ztgsm_outb_io(a,b,c) \
++    outw((b), ((a)->ioport+4)); \
++    outb((c), ((a)->ioport));
++
++#define ztgsm_inb_io(a,b) ({ outw((b), (a)->ioport+4); inb((a)->ioport); })
++
++#define ztgsm_outw_io(a,b,c) \
++    outw((b), ((a)->ioport+4)); \
++    outw((c), ((a)->ioport));
++
++#define ztgsm_inw_io(a,b) ({ outw((b), (a)->ioport+4); inw((a)->ioport); })
++
++#define _ztgsm_outdw_io(a,b,c) \
++    outw((b), ((a)->ioport+4)); \
++    outl((c), ((a)->ioport));
++
++#define ztgsm_outdw_io(a,b,c) (outl((c), ((a)->ioport+b)))
++
++#define ztgsm_indw_io(a,b) (inl((a)->ioport+b))
++
++#define ztgsm_outb(a,b,c) (writeb((c),(a)->pci_io+(b)))
++#define ztgsm_inb(a,b) (readb((a)->pci_io+(b)))
++
++#define ztgsm_outw(a,b,c) (writew((c),(a)->pci_io+(b)))
++#define ztgsm_inw(a,b) (readw((a)->pci_io+(b)))
++
++#define ztgsm_outdw(a,b,c) (writel((c),(a)->pci_io+(b)))
++#define ztgsm_indw(a,b) (readl((a)->pci_io+(b)))
++
++#define ztgsm_IO_BASE		0x0
++#define ztgsm_VERS_A		ztgsm_IO_BASE
++#define ztgsm_SER_CLK_DIV	ztgsm_IO_BASE + 4
++#define ztgsm_SER_CLK_PRE_DIV	ztgsm_IO_BASE + (4 * 0x02)
++#define ztgsm_PCM_CLK_PRE_DIV	ztgsm_IO_BASE + (4 * 0x03)
++#define ztgsm_SER_IDLE_VAL	ztgsm_IO_BASE + (4 * 0x04)
++#define ztgsm_SER_RTS_O 	ztgsm_IO_BASE + (4 * 0x05)
++#define ztgsm_SER_TX_EN		ztgsm_IO_BASE + (4 * 0x06)
++#define ztgsm_SER_RX_EN		ztgsm_IO_BASE + (4 * 0x07)
++#define ztgsm_SER_DTR_ON_OFF 	ztgsm_IO_BASE + (4 * 0x08)
++#define ztgsm_DIP_SWITCH 	ztgsm_IO_BASE + (4 * 0x09)
++#define ztgsm_LED_DUAL 		ztgsm_IO_BASE + (4 * 0x0A)
++#define ztgsm_SER_G20_ACTIVATED	ztgsm_IO_BASE + (4 * 0x0B)
++#define ztgsm_SIM_SEL 		ztgsm_IO_BASE + (4 * 0x0C)
++#define ztgsm_PCM_DIR 		ztgsm_IO_BASE + (4 * 0x0D)
++
++#define ztgsm_SER_TX_DATA_A	ztgsm_IO_BASE + (4 * 0x10)
++#define ztgsm_SER_TX_COUNT_A	ztgsm_IO_BASE + (4 * 0x11)
++#define ztgsm_SER_TX_DATA_B	ztgsm_IO_BASE + (4 * 0x12)
++#define ztgsm_SER_TX_COUNT_B	ztgsm_IO_BASE + (4 * 0x13)
++#define ztgsm_SER_TX_DATA_C	ztgsm_IO_BASE + (4 * 0x14)
++#define ztgsm_SER_TX_COUNT_C	ztgsm_IO_BASE + (4 * 0x15)
++#define ztgsm_SER_TX_DATA_D	ztgsm_IO_BASE + (4 * 0x16)
++#define ztgsm_SER_TX_COUNT_D	ztgsm_IO_BASE + (4 * 0x17)
++#define ztgsm_SER_RX_DATA_A	ztgsm_IO_BASE + (4 * 0x18)
++#define ztgsm_SER_RX_COUNT_A	ztgsm_IO_BASE + (4 * 0x19)
++#define ztgsm_SER_RX_DATA_B	ztgsm_IO_BASE + (4 * 0x1a)
++#define ztgsm_SER_RX_COUNT_B	ztgsm_IO_BASE + (4 * 0x1b)
++#define ztgsm_SER_RX_DATA_C	ztgsm_IO_BASE + (4 * 0x1c)
++#define ztgsm_SER_RX_COUNT_C	ztgsm_IO_BASE + (4 * 0x1d)
++#define ztgsm_SER_RX_DATA_D	ztgsm_IO_BASE + (4 * 0x1e)
++#define ztgsm_SER_RX_COUNT_D	ztgsm_IO_BASE + (4 * 0x1f)
++#define ztgsm_SER_STATUS	ztgsm_IO_BASE + (4 * 0x20)
++#define ztgsm_SER_INT_MASK	ztgsm_IO_BASE + (4 * 0x21)
++#define ztgsm_SER_RX_WATERMARK	ztgsm_IO_BASE + (4 * 0x22)
++#define ztgsm_SER_TX_WATERMARK	ztgsm_IO_BASE + (4 * 0x23)
++#define ztgsm_SER_TX_WM_SEN	ztgsm_IO_BASE + (4 * 0x24)
++
++#define ztgsm_PCM_SAP_EN	ztgsm_IO_BASE + (4 * 0x30)
++#define ztgsm_PCM_MASK_LAST	ztgsm_IO_BASE + (4 * 0x31)
++#define ztgsm_PCM_FRAME_CNT	ztgsm_IO_BASE + (4 * 0x32)
++#define ztgsm_PCM_FC_TOG_BIT	ztgsm_IO_BASE + (4 * 0x33)
++#define ztgsm_PCM_SIGNAL_CFG	ztgsm_IO_BASE + (4 * 0x34)
++#define ztgsm_PCM_VECTOR_CFG	ztgsm_IO_BASE + (4 * 0x35)
++
++

Modified: zaptel/trunk/debian/rules
===================================================================
--- zaptel/trunk/debian/rules	2006-05-07 22:19:35 UTC (rev 1748)
+++ zaptel/trunk/debian/rules	2006-05-09 05:19:27 UTC (rev 1749)
@@ -130,7 +130,7 @@
 	# driver source code
 	mkdir -p $(TARDIR)/debian
 	cp Makefile .version *.c *.h *.rbt $(TARDIR)/
-	for dir in build_tools cwain qozap xpp zaphfc; do \
+	for dir in build_tools cwain qozap xpp zaphfc ztgsm; do \
 	  if [ -d $$dir ]; then cp -r $$dir $(TARDIR); fi; \
 	done
 	dh_install -i zaptel.h torisa.h usr/include/linux/
@@ -147,7 +147,7 @@
 	tar cjf debian/$(PREFIX)-source/usr/src/$(PREFIX).tar.bz2 \
 	  -C $(TARPARDIR) modules
 ifeq (1,$(USE_BRISTUFF))
-	set -e; for module in cwain qozap zaphfc; do \
+	set -e; for module in cwain qozap zaphfc ztgsm; do \
 		mkdir -p $(MOD_EXAMPLES_DIR)/$$module; \
 		cp -a $$module/*.conf* $(MOD_EXAMPLES_DIR)/$$module; \
 	done




More information about the Pkg-voip-commits mailing list